From 404690ca3110bcca4d5c66173f3ef1a5146803c2 Mon Sep 17 00:00:00 2001 From: Marco Esposito Date: Sat, 20 Dec 2025 19:57:50 +0100 Subject: [PATCH 01/51] new onboarding flow wip --- apps/demo/config.ts | 7 +- apps/demo/src/App.tsx | 149 +++++++++++-- apps/demo/src/components/InitialForm.tsx | 2 +- .../src/components/SessionSetupPrompt.tsx | 139 ++++++++++++ apps/demo/src/hooks/useChatActions.ts | 1 + apps/demo/src/hooks/useSessionSetup.ts | 191 ++++++++++++++++ apps/demo/src/providers.tsx | 2 +- apps/demo/src/rpc.tsx | 10 +- apps/demo/src/services/DbService.ts | 23 ++ apps/demo/src/services/safeAccount.ts | 209 ++++++++++++++++++ apps/demo/src/types.ts | 1 - 11 files changed, 701 insertions(+), 33 deletions(-) create mode 100644 apps/demo/src/components/SessionSetupPrompt.tsx create mode 100644 apps/demo/src/hooks/useSessionSetup.ts create mode 100644 apps/demo/src/services/safeAccount.ts diff --git a/apps/demo/config.ts b/apps/demo/config.ts index e3a78fc..c73219b 100644 --- a/apps/demo/config.ts +++ b/apps/demo/config.ts @@ -1,5 +1,5 @@ import { http, createConfig } from 'wagmi'; -import { base, mainnet } from 'wagmi/chains'; +import { base, mainnet, baseSepolia} from 'wagmi/chains'; import { connectorsForWallets } from '@rainbow-me/rainbowkit'; import { coinbaseWallet, @@ -31,9 +31,10 @@ const connectors = connectorsForWallets( export const config = createConfig({ connectors, - chains: [base, mainnet], + chains: [baseSepolia, base, mainnet], transports: { - [mainnet.id]: http(), + [baseSepolia.id]: http('https://sepolia.base.org'), [base.id]: http('https://base-rpc.publicnode.com'), + [mainnet.id]: http(), }, }); \ No newline at end of file diff --git a/apps/demo/src/App.tsx b/apps/demo/src/App.tsx index 9318fe3..08c0f10 100644 --- a/apps/demo/src/App.tsx +++ b/apps/demo/src/App.tsx @@ -1,11 +1,9 @@ import { useEffect, useRef, useState, useCallback, useMemo } from "react"; import { Fingerprint } from "lucide-react"; import { ConnectButton } from '@rainbow-me/rainbowkit'; -import Safe from '@safe-global/protocol-kit' -import SafeApiKit from '@safe-global/api-kit' import { useAccount, useWalletClient } from 'wagmi'; import { useRpcClients } from './rpc.js'; -import { BrowserProvider, Wallet } from "ethers"; +import { BrowserProvider, Wallet, Contract } from "ethers"; import { LogChainV1__factory, type LogChainV1, @@ -22,19 +20,21 @@ import { import { useMessageListener } from './hooks/useMessageListener.js'; import { useMessageProcessor } from './hooks/useMessageProcessor.js'; import { dbService } from './services/DbService.js'; +import { getOrCreateSafeForOwner, ensureModuleEnabled } from './services/safeAccount.js'; import { LOGCHAIN_SINGLETON_ADDR, CONTRACT_CREATION_BLOCK, Contact, StoredIdentity, - SAFE_MODULE_ADDRESS, - SAFE_TX_SERVICE_URL + SAFE_MODULE_ADDRESS } from './types.js'; import { InitialForm } from './components/InitialForm.js'; import { SideToastNotifications } from './components/SideToastNotification.js'; import { IdentityCreation } from './components/IdentityCreation.js'; import { CelebrationToast } from "./components/CelebrationToast.js"; +import { SessionSetupPrompt } from './components/SessionSetupPrompt.js'; import { useChatActions } from './hooks/useChatActions.js'; +import { useSessionSetup } from './hooks/useSessionSetup.js'; @@ -58,9 +58,13 @@ export default function App() { const [identityProof, setIdentityProof] = useState(null); const [executor, setExecutor] = useState(null); const [contract, setContract] = useState(null); - const [signer, setSigner] = useState(null); + const [identitySigner, setIdentitySigner] = useState(null); + const [txSigner, setTxSigner] = useState(null); + const [safeAddr, setSafeAddr] = useState(null); const [isActivityLogOpen, setIsActivityLogOpen] = useState(false); const [activityLogs, setActivityLogs] = useState(""); + const [reinitTrigger, setReinitTrigger] = useState(0); + const [verbethClient, setVerbethClient] = useState(null); @@ -91,12 +95,12 @@ export default function App() { const createIdentity = useCallback(async () => { // Wagmi - if (signer && address) { + if (identitySigner && address && safeAddr) { setLoading(true); try { addLog("Deriving new identity key (2 signatures)..."); - const result = await deriveIdentityKeyPairWithProof(signer, address, identityContext); + const result = await deriveIdentityKeyPairWithProof(identitySigner, address, safeAddr, identityContext); setIdentityKeyPair(result.keyPair); setIdentityProof(result.identityProof); @@ -113,6 +117,9 @@ export default function App() { setNeedsIdentityCreation(false); setShowToast(true); + // Trigger re-initialization to complete Safe setup + setReinitTrigger(t => t + 1); + } catch (signError: any) { if (signError.code === 4001) { addLog("User rejected signing request."); @@ -126,7 +133,28 @@ export default function App() { } addLog("โœ— Missing signer/provider or address for identity creation"); - }, [signer, address, identityContext, addLog]); + }, [identitySigner, address, safeAddr, identityContext, addLog]); + + const { + sessionSignerAddr, + sessionSignerBalance, + needsSessionSetup, + isSafeDeployed, + setSessionSignerAddr, + setNeedsSessionSetup, + setIsSafeDeployed, + setIsModuleEnabled, + refreshSessionBalance, + setupSession, + } = useSessionSetup({ + walletClient, + address: address as `0x${string}` | undefined, + safeAddr, + chainId, + readProvider, + addLog, + onSessionSetupComplete: () => setReinitTrigger(t => t + 1), + }); const { messages, @@ -176,12 +204,12 @@ export default function App() { useEffect(() => { const currentAddress = address; - if (executor && identityKeyPair && identityProof && signer && currentAddress) { + if (executor && identityKeyPair && identityProof && identitySigner && currentAddress) { const client = new VerbethClient({ executor, identityKeyPair, identityProof, - signer, + signer: identitySigner, address: currentAddress, }); setVerbethClient(client); @@ -189,7 +217,7 @@ export default function App() { } else { setVerbethClient(null); } - }, [executor, identityKeyPair, identityProof, signer, address, addLog]); + }, [executor, identityKeyPair, identityProof, identitySigner, address, addLog]); // sync handshakeToasts useEffect(() => { @@ -223,7 +251,7 @@ export default function App() { useEffect(() => { handleInitialization(); - }, [ready, readProvider, walletClient, address]); + }, [ready, readProvider, walletClient, address, reinitTrigger]); // hide handshake form when we have contacts AND user is connected useEffect(() => { @@ -247,9 +275,15 @@ export default function App() { } }, [ready, readProvider, walletClient, address]); - const initializeWagmiAccount = async () => { + const initializeWagmiAccount = useCallback(async () => { + const ethersProvider = new BrowserProvider(walletClient!.transport); const ethersSigner = await ethersProvider.getSigner(); + setIdentitySigner(ethersSigner); + + if (address !== currentAccount) { + await switchToAccount(address!); + } const net = await ethersProvider.getNetwork(); if (Number(net.chainId) !== chainId) { @@ -257,18 +291,75 @@ export default function App() { return; } - const contractInstance = LogChainV1__factory.connect(LOGCHAIN_SINGLETON_ADDR, ethersSigner as any); + // Safe init/deploy - get counterfactual address first + const { safeAddress, isDeployed, moduleEnabled } = await getOrCreateSafeForOwner({ + chainId, + ownerAddress: address as `0x${string}`, + providerEip1193: walletClient!.transport, + ethersSigner, + deployIfMissing: false, + enableModuleDuringDeploy: false, + }); + setSafeAddr(safeAddress); + setIsSafeDeployed(isDeployed); + setIsModuleEnabled(moduleEnabled ?? false); + console.log(`\n========== SAFE & SESSION INFO ==========`); + console.log(`Connected EOA wallet: ${address}`); + console.log(`Associated Safe address: ${safeAddress}`); + console.log(` Safe deployed: ${isDeployed}`); + console.log(` Chain ID: ${chainId}`); + + // Check if identity exists - if not, stop here and wait for identity creation + const storedIdentity = await dbService.getIdentity(address!); + if (!storedIdentity) { + addLog(`Counterfactual Safe address: ${safeAddress.slice(0, 10)}... - awaiting identity creation`); + return; + } + + const sessionPrivKey = await dbService.getSessionPrivKey(safeAddress, chainId); + const sessionWallet = new Wallet(sessionPrivKey, readProvider!); + + const safeSessionSigner = new SafeSessionSigner({ + provider: readProvider!, + safeAddress, + moduleAddress: SAFE_MODULE_ADDRESS, + logChainAddress: LOGCHAIN_SINGLETON_ADDR, + sessionSigner: sessionWallet, + }); + setTxSigner(safeSessionSigner); + // Get session signer address for funding + const sessionAddr = await sessionWallet.getAddress(); + setSessionSignerAddr(sessionAddr); + + // Check balance + const balance = await readProvider!.getBalance(sessionAddr); + const balanceEth = Number(balance) / 1e18; + console.log(`๐Ÿ“ Session signer address: ${sessionAddr}`); + console.log(`๐Ÿ’ฐ Session signer balance: ${balanceEth.toFixed(6)} ETH (${balance.toString()} wei)`); + + if (balance === 0n) { + addLog(`Session signer needs funding: ${sessionAddr}`); + } + + // Check if session is configured on module + const isValid = await safeSessionSigner.isSessionValid(); + const isTargetAllowed = await safeSessionSigner.isTargetAllowed(); + console.log(`Session valid on module: ${isValid}`); + console.log(`LogChain target allowed: ${isTargetAllowed}`); + setNeedsSessionSetup(!isValid || !isTargetAllowed); + + if (!isValid || !isTargetAllowed) { + addLog(`โš ๏ธ Session needs setup on module (valid: ${isValid}, target: ${isTargetAllowed})`); + } + + const contractInstance = LogChainV1__factory.connect(LOGCHAIN_SINGLETON_ADDR, safeSessionSigner as any); const executorInstance = ExecutorFactory.createEOA(contractInstance); - setSigner(ethersSigner); setExecutor(executorInstance); setContract(contractInstance); - if (address !== currentAccount) { - console.log(`EOA connected: ${address!.slice(0, 8)}...`); - await switchToAccount(address!); - } - }; + }, [walletClient, address, currentAccount, chainId, readProvider, addLog]); + const switchToAccount = async (newAddress: string) => { setIdentityKeyPair(null); @@ -294,7 +385,8 @@ export default function App() { setIdentityKeyPair(null); setIdentityProof(null); setSelectedContact(null); - setSigner(null); + setIdentitySigner(null); + setTxSigner(null); setContract(null); setExecutor(null); setNeedsIdentityCreation(false); @@ -366,6 +458,19 @@ export default function App() { setShowToast(false)} /> + {/* Session Setup Prompt - show when wallet connected but session not ready */} + {isConnected && sessionSignerAddr && (needsSessionSetup || (sessionSignerBalance !== null && sessionSignerBalance < BigInt(0.0001 * 1e18))) && ( + + )} + {needsIdentityCreation ? (

- {isAnyConnected ? "Hi, start your first chat" : "Have Your Say"} + {isAnyConnected ? "Hi, start your first chat" : "just verb it"}

diff --git a/apps/demo/src/components/SessionSetupPrompt.tsx b/apps/demo/src/components/SessionSetupPrompt.tsx new file mode 100644 index 0000000..4b0b388 --- /dev/null +++ b/apps/demo/src/components/SessionSetupPrompt.tsx @@ -0,0 +1,139 @@ +interface SessionSetupPromptProps { + sessionSignerAddr: string | null; + sessionSignerBalance: bigint | null; + needsSessionSetup: boolean; + isSafeDeployed?: boolean; + onSetupSession: () => void; + onRefreshBalance?: () => void; + loading: boolean; +} + +export function SessionSetupPrompt({ + sessionSignerAddr, + sessionSignerBalance, + needsSessionSetup, + isSafeDeployed = false, + onSetupSession, + onRefreshBalance, + loading, +}: SessionSetupPromptProps) { + if (!sessionSignerAddr) return null; + + const balanceEth = sessionSignerBalance !== null ? Number(sessionSignerBalance) / 1e18 : 0; + const needsFunding = sessionSignerBalance === null || sessionSignerBalance < BigInt(0.0001 * 1e18); + + console.log(`[SessionSetupPrompt] balance: ${balanceEth} ETH, needsFunding: ${needsFunding}, needsSessionSetup: ${needsSessionSetup}, isSafeDeployed: ${isSafeDeployed}`); + + // All good - show ready state + if (!needsFunding && !needsSessionSetup) { + return ( +
+

+ โœ… Ready for gasless messaging! +

+

+ Session balance: {balanceEth.toFixed(6)} ETH +

+
+ ); + } + + // Determine transaction count for button text + const getTxCount = () => { + if (!isSafeDeployed) { + // Deploy + Enable (batched) + setSession + setTarget = 3 txs + return "3 txs: Deploy Safe + Authorize"; + } + // setSession + setTarget = 2 txs + return "2 txs"; + }; + + return ( +
+ {/* Funding prompt */} + {needsFunding && ( +
+

+ โ›ฝ Step 1: Fund Session Wallet +

+

+ Send a small amount of ETH to this address to pay for gas: +

+
+ {sessionSignerAddr} +
+
+ + Balance: {balanceEth.toFixed(6)} ETH + + + {onRefreshBalance && ( + + )} +
+

+ Recommended: 0.001 - 0.005 ETH (~20-100 messages on Base) +

+
+ )} + + {/* Session setup prompt - only show when funded */} + {!needsFunding && needsSessionSetup && ( +
+

+ ๐Ÿ”‘ Step 2: {!isSafeDeployed ? "Deploy & Authorize" : "Authorize Session"} +

+

+ {!isSafeDeployed ? ( + <> + One-time setup: deploy your Safe wallet and authorize session-based messaging. +
+ + This batches Safe deployment + module setup into fewer transactions. + + + ) : ( + "One-time setup: authorize your session wallet to send messages without popups." + )} +

+ + {/* Show what will happen */} +
+

What happens:

+
    + {!isSafeDeployed && ( +
  1. Deploy your Safe smart wallet + enable session module
  2. + )} +
  3. Register session signer on module
  4. +
  5. Allow LogChain contract as target
  6. +
+
+ + +
+ )} +
+ ); +} \ No newline at end of file diff --git a/apps/demo/src/hooks/useChatActions.ts b/apps/demo/src/hooks/useChatActions.ts index 32072dd..db20977 100644 --- a/apps/demo/src/hooks/useChatActions.ts +++ b/apps/demo/src/hooks/useChatActions.ts @@ -40,6 +40,7 @@ export const useChatActions = ({ addLog("โœ— Missing recipient address or message"); return; } + setLoading(true); try { diff --git a/apps/demo/src/hooks/useSessionSetup.ts b/apps/demo/src/hooks/useSessionSetup.ts new file mode 100644 index 0000000..f0271d9 --- /dev/null +++ b/apps/demo/src/hooks/useSessionSetup.ts @@ -0,0 +1,191 @@ +// src/hooks/useSessionSetup.ts +import { useState, useEffect, useCallback } from 'react'; +import { BrowserProvider, Contract } from 'ethers'; +import { getOrCreateSafeForOwner, ensureModuleEnabled } from '../services/safeAccount.js'; +import { LOGCHAIN_SINGLETON_ADDR, SAFE_MODULE_ADDRESS } from '../types.js'; + +interface UseSessionSetupParams { + walletClient: any; + address: `0x${string}` | undefined; + safeAddr: string | null; + chainId: number; + readProvider: any; + addLog: (message: string) => void; + onSessionSetupComplete?: () => void; +} + +export function useSessionSetup({ + walletClient, + address, + safeAddr, + chainId, + readProvider, + addLog, + onSessionSetupComplete, +}: UseSessionSetupParams) { + const [sessionSignerAddr, setSessionSignerAddr] = useState(null); + const [sessionSignerBalance, setSessionSignerBalance] = useState(null); + const [needsSessionSetup, setNeedsSessionSetup] = useState(false); + const [isSafeDeployed, setIsSafeDeployed] = useState(false); + const [isModuleEnabled, setIsModuleEnabled] = useState(false); + const [loading, setLoading] = useState(false); + + // Refresh session signer balance periodically + useEffect(() => { + if (!sessionSignerAddr || !readProvider) return; + + const refreshBalance = async () => { + try { + const balance = await readProvider.getBalance(sessionSignerAddr); + console.log(`๐Ÿ”„ Balance refresh: ${Number(balance) / 1e18} ETH`); + setSessionSignerBalance(balance); + } catch (err) { + console.error("Failed to refresh balance:", err); + } + }; + + refreshBalance(); + const interval = setInterval(refreshBalance, 10000); + return () => clearInterval(interval); + }, [sessionSignerAddr, readProvider]); + + const refreshSessionBalance = useCallback(async () => { + if (!sessionSignerAddr || !readProvider) return; + try { + const balance = await readProvider.getBalance(sessionSignerAddr); + console.log(`๐Ÿ”„ Manual balance refresh: ${Number(balance) / 1e18} ETH`); + setSessionSignerBalance(balance); + } catch (err) { + console.error("Failed to refresh balance:", err); + } + }, [sessionSignerAddr, readProvider]); + + const setupSession = useCallback(async () => { + if (!walletClient || !address || !safeAddr || !sessionSignerAddr) { + addLog("Missing requirements for session setup"); + return; + } + + setLoading(true); + try { + const ethersProvider = new BrowserProvider(walletClient.transport); + const ethersSigner = await ethersProvider.getSigner(); + + console.log(`\n========== SETTING UP SESSION ==========`); + console.log(`Safe: ${safeAddr}`); + console.log(`Safe deployed: ${isSafeDeployed}`); + console.log(`Module enabled: ${isModuleEnabled}`); + console.log(`Session signer: ${sessionSignerAddr}`); + console.log(`Target (LogChain): ${LOGCHAIN_SINGLETON_ADDR}`); + + let currentModuleEnabled = isModuleEnabled; + + // Step 1: Deploy Safe + Enable Module in one transaction + if (!isSafeDeployed) { + addLog("Deploying Safe + enabling module (tx 1)..."); + + const { isDeployed, moduleEnabled } = await getOrCreateSafeForOwner({ + chainId, + ownerAddress: address as `0x${string}`, + providerEip1193: walletClient.transport, + ethersSigner, + deployIfMissing: true, + enableModuleDuringDeploy: true, + }); + + if (!isDeployed) { + throw new Error("Safe deployment failed"); + } + + console.log(`โœ… Safe deployed at ${safeAddr}`); + setIsSafeDeployed(true); + + currentModuleEnabled = moduleEnabled ?? false; + setIsModuleEnabled(currentModuleEnabled); + + if (currentModuleEnabled) { + console.log(`โœ… Module enabled during deployment`); + } + } + + // Step 2: Enable module separately if deployment didn't include it + if (!currentModuleEnabled) { + addLog("Enabling session module (tx 2)..."); + + const { protocolKit } = await getOrCreateSafeForOwner({ + chainId, + ownerAddress: address as `0x${string}`, + providerEip1193: walletClient.transport, + ethersSigner, + deployIfMissing: false, + }); + + await ensureModuleEnabled(protocolKit); + setIsModuleEnabled(true); + console.log(`Module enabled`); + } + + // Step 3: Register session signer + const moduleContract = new Contract( + SAFE_MODULE_ADDRESS, + [ + "function setSession(address safe, address signer, uint256 expiry)", + "function setTarget(address safe, address target, bool allowed)", + ], + ethersSigner + ); + + addLog("Registering session signer..."); + const tx1 = await moduleContract.setSession( + safeAddr, + sessionSignerAddr, + BigInt("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff") + ); + console.log(`TX hash: ${tx1.hash}`); + await tx1.wait(); + console.log(`โœ… Session signer authorized`); + + // Step 4: Allow LogChain target + addLog("Allowing LogChain target..."); + const tx2 = await moduleContract.setTarget( + safeAddr, + LOGCHAIN_SINGLETON_ADDR, + true + ); + console.log(`TX hash: ${tx2.hash}`); + await tx2.wait(); + console.log(`โœ… LogChain target allowed`); + + addLog("โœ“ Session setup complete!"); + console.log(`==========================================\n`); + setNeedsSessionSetup(false); + + onSessionSetupComplete?.(); + + } catch (err: any) { + console.error(`Session setup error:`, err); + addLog(`โœ— Session setup failed: ${err.message}`); + } finally { + setLoading(false); + } + }, [walletClient, address, safeAddr, sessionSignerAddr, isSafeDeployed, isModuleEnabled, chainId, addLog, onSessionSetupComplete]); + + return { + // State + sessionSignerAddr, + sessionSignerBalance, + needsSessionSetup, + isSafeDeployed, + isModuleEnabled, + sessionLoading: loading, + // Setters (needed by initializeWagmiAccount) + setSessionSignerAddr, + setSessionSignerBalance, + setNeedsSessionSetup, + setIsSafeDeployed, + setIsModuleEnabled, + // Actions + refreshSessionBalance, + setupSession, + }; +} \ No newline at end of file diff --git a/apps/demo/src/providers.tsx b/apps/demo/src/providers.tsx index f7dffc1..2c9969a 100644 --- a/apps/demo/src/providers.tsx +++ b/apps/demo/src/providers.tsx @@ -22,7 +22,7 @@ export function Providers({ children }: { children: React.ReactNode }) { {children} diff --git a/apps/demo/src/rpc.tsx b/apps/demo/src/rpc.tsx index 9161966..927494d 100644 --- a/apps/demo/src/rpc.tsx +++ b/apps/demo/src/rpc.tsx @@ -1,7 +1,7 @@ import { createContext, useContext, useEffect, useState, useMemo } from "react"; import { JsonRpcProvider } from "ethers"; import { createPublicClient, http, fallback } from "viem"; -import { base } from "viem/chains"; +import { base, baseSepolia } from "viem/chains"; type RpcState = { @@ -19,7 +19,7 @@ export function RpcProvider({ children }: { children: React.ReactNode }) { let mounted = true; (async () => { try { - const p = new JsonRpcProvider("https://mainnet.base.org", undefined, { + const p = new JsonRpcProvider("https://sepolia.base.org", undefined, { polling: true, pollingInterval: 3000, }); @@ -35,10 +35,10 @@ export function RpcProvider({ children }: { children: React.ReactNode }) { const viemClient = useMemo( () => createPublicClient({ - chain: base, + chain: baseSepolia, transport: fallback([ - http("https://mainnet.base.org"), // rate-limited - http("https://base-rpc.publicnode.com"), + http("https://sepolia.base.org"), + http("https://base-sepolia-rpc.publicnode.com"), ]), }), [] diff --git a/apps/demo/src/services/DbService.ts b/apps/demo/src/services/DbService.ts index 46e7149..f607751 100644 --- a/apps/demo/src/services/DbService.ts +++ b/apps/demo/src/services/DbService.ts @@ -101,6 +101,29 @@ export class DbService { return this.db.identity.delete(normalizedAddress); } + async getSessionPrivKey(safeAddress: string, chainId: number): Promise { + const { Wallet } = await import('ethers'); + const normalizedSafe = this.normalizeAddress(safeAddress); + const key = `sessionKey_${normalizedSafe}_${chainId}`; + let privKey = await this.getSetting(key); + + if (!privKey) { + const newWallet = Wallet.createRandom(); + privKey = newWallet.privateKey; + await this.setSetting(key, privKey); + console.log(`๐Ÿ”‘ NEW session key created for Safe ${normalizedSafe.slice(0, 10)}...`); + console.log(` Session signer address: ${newWallet.address}`); + console.log(` Stored in IndexedDB with key: "${key}"`); + } else { + const existingWallet = new Wallet(privKey); + console.log(`๐Ÿ”‘ EXISTING session key loaded for Safe ${normalizedSafe.slice(0, 10)}...`); + console.log(` Session signer address: ${existingWallet.address}`); + } + + return privKey; + } + + /* ------------------------------ CONTACTS --------------------------------- */ saveContact(contact: Contact) { const normalizedContact = { diff --git a/apps/demo/src/services/safeAccount.ts b/apps/demo/src/services/safeAccount.ts new file mode 100644 index 0000000..18612f1 --- /dev/null +++ b/apps/demo/src/services/safeAccount.ts @@ -0,0 +1,209 @@ +// src/services/safeAccount.ts +import SafeDefault from '@safe-global/protocol-kit' +import SafeApiKitDefault from '@safe-global/api-kit' +import { getAddress, Interface } from 'ethers' +import { SAFE_MODULE_ADDRESS } from '../types.js' + +// Handle ESM/CJS interop - safe libs export default differently +const Safe = (SafeDefault as any).default ?? SafeDefault +const SafeApiKit = (SafeApiKitDefault as any).default ?? SafeApiKitDefault + +const SAFE_API_KEY = import.meta.env.VITE_SAFE_API_KEY as string + +const MODULE_SETUP_HELPER_ADDRESS: Record = { + 84532: '0xc022F74924BDB4b62D830234d89b066359bF67c0', + 8453: '0xc022F74924BDB4b62D830234d89b066359bF67c0', +} + +export async function getOrCreateSafeForOwner(params: { + chainId: number + ownerAddress: `0x${string}` + providerEip1193: any + ethersSigner: any + /** + * Deploy the Safe if it doesn't exist yet + */ + deployIfMissing?: boolean + /** + * Enable the session module during deployment (only works with deployIfMissing=true) + */ + enableModuleDuringDeploy?: boolean + /** + * Pass Safe contractNetworks if on a chain not bundled in this protocol-kit version + */ + contractNetworks?: any +}) { + const { + chainId, + ownerAddress: rawOwnerAddress, + providerEip1193, + ethersSigner, + deployIfMissing = false, + enableModuleDuringDeploy = false, + contractNetworks, + } = params + + const ownerAddress = getAddress(rawOwnerAddress) as `0x${string}` + + const apiKit = new SafeApiKit({ + chainId: BigInt(chainId), + ...(SAFE_API_KEY ? { apiKey: SAFE_API_KEY } : {}), + }) + + let safeAddress: `0x${string}` | undefined + + // 1) Try to find an existing Safe for owner + try { + const { safes } = await apiKit.getSafesByOwner(ownerAddress) + safeAddress = safes?.[0] as `0x${string}` | undefined + } catch (e: any) { + const status = + e?.response?.status ?? + e?.status ?? + e?.cause?.status ?? + (typeof e?.message === 'string' && e.message.includes('404') ? 404 : undefined) + + if (status === 404) { + safeAddress = undefined + } else { + throw new Error(`Safe Tx Service error: ${e?.message ?? String(e)}`) + } + } + + // Spread optional contractNetworks only if provided + const maybeNetworks = contractNetworks ? { contractNetworks } : {} + + // 2) If not found, build predicted safe (deploy only if deployIfMissing=true) + if (!safeAddress) { + // Build the predicted safe configuration + // If enableModuleDuringDeploy=true, include the setup callback + const safeAccountConfig = buildSafeAccountConfig( + ownerAddress, + chainId, + enableModuleDuringDeploy && deployIfMissing + ) + + const predictedSafe = { + safeAccountConfig, + safeDeploymentConfig: { + saltNonce: '0', + }, + } + + let protocolKit = await Safe.init({ + provider: providerEip1193, + signer: ownerAddress, + predictedSafe, + ...maybeNetworks, + }) + + safeAddress = (await protocolKit.getAddress()) as `0x${string}` + + if (!deployIfMissing) { + return { safeAddress, protocolKit, isDeployed: false, moduleEnabled: false } + } + + // Deploy (createProxyWithNonce tx) + console.log(`๐Ÿš€ Deploying Safe${enableModuleDuringDeploy ? ' with module enabled' : ''}...`) + const deploymentTx = await protocolKit.createSafeDeploymentTransaction() + + const txResp = await ethersSigner.sendTransaction({ + to: deploymentTx.to, + data: deploymentTx.data, + value: BigInt(deploymentTx.value), + }) + const receipt = await txResp.wait() + + const statusOk = receipt?.status === 1 || receipt?.status === 1n + if (!statusOk) { + throw new Error('Safe deployment reverted') + } + + console.log(`Safe deployed at ${safeAddress}`) + + // Re-init on the deployed address + protocolKit = await Safe.init({ + provider: providerEip1193, + signer: ownerAddress, + safeAddress, + ...maybeNetworks, + }) + + // Verify module is enabled if we tried to enable it + let moduleEnabled = false + if (enableModuleDuringDeploy) { + moduleEnabled = await protocolKit.isModuleEnabled(SAFE_MODULE_ADDRESS) + console.log(`Module enabled during deploy: ${moduleEnabled}`) + } + + return { safeAddress, protocolKit, isDeployed: true, moduleEnabled } + } + + // 3) Safe already exists + const protocolKit = await Safe.init({ + provider: providerEip1193, + signer: ownerAddress, + safeAddress, + ...maybeNetworks, + }) + + const moduleEnabled = await protocolKit.isModuleEnabled(SAFE_MODULE_ADDRESS) + + return { safeAddress, protocolKit, isDeployed: true, moduleEnabled } +} + +/** + * Build SafeAccountConfig, optionally including module setup callback + */ +function buildSafeAccountConfig( + ownerAddress: string, + chainId: number, + includeModuleSetup: boolean +): any { + const baseConfig = { + owners: [ownerAddress], + threshold: 1, + } + + if (!includeModuleSetup) { + return baseConfig + } + + const helperAddress = MODULE_SETUP_HELPER_ADDRESS[chainId] + if (!helperAddress || helperAddress === '0x...') { + console.warn(`โš ๏ธ ModuleSetupHelper not deployed on chain ${chainId}, falling back to separate tx`) + return baseConfig + } + + // Encode the enableModule call for the helper contract + const helperInterface = new Interface(['function enableModule(address module)']) + const enableModuleData = helperInterface.encodeFunctionData('enableModule', [ + SAFE_MODULE_ADDRESS, + ]) + + return { + ...baseConfig, + to: helperAddress, + data: enableModuleData, + } +} + +/** + * Enable module on an already-deployed Safe + */ +export async function ensureModuleEnabled(protocolKit: any): Promise { + const moduleAddress = getAddress(SAFE_MODULE_ADDRESS) + const enabled = await protocolKit.isModuleEnabled(moduleAddress) + if (enabled) { + console.log(`Module already enabled`) + return true + } + + console.log(`Enabling module ${moduleAddress}...`) + const enableTx = await protocolKit.createEnableModuleTx(moduleAddress) + const signed = await protocolKit.signTransaction(enableTx) + const exec = await protocolKit.executeTransaction(signed) + await exec.transactionResponse?.wait() + console.log(`Module enabled`) + return true +} \ No newline at end of file diff --git a/apps/demo/src/types.ts b/apps/demo/src/types.ts index a99528e..d9ee0c6 100644 --- a/apps/demo/src/types.ts +++ b/apps/demo/src/types.ts @@ -11,7 +11,6 @@ export const MAX_RANGE_PROVIDER = 2_000; export const CHUNK_SIZE = 2_000; export const REAL_TIME_BUFFER = 3; -export const SAFE_TX_SERVICE_URL = import.meta.env.VITE_SAFE_TX_SERVICE_URL as string export const SAFE_MODULE_ADDRESS = import.meta.env.VITE_SAFE_SESSION_MODULE as `0x${string}` /* --------------------------- EVENT SIGNATURES ---------------------------- */ From 85d7332fd7fcc23db8412eae8a0ac57b4917a212 Mon Sep 17 00:00:00 2001 From: Marco Esposito Date: Tue, 23 Dec 2025 18:14:32 +0100 Subject: [PATCH 02/51] add session module helper + new hooks --- apps/demo/src/App.tsx | 265 +- .../src/components/SessionSetupPrompt.tsx | 70 +- apps/demo/src/hooks/useInitIdentity.ts | 278 + apps/demo/src/hooks/useSessionSetup.ts | 144 +- apps/demo/src/services/DbService.ts | 54 +- apps/demo/src/services/safeAccount.ts | 213 +- .../contracts/contracts/ModuleSetupHelper.sol | 64 + .../contracts/contracts/SessionModule.sol | 112 + packages/contracts/hardhat.config.ts | 1 - .../ignition/modules/SessionModule.ts | 11 + packages/contracts/package.json | 4 +- packages/sdk/src/identity.ts | 19 +- packages/sdk/src/index.ts | 4 +- packages/sdk/src/utils.ts | 4 + .../sdk/src/{ => utils}/safeSessionSigner.ts | 73 +- packages/sdk/src/verify.ts | 25 +- pnpm-lock.yaml | 4549 ++++++++++------- 17 files changed, 3715 insertions(+), 2175 deletions(-) create mode 100644 apps/demo/src/hooks/useInitIdentity.ts create mode 100644 packages/contracts/contracts/ModuleSetupHelper.sol create mode 100644 packages/contracts/contracts/SessionModule.sol create mode 100644 packages/contracts/ignition/modules/SessionModule.ts rename packages/sdk/src/{ => utils}/safeSessionSigner.ts (54%) diff --git a/apps/demo/src/App.tsx b/apps/demo/src/App.tsx index 08c0f10..7efded2 100644 --- a/apps/demo/src/App.tsx +++ b/apps/demo/src/App.tsx @@ -1,32 +1,17 @@ -import { useEffect, useRef, useState, useCallback, useMemo } from "react"; +import { useEffect, useRef, useState, useCallback } from "react"; import { Fingerprint } from "lucide-react"; import { ConnectButton } from '@rainbow-me/rainbowkit'; import { useAccount, useWalletClient } from 'wagmi'; import { useRpcClients } from './rpc.js'; -import { BrowserProvider, Wallet, Contract } from "ethers"; import { - LogChainV1__factory, - type LogChainV1, -} from "@verbeth/contracts/typechain-types/index.js"; -import { - IExecutor, - ExecutorFactory, - deriveIdentityKeyPairWithProof, - IdentityKeyPair, - IdentityProof, VerbethClient, - SafeSessionSigner } from '@verbeth/sdk'; import { useMessageListener } from './hooks/useMessageListener.js'; import { useMessageProcessor } from './hooks/useMessageProcessor.js'; -import { dbService } from './services/DbService.js'; -import { getOrCreateSafeForOwner, ensureModuleEnabled } from './services/safeAccount.js'; import { LOGCHAIN_SINGLETON_ADDR, CONTRACT_CREATION_BLOCK, Contact, - StoredIdentity, - SAFE_MODULE_ADDRESS } from './types.js'; import { InitialForm } from './components/InitialForm.js'; import { SideToastNotifications } from './components/SideToastNotification.js'; @@ -35,8 +20,7 @@ import { CelebrationToast } from "./components/CelebrationToast.js"; import { SessionSetupPrompt } from './components/SessionSetupPrompt.js'; import { useChatActions } from './hooks/useChatActions.js'; import { useSessionSetup } from './hooks/useSessionSetup.js'; - - +import { useInitIdentity } from './hooks/useInitIdentity.js'; export default function App() { const { ethers: readProvider, viem: viemClient } = useRpcClients(); @@ -48,32 +32,15 @@ export default function App() { const [message, setMessage] = useState(""); const [selectedContact, setSelectedContact] = useState(null); const [loading, setLoading] = useState(false); - const [currentAccount, setCurrentAccount] = useState(null); const [showHandshakeForm, setShowHandshakeForm] = useState(true); const [handshakeToasts, setHandshakeToasts] = useState([]); - const [needsIdentityCreation, setNeedsIdentityCreation] = useState(false); const [showToast, setShowToast] = useState(false); - - const [identityKeyPair, setIdentityKeyPair] = useState(null); - const [identityProof, setIdentityProof] = useState(null); - const [executor, setExecutor] = useState(null); - const [contract, setContract] = useState(null); - const [identitySigner, setIdentitySigner] = useState(null); - const [txSigner, setTxSigner] = useState(null); - const [safeAddr, setSafeAddr] = useState(null); const [isActivityLogOpen, setIsActivityLogOpen] = useState(false); const [activityLogs, setActivityLogs] = useState(""); - const [reinitTrigger, setReinitTrigger] = useState(0); - - const [verbethClient, setVerbethClient] = useState(null); const logRef = useRef(null); - - // Identity context (domain and chain binding) const chainId = Number(import.meta.env.VITE_CHAIN_ID); - const rpId = globalThis.location?.host ?? ""; - const identityContext = useMemo(() => ({ chainId, rpId }), [chainId, rpId]); const addLog = useCallback((message: string) => { const timestamp = new Date().toLocaleTimeString(); @@ -93,67 +60,58 @@ export default function App() { }, [isActivityLogOpen]); - const createIdentity = useCallback(async () => { - // Wagmi - if (identitySigner && address && safeAddr) { - setLoading(true); - try { - addLog("Deriving new identity key (2 signatures)..."); - - const result = await deriveIdentityKeyPairWithProof(identitySigner, address, safeAddr, identityContext); - - setIdentityKeyPair(result.keyPair); - setIdentityProof(result.identityProof); - - const identityToStore: StoredIdentity = { - address: address, - keyPair: result.keyPair, - derivedAt: Date.now(), - proof: result.identityProof - }; - - await dbService.saveIdentity(identityToStore); - addLog(`New identity key derived and saved for EOA`); - setNeedsIdentityCreation(false); - setShowToast(true); - - // Trigger re-initialization to complete Safe setup - setReinitTrigger(t => t + 1); - - } catch (signError: any) { - if (signError.code === 4001) { - addLog("User rejected signing request."); - } else { - addLog(`โœ— Failed to derive identity: ${signError.message}`); - } - } finally { - setLoading(false); - } - return; - } - - addLog("โœ— Missing signer/provider or address for identity creation"); - }, [identitySigner, address, safeAddr, identityContext, addLog]); - const { + identityKeyPair, + identityProof, + executor, + identitySigner, + safeAddr, + needsIdentityCreation, + identityContext, + // Session state (owned by useInitIdentity) sessionSignerAddr, - sessionSignerBalance, needsSessionSetup, isSafeDeployed, - setSessionSignerAddr, - setNeedsSessionSetup, + isModuleEnabled, setIsSafeDeployed, setIsModuleEnabled, + setNeedsSessionSetup, + // Actions + createIdentity, + triggerReinit, + } = useInitIdentity({ + walletClient, + address, + chainId, + readProvider, + ready, + addLog, + onIdentityCreated: () => setShowToast(true), + onReset: () => { + setSelectedContact(null); + setVerbethClient(null); + }, + }); + + // useSessionSetup receives state from useInitIdentity + const { + sessionSignerBalance, refreshSessionBalance, setupSession, } = useSessionSetup({ walletClient, - address: address as `0x${string}` | undefined, + address, safeAddr, + sessionSignerAddr, chainId, readProvider, addLog, - onSessionSetupComplete: () => setReinitTrigger(t => t + 1), + isSafeDeployed, + isModuleEnabled, + setIsSafeDeployed, + setIsModuleEnabled, + setNeedsSessionSetup, + onSessionSetupComplete: () => triggerReinit(), }); const { @@ -249,150 +207,12 @@ export default function App() { setReady(readProvider !== null && isConnected && walletClient !== undefined); }, [readProvider, isConnected, walletClient]); - useEffect(() => { - handleInitialization(); - }, [ready, readProvider, walletClient, address, reinitTrigger]); - // hide handshake form when we have contacts AND user is connected useEffect(() => { const currentlyConnected = isConnected; setShowHandshakeForm(!ready || !currentlyConnected || contacts.length === 0 || needsIdentityCreation); }, [ready, isConnected, contacts.length, needsIdentityCreation]); - const handleInitialization = useCallback(async () => { - try { - if (ready && readProvider && walletClient && address) { - await initializeWagmiAccount(); - return; - } - - if (!address) { - resetState(); - } - } catch (error) { - console.error("Failed to initialize:", error); - addLog(`โœ— Failed to initialize: ${error instanceof Error ? error.message : 'Unknown error'}`); - } - }, [ready, readProvider, walletClient, address]); - - const initializeWagmiAccount = useCallback(async () => { - - const ethersProvider = new BrowserProvider(walletClient!.transport); - const ethersSigner = await ethersProvider.getSigner(); - setIdentitySigner(ethersSigner); - - if (address !== currentAccount) { - await switchToAccount(address!); - } - - const net = await ethersProvider.getNetwork(); - if (Number(net.chainId) !== chainId) { - addLog(`Wrong network: connected to chain ${Number(net.chainId)}, expected ${chainId}. Please switch network in your wallet.`); - return; - } - - // Safe init/deploy - get counterfactual address first - const { safeAddress, isDeployed, moduleEnabled } = await getOrCreateSafeForOwner({ - chainId, - ownerAddress: address as `0x${string}`, - providerEip1193: walletClient!.transport, - ethersSigner, - deployIfMissing: false, - enableModuleDuringDeploy: false, - }); - setSafeAddr(safeAddress); - setIsSafeDeployed(isDeployed); - setIsModuleEnabled(moduleEnabled ?? false); - console.log(`\n========== SAFE & SESSION INFO ==========`); - console.log(`Connected EOA wallet: ${address}`); - console.log(`Associated Safe address: ${safeAddress}`); - console.log(` Safe deployed: ${isDeployed}`); - console.log(` Chain ID: ${chainId}`); - - // Check if identity exists - if not, stop here and wait for identity creation - const storedIdentity = await dbService.getIdentity(address!); - if (!storedIdentity) { - addLog(`Counterfactual Safe address: ${safeAddress.slice(0, 10)}... - awaiting identity creation`); - return; - } - - const sessionPrivKey = await dbService.getSessionPrivKey(safeAddress, chainId); - const sessionWallet = new Wallet(sessionPrivKey, readProvider!); - - const safeSessionSigner = new SafeSessionSigner({ - provider: readProvider!, - safeAddress, - moduleAddress: SAFE_MODULE_ADDRESS, - logChainAddress: LOGCHAIN_SINGLETON_ADDR, - sessionSigner: sessionWallet, - }); - setTxSigner(safeSessionSigner); - // Get session signer address for funding - const sessionAddr = await sessionWallet.getAddress(); - setSessionSignerAddr(sessionAddr); - - // Check balance - const balance = await readProvider!.getBalance(sessionAddr); - const balanceEth = Number(balance) / 1e18; - console.log(`๐Ÿ“ Session signer address: ${sessionAddr}`); - console.log(`๐Ÿ’ฐ Session signer balance: ${balanceEth.toFixed(6)} ETH (${balance.toString()} wei)`); - - if (balance === 0n) { - addLog(`Session signer needs funding: ${sessionAddr}`); - } - - // Check if session is configured on module - const isValid = await safeSessionSigner.isSessionValid(); - const isTargetAllowed = await safeSessionSigner.isTargetAllowed(); - console.log(`Session valid on module: ${isValid}`); - console.log(`LogChain target allowed: ${isTargetAllowed}`); - setNeedsSessionSetup(!isValid || !isTargetAllowed); - - if (!isValid || !isTargetAllowed) { - addLog(`โš ๏ธ Session needs setup on module (valid: ${isValid}, target: ${isTargetAllowed})`); - } - - const contractInstance = LogChainV1__factory.connect(LOGCHAIN_SINGLETON_ADDR, safeSessionSigner as any); - const executorInstance = ExecutorFactory.createEOA(contractInstance); - - setExecutor(executorInstance); - setContract(contractInstance); - - }, [walletClient, address, currentAccount, chainId, readProvider, addLog]); - - - const switchToAccount = async (newAddress: string) => { - setIdentityKeyPair(null); - setIdentityProof(null); - setSelectedContact(null); - - await dbService.switchAccount(newAddress); - setCurrentAccount(newAddress); - - const storedIdentity = await dbService.getIdentity(newAddress); - if (storedIdentity) { - setIdentityKeyPair(storedIdentity.keyPair); - setIdentityProof(storedIdentity.proof ?? null); - setNeedsIdentityCreation(false); - addLog(`Identity keys restored from database`); - } else { - setNeedsIdentityCreation(true); - } - }; - - const resetState = () => { - setCurrentAccount(null); - setIdentityKeyPair(null); - setIdentityProof(null); - setSelectedContact(null); - setIdentitySigner(null); - setTxSigner(null); - setContract(null); - setExecutor(null); - setNeedsIdentityCreation(false); - setVerbethClient(null); - }; - return (
@@ -422,7 +242,7 @@ export default function App() { {/* LEFT: title */}

- Unstoppable Chat + Blockless Chat

powered by Verbeth @@ -459,12 +279,13 @@ export default function App() { setShowToast(false)} /> {/* Session Setup Prompt - show when wallet connected but session not ready */} - {isConnected && sessionSignerAddr && (needsSessionSetup || (sessionSignerBalance !== null && sessionSignerBalance < BigInt(0.0001 * 1e18))) && ( + {isConnected && sessionSignerAddr && !needsIdentityCreation && (needsSessionSetup || (sessionSignerBalance !== null && sessionSignerBalance < BigInt(0.0001 * 1e18))) && ( void; onRefreshBalance?: () => void; loading: boolean; @@ -13,6 +14,7 @@ export function SessionSetupPrompt({ sessionSignerBalance, needsSessionSetup, isSafeDeployed = false, + isModuleEnabled = false, onSetupSession, onRefreshBalance, loading, @@ -22,7 +24,7 @@ export function SessionSetupPrompt({ const balanceEth = sessionSignerBalance !== null ? Number(sessionSignerBalance) / 1e18 : 0; const needsFunding = sessionSignerBalance === null || sessionSignerBalance < BigInt(0.0001 * 1e18); - console.log(`[SessionSetupPrompt] balance: ${balanceEth} ETH, needsFunding: ${needsFunding}, needsSessionSetup: ${needsSessionSetup}, isSafeDeployed: ${isSafeDeployed}`); + console.log(`[SessionSetupPrompt] balance: ${balanceEth} ETH, needsFunding: ${needsFunding}, needsSessionSetup: ${needsSessionSetup}, isSafeDeployed: ${isSafeDeployed}, isModuleEnabled: ${isModuleEnabled}`); // All good - show ready state if (!needsFunding && !needsSessionSetup) { @@ -38,16 +40,46 @@ export function SessionSetupPrompt({ ); } - // Determine transaction count for button text - const getTxCount = () => { + // Determine what setup is needed + const getSetupInfo = () => { if (!isSafeDeployed) { - // Deploy + Enable (batched) + setSession + setTarget = 3 txs - return "3 txs: Deploy Safe + Authorize"; + // New user: everything in 1 tx + return { + txCount: "1 tx", + title: "Deploy & Authorize", + description: "One-time setup: deploy your Safe wallet, enable the session module, and authorize gasless messaging โ€” all in a single transaction.", + steps: [ + "Deploy your Safe smart wallet", + "Enable session module", + "Register session signer + allow LogChain target", + ], + }; + } else if (!isModuleEnabled) { + // Safe exists but module not enabled + return { + txCount: "2 txs", + title: "Enable Module & Authorize", + description: "Enable the session module on your existing Safe and authorize gasless messaging.", + steps: [ + "Enable session module on Safe", + "Register session signer + allow LogChain target", + ], + }; + } else { + // Safe + module exist, just need session setup + return { + txCount: "1 tx", + title: "Authorize Session", + description: "One-time setup: authorize your session wallet to send messages without popups.", + steps: [ + "Register session signer + allow LogChain target", + ], + }; } - // setSession + setTarget = 2 txs - return "2 txs"; }; + const setupInfo = getSetupInfo(); + return (
{/* Funding prompt */} @@ -91,31 +123,19 @@ export function SessionSetupPrompt({ {!needsFunding && needsSessionSetup && (

- ๐Ÿ”‘ Step 2: {!isSafeDeployed ? "Deploy & Authorize" : "Authorize Session"} + ๐Ÿ”‘ Step 2: {setupInfo.title}

- {!isSafeDeployed ? ( - <> - One-time setup: deploy your Safe wallet and authorize session-based messaging. -
- - This batches Safe deployment + module setup into fewer transactions. - - - ) : ( - "One-time setup: authorize your session wallet to send messages without popups." - )} + {setupInfo.description}

{/* Show what will happen */}

What happens:

    - {!isSafeDeployed && ( -
  1. Deploy your Safe smart wallet + enable session module
  2. - )} -
  3. Register session signer on module
  4. -
  5. Allow LogChain contract as target
  6. + {setupInfo.steps.map((step, i) => ( +
  7. {step}
  8. + ))}
@@ -129,7 +149,7 @@ export function SessionSetupPrompt({ โณ Setting up... ) : ( - `${!isSafeDeployed ? "Deploy & " : ""}Authorize Session (${getTxCount()})` + `${setupInfo.title} (${setupInfo.txCount})` )}
diff --git a/apps/demo/src/hooks/useInitIdentity.ts b/apps/demo/src/hooks/useInitIdentity.ts new file mode 100644 index 0000000..8e93c2a --- /dev/null +++ b/apps/demo/src/hooks/useInitIdentity.ts @@ -0,0 +1,278 @@ +// src/hooks/useInitIdentity.ts +import { useState, useEffect, useCallback, useMemo } from 'react'; +import { BrowserProvider, Wallet } from 'ethers'; +import { + LogChainV1__factory, + type LogChainV1, +} from '@verbeth/contracts/typechain-types/index.js'; +import { + IExecutor, + ExecutorFactory, + deriveIdentityKeyPairWithProof, + IdentityKeyPair, + IdentityProof, + SafeSessionSigner, +} from '@verbeth/sdk'; +import { dbService } from '../services/DbService.js'; +import { getOrCreateSafeForOwner } from '../services/safeAccount.js'; +import { LOGCHAIN_SINGLETON_ADDR, SAFE_MODULE_ADDRESS, StoredIdentity } from '../types.js'; + +interface UseInitIdentityParams { + walletClient: any; + address: string | undefined; + chainId: number; + readProvider: any; + ready: boolean; + addLog: (message: string) => void; + // Callbacks + onIdentityCreated?: () => void; + onReset?: () => void; +} + +export function useInitIdentity({ + walletClient, + address, + chainId, + readProvider, + ready, + addLog, + onIdentityCreated, + onReset, +}: UseInitIdentityParams) { + const [identityKeyPair, setIdentityKeyPair] = useState(null); + const [identityProof, setIdentityProof] = useState(null); + const [executor, setExecutor] = useState(null); + const [contract, setContract] = useState(null); + const [identitySigner, setIdentitySigner] = useState(null); + const [txSigner, setTxSigner] = useState(null); + const [safeAddr, setSafeAddr] = useState(null); + const [currentAccount, setCurrentAccount] = useState(null); + const [needsIdentityCreation, setNeedsIdentityCreation] = useState(false); + const [loading, setLoading] = useState(false); + const [reinitTrigger, setReinitTrigger] = useState(0); + + // Session-related state (initialized here, used by useSessionSetup) + const [sessionSignerAddr, setSessionSignerAddr] = useState(null); + const [needsSessionSetup, setNeedsSessionSetup] = useState(false); + const [isSafeDeployed, setIsSafeDeployed] = useState(false); + const [isModuleEnabled, setIsModuleEnabled] = useState(false); + + const rpId = globalThis.location?.host ?? ''; + const identityContext = useMemo(() => ({ chainId, rpId }), [chainId, rpId]); + + const resetState = useCallback(() => { + setCurrentAccount(null); + setIdentityKeyPair(null); + setIdentityProof(null); + setIdentitySigner(null); + setTxSigner(null); + setContract(null); + setExecutor(null); + setNeedsIdentityCreation(false); + onReset?.(); + }, [onReset]); + + const switchToAccount = useCallback(async (newAddress: string) => { + setIdentityKeyPair(null); + setIdentityProof(null); + + await dbService.switchAccount(newAddress); + setCurrentAccount(newAddress); + + const storedIdentity = await dbService.getIdentity(newAddress); + if (storedIdentity) { + setIdentityKeyPair(storedIdentity.keyPair); + setIdentityProof(storedIdentity.proof ?? null); + setNeedsIdentityCreation(false); + addLog(`Identity keys restored from database`); + } else { + setNeedsIdentityCreation(true); + } + }, [addLog]); + + const initializeWagmiAccount = useCallback(async () => { + if (!walletClient || !address || !readProvider) return; + + const ethersProvider = new BrowserProvider(walletClient.transport); + const ethersSigner = await ethersProvider.getSigner(); + setIdentitySigner(ethersSigner); + + if (address !== currentAccount) { + await switchToAccount(address); + } + + const net = await ethersProvider.getNetwork(); + if (Number(net.chainId) !== chainId) { + addLog(`Wrong network: connected to chain ${Number(net.chainId)}, expected ${chainId}. Please switch network in your wallet.`); + return; + } + + // ============================================================ + // KEY CHANGE: Get session key FIRST, based on EOA (not Safe) + // This ensures consistent Safe address prediction + // ============================================================ + const sessionPrivKey = await dbService.getSessionPrivKey(address, chainId); + const sessionWallet = new Wallet(sessionPrivKey, readProvider); + const sessionAddr = await sessionWallet.getAddress(); + setSessionSignerAddr(sessionAddr); + + // Now predict/get Safe with sessionConfig included + // This ensures prediction matches what will be deployed + const { safeAddress, isDeployed, moduleEnabled } = await getOrCreateSafeForOwner({ + chainId, + ownerAddress: address as `0x${string}`, + providerEip1193: walletClient.transport, + ethersSigner, + deployIfMissing: false, + sessionConfig: { + sessionSigner: sessionAddr, + target: LOGCHAIN_SINGLETON_ADDR, + }, + }); + + setSafeAddr(safeAddress); + setIsSafeDeployed(isDeployed); + setIsModuleEnabled(moduleEnabled ?? false); + if (!isDeployed || !(moduleEnabled ?? false)) { + setNeedsSessionSetup(true); + } + + console.log(`\n========== SAFE & SESSION INFO ==========`); + console.log(`Connected EOA wallet: ${address}`); + console.log(`Associated Safe address: ${safeAddress}`); + console.log(` Safe deployed: ${isDeployed}`); + console.log(` Module enabled: ${moduleEnabled}`); + console.log(` Chain ID: ${chainId}`); + console.log(`๐Ÿ“ Session signer address: ${sessionAddr}`); + + // Check session signer balance + const balance = await readProvider.getBalance(sessionAddr); + const balanceEth = Number(balance) / 1e18; + console.log(`๐Ÿ’ฐ Session signer balance: ${balanceEth.toFixed(6)} ETH (${balance.toString()} wei)`); + + if (balance === 0n) { + addLog(`Session signer needs funding: ${sessionAddr}`); + } + + // Check if identity exists - if not, stop here and wait for identity creation + const storedIdentity = await dbService.getIdentity(address); + if (!storedIdentity) { + addLog(`Counterfactual Safe address: ${safeAddress.slice(0, 10)}... - awaiting identity creation`); + return; + } + + // Create SafeSessionSigner for transaction signing + const safeSessionSigner = new SafeSessionSigner({ + provider: readProvider, + safeAddress, + moduleAddress: SAFE_MODULE_ADDRESS, + logChainAddress: LOGCHAIN_SINGLETON_ADDR, + sessionSigner: sessionWallet, + }); + setTxSigner(safeSessionSigner); + + // Check if session is properly configured on the module + const isValid = await safeSessionSigner.isSessionValid(); + const isTargetAllowed = await safeSessionSigner.isTargetAllowed(); + console.log(`Session valid on module: ${isValid}`); + console.log(`LogChain target allowed: ${isTargetAllowed}`); + setNeedsSessionSetup(!isValid || !isTargetAllowed); + + if (!isValid || !isTargetAllowed) { + addLog(`โš ๏ธ Session needs setup on module (valid: ${isValid}, target: ${isTargetAllowed})`); + } + + const contractInstance = LogChainV1__factory.connect(LOGCHAIN_SINGLETON_ADDR, safeSessionSigner as any); + const executorInstance = ExecutorFactory.createEOA(contractInstance); + + setExecutor(executorInstance); + setContract(contractInstance); + }, [walletClient, address, currentAccount, chainId, readProvider, addLog, switchToAccount]); + + const createIdentity = useCallback(async () => { + if (!identitySigner || !address || !safeAddr) { + addLog('โœ— Missing signer/provider or address for identity creation'); + return; + } + + setLoading(true); + try { + addLog('Deriving new identity key (2 signatures)...'); + + const result = await deriveIdentityKeyPairWithProof(identitySigner, address, safeAddr, identityContext); + + setIdentityKeyPair(result.keyPair); + setIdentityProof(result.identityProof); + + const identityToStore: StoredIdentity = { + address: address, + keyPair: result.keyPair, + derivedAt: Date.now(), + proof: result.identityProof, + }; + + await dbService.saveIdentity(identityToStore); + addLog(`New identity key derived and saved for EOA`); + setNeedsIdentityCreation(false); + onIdentityCreated?.(); + + // Trigger re-initialization to complete Safe setup + setReinitTrigger((t) => t + 1); + } catch (signError: any) { + if (signError.code === 4001) { + addLog('User rejected signing request.'); + } else { + addLog(`โœ— Failed to derive identity: ${signError.message}`); + } + } finally { + setLoading(false); + } + }, [identitySigner, address, safeAddr, identityContext, addLog, onIdentityCreated]); + + // Handle initialization on ready/wallet/address/reinit changes + useEffect(() => { + const handleInit = async () => { + try { + if (ready && readProvider && walletClient && address) { + await initializeWagmiAccount(); + return; + } + if (!address) { + resetState(); + } + } catch (error) { + console.error('Failed to initialize:', error); + addLog(`โœ— Failed to initialize: ${error instanceof Error ? error.message : 'Unknown error'}`); + } + }; + handleInit(); + }, [ready, readProvider, walletClient, address, reinitTrigger]); + + return { + // Identity state + identityKeyPair, + identityProof, + executor, + contract, + identitySigner, + txSigner, + safeAddr, + currentAccount, + needsIdentityCreation, + identityLoading: loading, + identityContext, + // Session state (owned here, used by useSessionSetup) + sessionSignerAddr, + needsSessionSetup, + isSafeDeployed, + isModuleEnabled, + setSessionSignerAddr, + setNeedsSessionSetup, + setIsSafeDeployed, + setIsModuleEnabled, + // Actions + createIdentity, + resetState, + triggerReinit: () => setReinitTrigger((t) => t + 1), + }; +} \ No newline at end of file diff --git a/apps/demo/src/hooks/useSessionSetup.ts b/apps/demo/src/hooks/useSessionSetup.ts index f0271d9..d2930ce 100644 --- a/apps/demo/src/hooks/useSessionSetup.ts +++ b/apps/demo/src/hooks/useSessionSetup.ts @@ -1,16 +1,27 @@ // src/hooks/useSessionSetup.ts -import { useState, useEffect, useCallback } from 'react'; -import { BrowserProvider, Contract } from 'ethers'; -import { getOrCreateSafeForOwner, ensureModuleEnabled } from '../services/safeAccount.js'; -import { LOGCHAIN_SINGLETON_ADDR, SAFE_MODULE_ADDRESS } from '../types.js'; +import { useState, useEffect, useCallback } from "react"; +import { BrowserProvider, Contract } from "ethers"; +import { + getOrCreateSafeForOwner, + ensureModuleEnabled, +} from "../services/safeAccount.js"; +import { LOGCHAIN_SINGLETON_ADDR, SAFE_MODULE_ADDRESS } from "../types.js"; interface UseSessionSetupParams { walletClient: any; - address: `0x${string}` | undefined; + address: string | undefined; safeAddr: string | null; + sessionSignerAddr: string | null; chainId: number; readProvider: any; addLog: (message: string) => void; + // State from useInitIdentity + isSafeDeployed: boolean; + isModuleEnabled: boolean; + setIsSafeDeployed: (deployed: boolean) => void; + setIsModuleEnabled: (enabled: boolean) => void; + setNeedsSessionSetup: (needs: boolean) => void; + // Callbacks onSessionSetupComplete?: () => void; } @@ -18,16 +29,20 @@ export function useSessionSetup({ walletClient, address, safeAddr, + sessionSignerAddr, chainId, readProvider, addLog, + isSafeDeployed, + isModuleEnabled, + setIsSafeDeployed, + setIsModuleEnabled, + setNeedsSessionSetup, onSessionSetupComplete, }: UseSessionSetupParams) { - const [sessionSignerAddr, setSessionSignerAddr] = useState(null); - const [sessionSignerBalance, setSessionSignerBalance] = useState(null); - const [needsSessionSetup, setNeedsSessionSetup] = useState(false); - const [isSafeDeployed, setIsSafeDeployed] = useState(false); - const [isModuleEnabled, setIsModuleEnabled] = useState(false); + const [sessionSignerBalance, setSessionSignerBalance] = useState< + bigint | null + >(null); const [loading, setLoading] = useState(false); // Refresh session signer balance periodically @@ -78,39 +93,52 @@ export function useSessionSetup({ console.log(`Session signer: ${sessionSignerAddr}`); console.log(`Target (LogChain): ${LOGCHAIN_SINGLETON_ADDR}`); - let currentModuleEnabled = isModuleEnabled; - - // Step 1: Deploy Safe + Enable Module in one transaction + // ============================================================ + // CASE 1: Safe not deployed โ†’ Single TX (deploy + module + session) + // ============================================================ if (!isSafeDeployed) { - addLog("Deploying Safe + enabling module (tx 1)..."); + addLog("Deploying Safe + enabling module + configuring session (1 tx)..."); - const { isDeployed, moduleEnabled } = await getOrCreateSafeForOwner({ + const { isDeployed, moduleEnabled, sessionConfigured } = await getOrCreateSafeForOwner({ chainId, ownerAddress: address as `0x${string}`, providerEip1193: walletClient.transport, ethersSigner, deployIfMissing: true, - enableModuleDuringDeploy: true, + sessionConfig: { + sessionSigner: sessionSignerAddr, + target: LOGCHAIN_SINGLETON_ADDR, + }, }); if (!isDeployed) { throw new Error("Safe deployment failed"); } - console.log(`โœ… Safe deployed at ${safeAddr}`); setIsSafeDeployed(true); + setIsModuleEnabled(moduleEnabled); + + if (sessionConfigured) { + console.log(`โœ… Safe deployed + module enabled + session configured in 1 tx`); + addLog("โœ“ Setup complete (1 tx)!"); + console.log(`==========================================\n`); + setNeedsSessionSetup(false); + // Allow RPC state propagation before reinit + await new Promise(resolve => setTimeout(resolve, 1500)); + onSessionSetupComplete?.(); + return; + } - currentModuleEnabled = moduleEnabled ?? false; - setIsModuleEnabled(currentModuleEnabled); - if (currentModuleEnabled) { - console.log(`โœ… Module enabled during deployment`); - } + // Fallback: helper didn't configure session, need separate tx + console.warn("Session not configured during deploy, falling back to separate tx"); } - // Step 2: Enable module separately if deployment didn't include it - if (!currentModuleEnabled) { - addLog("Enabling session module (tx 2)..."); + // ============================================================ + // CASE 2: Safe exists but module not enabled โ†’ Enable module first + // ============================================================ + if (!isModuleEnabled) { + addLog("Enabling session module..."); const { protocolKit } = await getOrCreateSafeForOwner({ chainId, @@ -118,73 +146,65 @@ export function useSessionSetup({ providerEip1193: walletClient.transport, ethersSigner, deployIfMissing: false, + sessionConfig: { + sessionSigner: sessionSignerAddr, + target: LOGCHAIN_SINGLETON_ADDR, + }, }); await ensureModuleEnabled(protocolKit); setIsModuleEnabled(true); - console.log(`Module enabled`); + console.log(`โœ… Module enabled`); } - // Step 3: Register session signer + // ============================================================ + // CASE 3: Safe + module exist โ†’ Just setup session + // ============================================================ const moduleContract = new Contract( SAFE_MODULE_ADDRESS, - [ - "function setSession(address safe, address signer, uint256 expiry)", - "function setTarget(address safe, address target, bool allowed)", - ], + ["function setupSession(address safe, address signer, uint256 expiry, address target)"], ethersSigner ); - addLog("Registering session signer..."); - const tx1 = await moduleContract.setSession( + addLog("Setting up session (signer + target)..."); + const tx = await moduleContract.setupSession( safeAddr, sessionSignerAddr, - BigInt("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff") + BigInt("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"), // no expiry + LOGCHAIN_SINGLETON_ADDR ); - console.log(`TX hash: ${tx1.hash}`); - await tx1.wait(); - console.log(`โœ… Session signer authorized`); - - // Step 4: Allow LogChain target - addLog("Allowing LogChain target..."); - const tx2 = await moduleContract.setTarget( - safeAddr, - LOGCHAIN_SINGLETON_ADDR, - true - ); - console.log(`TX hash: ${tx2.hash}`); - await tx2.wait(); - console.log(`โœ… LogChain target allowed`); + console.log(`TX hash: ${tx.hash}`); + await tx.wait(); + console.log(`โœ… Session signer authorized + LogChain target allowed`); addLog("โœ“ Session setup complete!"); console.log(`==========================================\n`); setNeedsSessionSetup(false); - onSessionSetupComplete?.(); - } catch (err: any) { console.error(`Session setup error:`, err); addLog(`โœ— Session setup failed: ${err.message}`); } finally { setLoading(false); } - }, [walletClient, address, safeAddr, sessionSignerAddr, isSafeDeployed, isModuleEnabled, chainId, addLog, onSessionSetupComplete]); - - return { - // State + }, [ + walletClient, + address, + safeAddr, sessionSignerAddr, - sessionSignerBalance, - needsSessionSetup, isSafeDeployed, isModuleEnabled, - sessionLoading: loading, - // Setters (needed by initializeWagmiAccount) - setSessionSignerAddr, - setSessionSignerBalance, - setNeedsSessionSetup, + chainId, + addLog, setIsSafeDeployed, setIsModuleEnabled, - // Actions + setNeedsSessionSetup, + onSessionSetupComplete, + ]); + + return { + sessionSignerBalance, + sessionLoading: loading, refreshSessionBalance, setupSession, }; diff --git a/apps/demo/src/services/DbService.ts b/apps/demo/src/services/DbService.ts index f607751..b92c75a 100644 --- a/apps/demo/src/services/DbService.ts +++ b/apps/demo/src/services/DbService.ts @@ -101,29 +101,38 @@ export class DbService { return this.db.identity.delete(normalizedAddress); } - async getSessionPrivKey(safeAddress: string, chainId: number): Promise { - const { Wallet } = await import('ethers'); - const normalizedSafe = this.normalizeAddress(safeAddress); - const key = `sessionKey_${normalizedSafe}_${chainId}`; + async getSessionPrivKey( + ownerAddress: string, + chainId: number + ): Promise { + const { Wallet } = await import("ethers"); + const normalizedOwner = this.normalizeAddress(ownerAddress); + const key = `sessionKey_${normalizedOwner}_${chainId}`; let privKey = await this.getSetting(key); - + if (!privKey) { const newWallet = Wallet.createRandom(); privKey = newWallet.privateKey; await this.setSetting(key, privKey); - console.log(`๐Ÿ”‘ NEW session key created for Safe ${normalizedSafe.slice(0, 10)}...`); + console.log( + `๐Ÿ”‘ NEW session key created for EOA ${normalizedOwner.slice(0, 10)}...` + ); console.log(` Session signer address: ${newWallet.address}`); console.log(` Stored in IndexedDB with key: "${key}"`); } else { const existingWallet = new Wallet(privKey); - console.log(`๐Ÿ”‘ EXISTING session key loaded for Safe ${normalizedSafe.slice(0, 10)}...`); + console.log( + `๐Ÿ”‘ EXISTING session key loaded for EOA ${normalizedOwner.slice( + 0, + 10 + )}...` + ); console.log(` Session signer address: ${existingWallet.address}`); } - + return privKey; } - /* ------------------------------ CONTACTS --------------------------------- */ saveContact(contact: Contact) { const normalizedContact = { @@ -175,7 +184,7 @@ export class DbService { async upsertDedup(entry: { key: string; // `${ownerAddress}:${txHash}-${logIndex}` - messageId: string; + messageId: string; txHash: string; blockNumber: number; }) { @@ -191,7 +200,6 @@ export class DbService { /* ------------------------------ MESSAGES --------------------------------- */ async saveMessage(message: Message): Promise { - if (await this.db.messages.get(message.id)) { console.debug(`Message ${message.id} already in DB`); return false; @@ -434,21 +442,21 @@ export class DbService { /* --------------------------------- SYNC --------------------------------- */ getLastKnownBlock(addr: string) { - const normalizedAddr = this.normalizeAddress(addr); - return this.getSetting(`lastKnownBlock_${normalizedAddr}`); -} + const normalizedAddr = this.normalizeAddress(addr); + return this.getSetting(`lastKnownBlock_${normalizedAddr}`); + } setLastKnownBlock(addr: string, n: number) { - const normalizedAddr = this.normalizeAddress(addr); - return this.setSetting(`lastKnownBlock_${normalizedAddr}`, n); -} + const normalizedAddr = this.normalizeAddress(addr); + return this.setSetting(`lastKnownBlock_${normalizedAddr}`, n); + } getOldestScannedBlock(addr: string) { - const normalizedAddr = this.normalizeAddress(addr); - return this.getSetting(`oldestScannedBlock_${normalizedAddr}`); -} + const normalizedAddr = this.normalizeAddress(addr); + return this.getSetting(`oldestScannedBlock_${normalizedAddr}`); + } setOldestScannedBlock(addr: string, n: number) { - const normalizedAddr = this.normalizeAddress(addr); - return this.setSetting(`oldestScannedBlock_${normalizedAddr}`, n); -} + const normalizedAddr = this.normalizeAddress(addr); + return this.setSetting(`oldestScannedBlock_${normalizedAddr}`, n); + } getInitialScanComplete(addr: string) { const normalizedAddr = this.normalizeAddress(addr); return this.getSetting(`initialScanComplete_${normalizedAddr}`); diff --git a/apps/demo/src/services/safeAccount.ts b/apps/demo/src/services/safeAccount.ts index 18612f1..f5b2f9d 100644 --- a/apps/demo/src/services/safeAccount.ts +++ b/apps/demo/src/services/safeAccount.ts @@ -2,7 +2,7 @@ import SafeDefault from '@safe-global/protocol-kit' import SafeApiKitDefault from '@safe-global/api-kit' import { getAddress, Interface } from 'ethers' -import { SAFE_MODULE_ADDRESS } from '../types.js' +import { SAFE_MODULE_ADDRESS, LOGCHAIN_SINGLETON_ADDR } from '../types.js' // Handle ESM/CJS interop - safe libs export default differently const Safe = (SafeDefault as any).default ?? SafeDefault @@ -11,8 +11,13 @@ const SafeApiKit = (SafeApiKitDefault as any).default ?? SafeApiKitDefault const SAFE_API_KEY = import.meta.env.VITE_SAFE_API_KEY as string const MODULE_SETUP_HELPER_ADDRESS: Record = { - 84532: '0xc022F74924BDB4b62D830234d89b066359bF67c0', - 8453: '0xc022F74924BDB4b62D830234d89b066359bF67c0', + 84532: '0xbd59Fea46D308eDF3b75C22a6f64AC68feFc731A', + 8453: '0xc022F74924BDB4b62D830234d89b066359bF67c0', +} + +export interface SessionConfig { + sessionSigner: string + target: string } export async function getOrCreateSafeForOwner(params: { @@ -25,9 +30,11 @@ export async function getOrCreateSafeForOwner(params: { */ deployIfMissing?: boolean /** - * Enable the session module during deployment (only works with deployIfMissing=true) + * Session config - MUST be provided for consistent address prediction. + * The Safe address is deterministic based on setup params including to/data. + * Pass the same sessionConfig for both prediction and deployment. */ - enableModuleDuringDeploy?: boolean + sessionConfig: SessionConfig /** * Pass Safe contractNetworks if on a chain not bundled in this protocol-kit version */ @@ -39,7 +46,7 @@ export async function getOrCreateSafeForOwner(params: { providerEip1193, ethersSigner, deployIfMissing = false, - enableModuleDuringDeploy = false, + sessionConfig, contractNetworks, } = params @@ -50,12 +57,13 @@ export async function getOrCreateSafeForOwner(params: { ...(SAFE_API_KEY ? { apiKey: SAFE_API_KEY } : {}), }) - let safeAddress: `0x${string}` | undefined + let existingSafeAddress: `0x${string}` | undefined - // 1) Try to find an existing Safe for owner + // 1) Try to find an existing Safe for owner via API + // Note: This may return a Safe with different config. We'll verify below. try { const { safes } = await apiKit.getSafesByOwner(ownerAddress) - safeAddress = safes?.[0] as `0x${string}` | undefined + existingSafeAddress = safes?.[0] as `0x${string}` | undefined } catch (e: any) { const status = e?.response?.status ?? @@ -64,7 +72,7 @@ export async function getOrCreateSafeForOwner(params: { (typeof e?.message === 'string' && e.message.includes('404') ? 404 : undefined) if (status === 404) { - safeAddress = undefined + existingSafeAddress = undefined } else { throw new Error(`Safe Tx Service error: ${e?.message ?? String(e)}`) } @@ -73,74 +81,113 @@ export async function getOrCreateSafeForOwner(params: { // Spread optional contractNetworks only if provided const maybeNetworks = contractNetworks ? { contractNetworks } : {} - // 2) If not found, build predicted safe (deploy only if deployIfMissing=true) - if (!safeAddress) { - // Build the predicted safe configuration - // If enableModuleDuringDeploy=true, include the setup callback - const safeAccountConfig = buildSafeAccountConfig( - ownerAddress, - chainId, - enableModuleDuringDeploy && deployIfMissing - ) - - const predictedSafe = { - safeAccountConfig, - safeDeploymentConfig: { - saltNonce: '0', - }, - } + // 2) Build predicted safe config - ALWAYS include sessionConfig for consistent address + const safeAccountConfig = buildSafeAccountConfig(ownerAddress, chainId, sessionConfig) - let protocolKit = await Safe.init({ + const predictedSafe = { + safeAccountConfig, + safeDeploymentConfig: { + saltNonce: '0', + }, + } + + // 2b) If API didn't find a Safe, check on-chain at predicted address + if (!existingSafeAddress) { + const tempKit = await Safe.init({ provider: providerEip1193, signer: ownerAddress, predictedSafe, ...maybeNetworks, }) + const predictedAddress = await tempKit.getAddress() + const isDeployedOnChain = await tempKit.isSafeDeployed() - safeAddress = (await protocolKit.getAddress()) as `0x${string}` - - if (!deployIfMissing) { - return { safeAddress, protocolKit, isDeployed: false, moduleEnabled: false } + if (isDeployedOnChain) { + existingSafeAddress = predictedAddress as `0x${string}` + console.log(`Safe not in API but found on-chain at ${predictedAddress}`) } + } - // Deploy (createProxyWithNonce tx) - console.log(`๐Ÿš€ Deploying Safe${enableModuleDuringDeploy ? ' with module enabled' : ''}...`) - const deploymentTx = await protocolKit.createSafeDeploymentTransaction() - - const txResp = await ethersSigner.sendTransaction({ - to: deploymentTx.to, - data: deploymentTx.data, - value: BigInt(deploymentTx.value), + // 3) If existing Safe found, use it (may have been deployed with different config) + if (existingSafeAddress) { + const protocolKit = await Safe.init({ + provider: providerEip1193, + signer: ownerAddress, + safeAddress: existingSafeAddress, + ...maybeNetworks, }) - const receipt = await txResp.wait() - const statusOk = receipt?.status === 1 || receipt?.status === 1n - if (!statusOk) { - throw new Error('Safe deployment reverted') + const moduleEnabled = await protocolKit.isModuleEnabled(SAFE_MODULE_ADDRESS) + + return { + safeAddress: existingSafeAddress, + protocolKit, + isDeployed: true, + moduleEnabled, + sessionConfigured: false, // Can't know without checking module state } + } - console.log(`Safe deployed at ${safeAddress}`) + // 4) No existing Safe - predict address with our config + let protocolKit = await Safe.init({ + provider: providerEip1193, + signer: ownerAddress, + predictedSafe, + ...maybeNetworks, + }) - // Re-init on the deployed address - protocolKit = await Safe.init({ - provider: providerEip1193, - signer: ownerAddress, - safeAddress, - ...maybeNetworks, - }) + const safeAddress = (await protocolKit.getAddress()) as `0x${string}` - // Verify module is enabled if we tried to enable it - let moduleEnabled = false - if (enableModuleDuringDeploy) { - moduleEnabled = await protocolKit.isModuleEnabled(SAFE_MODULE_ADDRESS) - console.log(`Module enabled during deploy: ${moduleEnabled}`) + if (!deployIfMissing) { + return { + safeAddress, + protocolKit, + isDeployed: false, + moduleEnabled: false, + sessionConfigured: false, } + } + + // 5) Deploy (createProxyWithNonce tx) + console.log(`๐Ÿš€ Deploying Safe with module + session configured...`) + + const deploymentTx = await protocolKit.createSafeDeploymentTransaction() + + const txResp = await ethersSigner.sendTransaction({ + to: deploymentTx.to, + data: deploymentTx.data, + value: BigInt(deploymentTx.value), + }) + const receipt = await txResp.wait() + + const statusOk = receipt?.status === 1 || receipt?.status === 1n + if (!statusOk) { + throw new Error('Safe deployment reverted') + } + + console.log(`โœ… Safe deployed at ${safeAddress}`) + + // If we used the helper with sessionConfig, module + session are already configured + // Skip verification to avoid timing issues with RPC propagation + const helperAddress = MODULE_SETUP_HELPER_ADDRESS[chainId] + if (helperAddress && sessionConfig) { + console.log(` Module enabled: true (via helper)`) + console.log(` Session configured: true (via helper)`) - return { safeAddress, protocolKit, isDeployed: true, moduleEnabled } + return { + safeAddress, + protocolKit: null, // Not needed - caller should trigger reinit + isDeployed: true, + moduleEnabled: true, + sessionConfigured: true, + } } - // 3) Safe already exists - const protocolKit = await Safe.init({ + // Fallback: re-init and verify (for chains without helper) + // Add small delay to allow RPC propagation + await new Promise((resolve) => setTimeout(resolve, 2000)) + + protocolKit = await Safe.init({ provider: providerEip1193, signer: ownerAddress, safeAddress, @@ -148,48 +195,64 @@ export async function getOrCreateSafeForOwner(params: { }) const moduleEnabled = await protocolKit.isModuleEnabled(SAFE_MODULE_ADDRESS) + const sessionConfigured = false // Helper wasn't used + + console.log(` Module enabled: ${moduleEnabled}`) + console.log(` Session configured: ${sessionConfigured}`) - return { safeAddress, protocolKit, isDeployed: true, moduleEnabled } + return { + safeAddress, + protocolKit, + isDeployed: true, + moduleEnabled, + sessionConfigured, + } } /** - * Build SafeAccountConfig, optionally including module setup callback + * Build SafeAccountConfig with module + session setup callback. + * This MUST be used consistently for both prediction and deployment + * to ensure the same Safe address. */ function buildSafeAccountConfig( ownerAddress: string, chainId: number, - includeModuleSetup: boolean + sessionConfig: SessionConfig ): any { const baseConfig = { owners: [ownerAddress], threshold: 1, } - if (!includeModuleSetup) { - return baseConfig - } - const helperAddress = MODULE_SETUP_HELPER_ADDRESS[chainId] - if (!helperAddress || helperAddress === '0x...') { - console.warn(`โš ๏ธ ModuleSetupHelper not deployed on chain ${chainId}, falling back to separate tx`) + if (!helperAddress) { + console.warn(`โš ๏ธ ModuleSetupHelper not deployed on chain ${chainId}, using base config`) return baseConfig } - // Encode the enableModule call for the helper contract - const helperInterface = new Interface(['function enableModule(address module)']) - const enableModuleData = helperInterface.encodeFunctionData('enableModule', [ + // Encode enableModuleWithSession call for the helper contract + const helperInterface = new Interface([ + 'function enableModuleWithSession(address module, address sessionSigner, uint256 expiry, address target)', + ]) + + const NO_EXPIRY = '0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff' + + const setupData = helperInterface.encodeFunctionData('enableModuleWithSession', [ SAFE_MODULE_ADDRESS, + sessionConfig.sessionSigner, + NO_EXPIRY, + sessionConfig.target, ]) return { ...baseConfig, - to: helperAddress, - data: enableModuleData, + to: helperAddress, + data: setupData, } } /** - * Enable module on an already-deployed Safe + * Enable module on an already-deployed Safe (separate tx, for legacy Safes) */ export async function ensureModuleEnabled(protocolKit: any): Promise { const moduleAddress = getAddress(SAFE_MODULE_ADDRESS) @@ -204,6 +267,6 @@ export async function ensureModuleEnabled(protocolKit: any): Promise { const signed = await protocolKit.signTransaction(enableTx) const exec = await protocolKit.executeTransaction(signed) await exec.transactionResponse?.wait() - console.log(`Module enabled`) + console.log(`โœ… Module enabled`) return true } \ No newline at end of file diff --git a/packages/contracts/contracts/ModuleSetupHelper.sol b/packages/contracts/contracts/ModuleSetupHelper.sol new file mode 100644 index 0000000..182d88f --- /dev/null +++ b/packages/contracts/contracts/ModuleSetupHelper.sol @@ -0,0 +1,64 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.20; + +interface ISessionModule { + function setupSession( + address safe, + address signer, + uint256 expiry, + address target + ) external; +} + +contract ModuleSetupHelper { + /** + * @notice Enable a single module during Safe setup + * @param module The module address to enable + */ + function enableModule(address module) external { + (bool success, bytes memory returnData) = address(this).call( + abi.encodeWithSignature("enableModule(address)", module) + ); + require(success, string(abi.encodePacked("Enable module failed: ", returnData))); + } + + /** + * @notice Enable module and setup session in one delegatecall + * @param module The SessionModule address + * @param sessionSigner The session signer address to authorize + * @param expiry Session expiry timestamp (type(uint256).max for no expiry) + * @param target The target contract to allow calls to + * @dev This is called via delegatecall from Safe.setup() + * - address(this) = Safe + * - First call enables module on the Safe (internal call) + * - Second call configures session on the module (external call, msg.sender = Safe) + */ + function enableModuleWithSession( + address module, + address sessionSigner, + uint256 expiry, + address target + ) external { + (bool enableSuccess, bytes memory enableData) = address(this).call( + abi.encodeWithSignature("enableModule(address)", module) + ); + require(enableSuccess, string(abi.encodePacked("Enable module failed: ", enableData))); + + + ISessionModule(module).setupSession( + address(this), // safe + sessionSigner, + expiry, + target + ); + } + + function enableModules(address[] calldata modules) external { + for (uint256 i = 0; i < modules.length; i++) { + (bool success, bytes memory returnData) = address(this).call( + abi.encodeWithSignature("enableModule(address)", modules[i]) + ); + require(success, string(abi.encodePacked("Enable module failed: ", returnData))); + } + } +} \ No newline at end of file diff --git a/packages/contracts/contracts/SessionModule.sol b/packages/contracts/contracts/SessionModule.sol new file mode 100644 index 0000000..68722e1 --- /dev/null +++ b/packages/contracts/contracts/SessionModule.sol @@ -0,0 +1,112 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.20; + +interface ISafe { + function execTransactionFromModule( + address to, + uint256 value, + bytes memory data, + uint8 operation + ) external returns (bool success); + + function isOwner(address owner) external view returns (bool); +} + +/** + * @title SessionModule (Singleton) + * @notice Allows session signers to execute txs on behalf of any Safe that has enabled this module. + */ +contract SessionModule { + // safe => sessionSigner => expiry timestamp (0 = never expires, < block.timestamp = expired) + mapping(address => mapping(address => uint256)) public sessionExpiry; + + // safe => target => allowed + mapping(address => mapping(address => bool)) public isAllowedTarget; + + event SessionSignerSet(address indexed safe, address indexed signer, uint256 expiry); + event TargetSet(address indexed safe, address indexed target, bool allowed); + event Executed(address indexed safe, address indexed to, uint256 value, bool success); + + error NotOwnerOrSafe(); + error SessionExpiredOrInvalid(); + error TargetNotAllowed(); + error ExecutionFailed(); + + /// @notice Authorize if caller is Safe owner or the Safe itself + /// @dev Allowing Safe as caller enables setup during deployment via delegatecall helper + modifier onlySafeOwnerOrSafe(address safe) { + if (msg.sender != safe && !ISafe(safe).isOwner(msg.sender)) revert NotOwnerOrSafe(); + _; + } + + /// @notice Check if a session signer is currently valid + function isValidSession( + address safe, + address signer + ) public view returns (bool) { + uint256 expiry = sessionExpiry[safe][signer]; + if (expiry == 0) return false; // never set + if (expiry == type(uint256).max) return true; // never expires + return block.timestamp < expiry; + } + + function setSession( + address safe, + address signer, + uint256 expiry + ) external onlySafeOwnerOrSafe(safe) { + sessionExpiry[safe][signer] = expiry; + emit SessionSignerSet(safe, signer, expiry); + } + + function setTarget( + address safe, + address target, + bool allowed + ) external onlySafeOwnerOrSafe(safe) { + isAllowedTarget[safe][target] = allowed; + emit TargetSet(safe, target, allowed); + } + + + /// @notice set session signer AND allow target in one tx + /// @param safe The Safe address + /// @param signer The session signer address + /// @param expiry Timestamp when session expires (type(uint256).max for no expiry) + /// @param target The target contract to allow + function setupSession( + address safe, + address signer, + uint256 expiry, + address target + ) external onlySafeOwnerOrSafe(safe) { + sessionExpiry[safe][signer] = expiry; + emit SessionSignerSet(safe, signer, expiry); + + isAllowedTarget[safe][target] = true; + emit TargetSet(safe, target, true); + } + + /// @notice Execute a transaction on behalf of the Safe (called by session signer) + function execute( + address safe, + address to, + uint256 value, + bytes calldata data, + uint8 operation + ) external returns (bool) { + if (!isValidSession(safe, msg.sender)) revert SessionExpiredOrInvalid(); + if (!isAllowedTarget[safe][to]) revert TargetNotAllowed(); + + bool success = ISafe(safe).execTransactionFromModule( + to, + value, + data, + operation + ); + emit Executed(safe, to, value, success); + + if (!success) revert ExecutionFailed(); + return success; + } +} diff --git a/packages/contracts/hardhat.config.ts b/packages/contracts/hardhat.config.ts index 354c738..1edda8a 100644 --- a/packages/contracts/hardhat.config.ts +++ b/packages/contracts/hardhat.config.ts @@ -49,7 +49,6 @@ const config: HardhatUserConfig = { ignition: { strategyConfig: { create2: { - // "VERBETH" in hex salt: "0x5645524245544800000000000000000000000000000000000000000000000000", }, }, diff --git a/packages/contracts/ignition/modules/SessionModule.ts b/packages/contracts/ignition/modules/SessionModule.ts new file mode 100644 index 0000000..dc4969b --- /dev/null +++ b/packages/contracts/ignition/modules/SessionModule.ts @@ -0,0 +1,11 @@ +import { buildModule } from "@nomicfoundation/hardhat-ignition/modules"; + +const SessionModuleModule = buildModule("SessionModuleModule", (m) => { + const sessionModule = m.contract("SessionModule"); + + const moduleSetupHelper = m.contract("ModuleSetupHelper"); + + return { sessionModule, moduleSetupHelper }; +}); + +export default SessionModuleModule; diff --git a/packages/contracts/package.json b/packages/contracts/package.json index 49152ee..2686614 100644 --- a/packages/contracts/package.json +++ b/packages/contracts/package.json @@ -29,7 +29,9 @@ "deploy:local": "hardhat ignition deploy ignition/modules/LogChain.ts --network localhost --strategy create2", "deploy:testnet": "hardhat ignition deploy ignition/modules/LogChain.ts --network baseSepolia --strategy create2", "deploy:mainnet": "hardhat ignition deploy ignition/modules/LogChain.ts --network base --strategy create2", - "deploy:mainnet:validator": "hardhat ignition deploy ignition/modules/UniversalSigValidator.ts --network base --strategy create2" + "deploy:mainnet:validator": "hardhat ignition deploy ignition/modules/UniversalSigValidator.ts --network base --strategy create2", + "deploy:mainnet:session": "hardhat ignition deploy ignition/modules/SessionModule.ts --network base --strategy create2", + "deploy:testnet:session": "hardhat ignition deploy ignition/modules/SessionModule.ts --network baseSepolia --strategy create2" }, "exports": { "./typechain-types/*": "./typechain-types/*", diff --git a/packages/sdk/src/identity.ts b/packages/sdk/src/identity.ts index 611b6f2..c98987a 100644 --- a/packages/sdk/src/identity.ts +++ b/packages/sdk/src/identity.ts @@ -4,6 +4,7 @@ import { Signer, concat, hexlify, getBytes } from "ethers"; import nacl from "tweetnacl"; import { encodeUnifiedPubKeys } from "./payload.js"; import { IdentityContext, IdentityKeyPair, IdentityProof } from "./types.js"; +import { exec } from "child_process"; const SECP256K1_N = BigInt( @@ -49,15 +50,12 @@ function canonicalizeEcdsaSig65(sig: Uint8Array): Uint8Array { return out; } -function buildSeedMessage(addrLower: string, ctx?: IdentityContext): string { +function buildSeedMessage(addrLower: string): string { const lines = [ "VerbEth Identity Seed v1", `Address: ${addrLower}`, "Context: verbeth", - "Version: 1", ]; - if (typeof ctx?.chainId === "number") lines.push(`ChainId: ${ctx.chainId}`); - if (ctx?.rpId) lines.push(`RpId: ${ctx.rpId}`); return lines.join("\n"); } @@ -65,6 +63,7 @@ function buildBindingMessage( addrLower: string, pkEd25519Hex: string, pkX25519Hex: string, + executorSafeAddress?: string, ctx?: IdentityContext ): string { const lines = [ @@ -72,10 +71,10 @@ function buildBindingMessage( `Address: ${addrLower}`, `PkEd25519: ${pkEd25519Hex}`, `PkX25519: ${pkX25519Hex}`, + `ExecutorSafeAddress: ${executorSafeAddress ?? ""}` ]; if (typeof ctx?.chainId === "number") lines.push(`ChainId: ${ctx.chainId}`); if (ctx?.rpId) lines.push(`RpId: ${ctx.rpId}`); - lines.push("Context: verbeth", "Version: 1"); return lines.join("\n"); } @@ -86,13 +85,15 @@ function buildBindingMessage( export async function deriveIdentityKeyPairWithProof( signer: any, address: string, + executorSafeAddress?: string, ctx?: IdentityContext ): Promise<{ keyPair: IdentityKeyPair; identityProof: IdentityProof }> { const enc = new TextEncoder(); const addrLower = address.toLowerCase(); + const executorSafeAddressLower = executorSafeAddress?.toLowerCase(); // 1) Signature-based seed - const seedMessage = buildSeedMessage(addrLower, ctx); + const seedMessage = buildSeedMessage(addrLower); let seedSignature = await signer.signMessage(seedMessage); const seedSigBytes = canonicalizeEcdsaSig65(getBytes(seedSignature)); seedSignature = ""; // wipe from memory @@ -138,11 +139,12 @@ export async function deriveIdentityKeyPairWithProof( signingSecretKey: signKeyPair.secretKey, }; - // 2) Second signature: binding both public keys (as before) + // 2) Second signature: binding both public keys + safe address const message = buildBindingMessage( addrLower, pkEd25519Hex, pkX25519Hex, + executorSafeAddressLower, ctx ); const signature = await signer.signMessage(message); @@ -163,6 +165,7 @@ export async function deriveIdentityKeyPairWithProof( export async function deriveIdentityWithUnifiedKeys( signer: Signer, address: string, + executorSafeAddress?: string, ctx?: IdentityContext ): Promise<{ identityProof: IdentityProof; @@ -170,7 +173,7 @@ export async function deriveIdentityWithUnifiedKeys( signingPubKey: Uint8Array; unifiedPubKeys: Uint8Array; }> { - const result = await deriveIdentityKeyPairWithProof(signer, address, ctx); + const result = await deriveIdentityKeyPairWithProof(signer, address, executorSafeAddress ,ctx); const unifiedPubKeys = encodeUnifiedPubKeys( result.keyPair.publicKey, // X25519 diff --git a/packages/sdk/src/index.ts b/packages/sdk/src/index.ts index fed532e..4cf134e 100644 --- a/packages/sdk/src/index.ts +++ b/packages/sdk/src/index.ts @@ -46,8 +46,8 @@ export { ExecutorFactory } from './executor.js'; -export { SafeSessionSigner } from "./safeSessionSigner.js"; -export type { SafeSessionSignerOptions } from "./safeSessionSigner.js"; +export { SafeSessionSigner } from "./utils/safeSessionSigner.js"; +export type { SafeSessionSignerOptions } from "./utils/safeSessionSigner.js"; // high-level client API export { VerbethClient } from './client/index.js'; diff --git a/packages/sdk/src/utils.ts b/packages/sdk/src/utils.ts index 29795a9..9395e74 100644 --- a/packages/sdk/src/utils.ts +++ b/packages/sdk/src/utils.ts @@ -22,6 +22,7 @@ export function parseBindingMessage(message: string): { address?: string; pkEd25519?: `0x${string}`; pkX25519?: `0x${string}`; + executorSafeAddress?: string; context?: string; version?: string; chainId?: number; @@ -45,6 +46,9 @@ export function parseBindingMessage(message: string): { if (key === "pkx25519") { out.pkX25519 = hexlify(val) as `0x${string}`; } + if (key === "executorsafeaddress" || key === "executorsafe") { + out.executorSafeAddress = getAddress(val); + } if (key === "context") out.context = val; if (key === "version") out.version = val; if (key === "chainid") out.chainId = Number(val); diff --git a/packages/sdk/src/safeSessionSigner.ts b/packages/sdk/src/utils/safeSessionSigner.ts similarity index 54% rename from packages/sdk/src/safeSessionSigner.ts rename to packages/sdk/src/utils/safeSessionSigner.ts index d206182..25e461d 100644 --- a/packages/sdk/src/safeSessionSigner.ts +++ b/packages/sdk/src/utils/safeSessionSigner.ts @@ -1,4 +1,4 @@ -// packages/sdk/src/safeSessionSigner.ts +// packages/sdk/src/utils/safeSessionSigner.ts import { AbstractSigner, Contract, @@ -13,34 +13,20 @@ import { export interface SafeSessionSignerOptions { provider: Provider; safeAddress: string; - /** Safe module enabled on the Safe */ moduleAddress: string; - /** only allowed target */ logChainAddress: string; - /** The EOA session signer (pays gas, calls the module). Must be connected to a provider. */ sessionSigner: Signer; - - /** Default: execute(address,uint256,bytes,uint8) */ - moduleAbi?: readonly string[]; - /** Default: "execute" */ - executeMethod?: string; } -const DEFAULT_ABI = [ - "function execute(address to, uint256 value, bytes data, uint8 operation)", +const MODULE_ABI = [ + "function execute(address safe, address to, uint256 value, bytes data, uint8 operation) returns (bool)", + "function isValidSession(address safe, address signer) view returns (bool)", + "function sessionExpiry(address safe, address signer) view returns (uint256)", + "function isAllowedTarget(address safe, address target) view returns (bool)", ] as const; -/** - * Ethers v6 Signer adapter: - * - Exposes address = Safe - * - Intercepts txs to LogChain and routes them through the Safe module - * - * sessionSigner is an EOA that directly sends the module tx. - */ export class SafeSessionSigner extends AbstractSigner { private module: Contract; - private executeMethod: string; - private opts: SafeSessionSignerOptions; constructor(opts: SafeSessionSignerOptions) { @@ -49,28 +35,40 @@ export class SafeSessionSigner extends AbstractSigner { if (!opts.sessionSigner.provider) { throw new Error( - "SafeSessionSigner: sessionSigner must be connected to a Provider (e.g., new Wallet(pk, provider))." + "SafeSessionSigner: sessionSigner must be connected to a Provider." ); } this.module = new Contract( opts.moduleAddress, - (opts.moduleAbi ?? DEFAULT_ABI) as any, + MODULE_ABI as any, opts.sessionSigner ); - this.executeMethod = opts.executeMethod ?? "execute"; } override async getAddress(): Promise { return this.opts.safeAddress; } + async getSessionSignerAddress(): Promise { + return this.opts.sessionSigner.getAddress(); + } + + async isSessionValid(): Promise { + const signerAddr = await this.opts.sessionSigner.getAddress(); + return this.module.isValidSession(this.opts.safeAddress, signerAddr); + } + + async isTargetAllowed(): Promise { + return this.module.isAllowedTarget(this.opts.safeAddress, this.opts.logChainAddress); + } + override async signMessage(message: string | Uint8Array): Promise { return this.opts.sessionSigner.signMessage(message); } override async signTransaction(_tx: TransactionRequest): Promise { - throw new Error("SafeSessionSigner: signTransaction not supported; use sendTransaction()."); + throw new Error("SafeSessionSigner: use sendTransaction() instead."); } override async signTypedData( @@ -78,37 +76,36 @@ export class SafeSessionSigner extends AbstractSigner { types: Record>, value: Record ): Promise { - // delegate const anySigner = this.opts.sessionSigner as any; if (typeof anySigner.signTypedData === "function") { return anySigner.signTypedData(domain, types, value); } - throw new Error("SafeSessionSigner: underlying sessionSigner does not support signTypedData."); + throw new Error("SafeSessionSigner: signTypedData not supported."); } override async sendTransaction(tx: TransactionRequest): Promise { - if (!tx.to) throw new Error("SafeSessionSigner: tx.to is required"); + if (!tx.to) throw new Error("SafeSessionSigner: tx.to required"); const to = String(tx.to).toLowerCase(); const logChain = this.opts.logChainAddress.toLowerCase(); if (to !== logChain) { - throw new Error(`SafeSessionSigner: only LogChain txs are supported. Got to=${tx.to}`); + throw new Error(`SafeSessionSigner: only LogChain txs allowed. Got ${tx.to}`); } const data = tx.data ?? "0x"; - const fn: any = (this.module as any)[this.executeMethod]; - if (typeof fn !== "function") { - throw new Error( - `SafeSessionSigner: module execute method "${this.executeMethod}" not found on ${this.opts.moduleAddress}` - ); - } - - // operation: 0 = CALL, value: 0 - return fn(this.opts.logChainAddress, 0n, data, 0); + + // execute(safe, to, value, data, operation) + return this.module.execute( + this.opts.safeAddress, + this.opts.logChainAddress, + 0n, + data, + 0 + ); } override connect(provider: Provider): SafeSessionSigner { return new SafeSessionSigner({ ...this.opts, provider }); } -} +} \ No newline at end of file diff --git a/packages/sdk/src/verify.ts b/packages/sdk/src/verify.ts index 6d1eb49..95472c5 100644 --- a/packages/sdk/src/verify.ts +++ b/packages/sdk/src/verify.ts @@ -135,7 +135,7 @@ export async function verifyHandshakeResponseIdentity( */ export async function verifyIdentityProof( identityProof: IdentityProof, - smartAccountAddress: string, + address: string, expectedUnifiedKeys: { identityPubKey: Uint8Array; signingPubKey: Uint8Array; @@ -145,31 +145,36 @@ export async function verifyIdentityProof( ): Promise { try { const client = await makeViemPublicClient(provider); - const address = smartAccountAddress as `0x${string}`; + const inputAddress = address as `0x${string}`; + + const parsed = parseBindingMessage(identityProof.message); + + if (!parsed.address) { + console.error("Parsed address is undefined"); + return false; + } + const signerAddress = getAddress(parsed.address) as `0x${string}`; const okSig = await client.verifyMessage({ - address, + address: signerAddress, message: identityProof.message, signature: identityProof.signature as `0x${string}`, }); if (!okSig) { - console.error("Binding signature invalid for address"); + console.error("Binding signature invalid for signer address"); return false; } - const parsed = parseBindingMessage(identityProof.message); - if (parsed.header && parsed.header !== "VerbEth Key Binding v1") { console.error("Unexpected binding header:", parsed.header); return false; } - if ( - !parsed.address || - getAddress(parsed.address) !== getAddress(smartAccountAddress) + !parsed.executorSafeAddress || + getAddress(parsed.executorSafeAddress) !== getAddress(inputAddress) ) { - console.error("Binding message address mismatch"); + console.error("Binding message Safe address mismatch"); return false; } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5adf7db..e06b879 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -23,37 +23,37 @@ importers: version: 2.3.0 '@types/node': specifier: ^20.0.0 - version: 20.19.9 + version: 20.19.27 ethers: specifier: ^6.7.0 - version: 6.15.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + version: 6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) tweetnacl: specifier: ^1.0.3 version: 1.0.3 typescript: specifier: ^5.4.0 - version: 5.8.3 + version: 5.9.3 vitest: specifier: ^3.1.4 - version: 3.2.4(@types/debug@4.1.12)(@types/node@20.19.9) + version: 3.2.4(@types/debug@4.1.12)(@types/node@20.19.27) apps/demo: dependencies: '@rainbow-me/rainbowkit': specifier: ^2.2.8 - version: 2.2.8(@tanstack/react-query@5.83.0(react@18.3.1))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.8.3)(viem@2.37.5(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4))(wagmi@2.16.0(@tanstack/query-core@5.83.0)(@tanstack/react-query@5.83.0(react@18.3.1))(@types/react@18.3.23)(bufferutil@4.0.9)(immer@10.0.2)(react@18.3.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(viem@2.37.5(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4))(zod@3.22.4)) + version: 2.2.10(@tanstack/react-query@5.90.12(react@18.3.1))(@types/react@18.3.27)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3)(viem@2.43.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1))(wagmi@2.19.5(@tanstack/query-core@5.90.12)(@tanstack/react-query@5.90.12(react@18.3.1))(@types/react@18.3.27)(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(immer@10.0.2)(react@18.3.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.43.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1))(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@4.2.1)) '@safe-global/api-kit': specifier: ^4.0.1 - version: 4.0.1(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) + version: 4.0.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) '@safe-global/protocol-kit': specifier: ^6.1.2 - version: 6.1.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) + version: 6.1.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) '@safe-global/types-kit': specifier: ^3.0.0 - version: 3.0.0(typescript@5.8.3)(zod@3.22.4) + version: 3.0.0(typescript@5.9.3)(zod@4.2.1) '@tanstack/react-query': specifier: ^5.59.20 - version: 5.83.0(react@18.3.1) + version: 5.90.12(react@18.3.1) '@verbeth/contracts': specifier: workspace:^0.1.0 version: link:../../packages/contracts @@ -65,13 +65,13 @@ importers: version: 6.0.3 dexie: specifier: ^4.0.8 - version: 4.0.11 + version: 4.2.1 ethers: specifier: ^6.7.0 - version: 6.15.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + version: 6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) framer-motion: specifier: ^12.23.9 - version: 12.23.9(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 12.23.26(react-dom@18.3.1(react@18.3.1))(react@18.3.1) lucide-react: specifier: ^0.525.0 version: 0.525.0(react@18.3.1) @@ -86,38 +86,38 @@ importers: version: 1.0.3 viem: specifier: ^2.17.11 - version: 2.37.5(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) + version: 2.43.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) wagmi: specifier: ^2.14.3 - version: 2.16.0(@tanstack/query-core@5.83.0)(@tanstack/react-query@5.83.0(react@18.3.1))(@types/react@18.3.23)(bufferutil@4.0.9)(immer@10.0.2)(react@18.3.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(viem@2.37.5(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4))(zod@3.22.4) + version: 2.19.5(@tanstack/query-core@5.90.12)(@tanstack/react-query@5.90.12(react@18.3.1))(@types/react@18.3.27)(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(immer@10.0.2)(react@18.3.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.43.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1))(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@4.2.1) devDependencies: '@types/react': specifier: ^18.2.0 - version: 18.3.23 + version: 18.3.27 '@types/react-dom': specifier: ^18.2.0 - version: 18.3.7(@types/react@18.3.23) + version: 18.3.7(@types/react@18.3.27) '@vitejs/plugin-react': specifier: ^4.0.0 - version: 4.7.0(vite@5.4.19(@types/node@22.7.5)) + version: 4.7.0(vite@5.4.21(@types/node@22.7.5)) autoprefixer: specifier: ^10.4.20 - version: 10.4.21(postcss@8.5.6) + version: 10.4.23(postcss@8.5.6) postcss: specifier: ^8.4.47 version: 8.5.6 tailwindcss: specifier: ^3.4.13 - version: 3.4.17(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.8.3)) + version: 3.4.19 typescript: specifier: ^5.4.0 - version: 5.8.3 + version: 5.9.3 vite: specifier: ^5.0.0 - version: 5.4.19(@types/node@22.7.5) + version: 5.4.21(@types/node@22.7.5) vite-plugin-wasm: specifier: ^3.4.0 - version: 3.5.0(vite@5.4.19(@types/node@22.7.5)) + version: 3.5.0(vite@5.4.21(@types/node@22.7.5)) packages/contracts: dependencies: @@ -130,10 +130,10 @@ importers: version: 0.8.0 '@nomicfoundation/hardhat-ignition': specifier: ^0.15.10 - version: 0.15.13(@nomicfoundation/hardhat-verify@2.1.0(hardhat@2.26.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.8.3))(typescript@5.8.3)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(hardhat@2.26.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.8.3))(typescript@5.8.3)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) + version: 0.15.16(@nomicfoundation/hardhat-verify@2.1.3(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) '@nomicfoundation/hardhat-toolbox': specifier: ^5.0.0 - version: 5.0.0(0e4b137f5db723198014a5b4a31800ae) + version: 5.0.0(718d8c1f3463e528ebfebd4ac5f4e994) '@openzeppelin/community-contracts': specifier: github:OpenZeppelin/openzeppelin-community-contracts version: https://codeload.github.com/OpenZeppelin/openzeppelin-community-contracts/tar.gz/7322fa7de0beabe0e0cf7e8663f879d406bb3f42 @@ -145,13 +145,13 @@ importers: version: 5.4.0(@openzeppelin/contracts@5.4.0) '@openzeppelin/hardhat-upgrades': specifier: ^3.9.0 - version: 3.9.1(@nomicfoundation/hardhat-ethers@3.1.0(ethers@6.15.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(hardhat@2.26.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.8.3))(typescript@5.8.3)(utf-8-validate@5.0.10)))(@nomicfoundation/hardhat-verify@2.1.0(hardhat@2.26.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.8.3))(typescript@5.8.3)(utf-8-validate@5.0.10)))(ethers@6.15.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(hardhat@2.26.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.8.3))(typescript@5.8.3)(utf-8-validate@5.0.10)) + version: 3.9.1(@nomicfoundation/hardhat-ethers@3.1.3(ethers@6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10)))(@nomicfoundation/hardhat-verify@2.1.3(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10)))(ethers@6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10)) '@typechain/ethers-v6': specifier: ^0.5.1 - version: 0.5.1(ethers@6.15.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(typechain@8.3.2(typescript@5.8.3))(typescript@5.8.3) + version: 0.5.1(ethers@6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(typechain@8.3.2(typescript@5.9.3))(typescript@5.9.3) '@typechain/hardhat': specifier: ^9.1.0 - version: 9.1.0(@typechain/ethers-v6@0.5.1(ethers@6.15.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(typechain@8.3.2(typescript@5.8.3))(typescript@5.8.3))(ethers@6.15.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(hardhat@2.26.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.8.3))(typescript@5.8.3)(utf-8-validate@5.0.10))(typechain@8.3.2(typescript@5.8.3)) + version: 9.1.0(@typechain/ethers-v6@0.5.1(ethers@6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(typechain@8.3.2(typescript@5.9.3))(typescript@5.9.3))(ethers@6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10))(typechain@8.3.2(typescript@5.9.3)) '@types/chai': specifier: ^4.3.20 version: 4.3.20 @@ -163,28 +163,28 @@ importers: version: 16.6.1 ethers: specifier: ^6.7.0 - version: 6.15.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + version: 6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) hardhat: specifier: ^2.23.0 - version: 2.26.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.8.3))(typescript@5.8.3)(utf-8-validate@5.0.10) + version: 2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10) hardhat-dependency-compiler: specifier: ^1.2.1 - version: 1.2.1(hardhat@2.26.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.8.3))(typescript@5.8.3)(utf-8-validate@5.0.10)) + version: 1.2.1(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10)) hardhat-gas-reporter: specifier: ^1.0.9 - version: 1.0.10(bufferutil@4.0.9)(hardhat@2.26.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.8.3))(typescript@5.8.3)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) + version: 1.0.10(bufferutil@4.0.9)(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) typechain: specifier: ^8.3.2 - version: 8.3.2(typescript@5.8.3) + version: 8.3.2(typescript@5.9.3) typescript: specifier: ^5.0.0 - version: 5.8.3 + version: 5.9.3 packages/sdk: dependencies: '@noble/curves': specifier: ^1.8.1 - version: 1.9.4 + version: 1.9.7 '@noble/hashes': specifier: ^1.8.0 version: 1.8.0 @@ -193,26 +193,26 @@ importers: version: 2.3.0 ethers: specifier: ^6.7.0 - version: 6.15.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + version: 6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) tweetnacl: specifier: ^1.0.3 version: 1.0.3 viem: specifier: ^2.37.5 - version: 2.37.5(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) + version: 2.43.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) devDependencies: '@verbeth/contracts': specifier: workspace:^0.1.0 version: link:../contracts ts-node: specifier: ^10.9.2 - version: 10.9.2(@types/node@22.7.5)(typescript@5.8.3) + version: 10.9.2(@types/node@22.7.5)(typescript@5.9.3) typechain: specifier: ^8.3.2 - version: 8.3.2(typescript@5.8.3) + version: 8.3.2(typescript@5.9.3) typescript: specifier: ^5.4.0 - version: 5.8.3 + version: 5.9.3 vitest: specifier: ^3.1.4 version: 3.2.4(@types/debug@4.1.12)(@types/node@22.7.5) @@ -225,17 +225,13 @@ packages: '@adraffy/ens-normalize@1.10.1': resolution: {integrity: sha512-96Z2IP3mYmF1Xg2cDm8f1gWGf/HUVedQ3FMifV4kG/PQ4yEP51xDtRAEfhVNt5f/uzpNkZHwWQuUcu6D6K+Ekw==} - '@adraffy/ens-normalize@1.11.0': - resolution: {integrity: sha512-/3DDPKHqqIqxUULp8yP4zODUY1i+2xvVWsv8A79xGWdCAG+8sb0hRh0Rk2QyOJUnnbyPUAZYcpBuRe3nS2OIUg==} + '@adraffy/ens-normalize@1.11.1': + resolution: {integrity: sha512-nhCBV3quEgesuf7c7KYfperqSS14T8bYuvJ8PcLJp6znkZpFc0AuW4qBtr8eKVyPPe/8RSr7sglCWPU5eaxwKQ==} '@alloc/quick-lru@5.2.0': resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==} engines: {node: '>=10'} - '@ampproject/remapping@2.3.0': - resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} - engines: {node: '>=6.0.0'} - '@aws-crypto/crc32@5.2.0': resolution: {integrity: sha512-nLbCWqQNgUiwwtFsen1AdzAtvuLRsQS8rYgMuxCrdKf9kOssamGLuPwyTY9wyYblNr9+1XM8v6zoDTPPSIeANg==} engines: {node: '>=16.0.0'} @@ -259,91 +255,95 @@ packages: '@aws-crypto/util@5.2.0': resolution: {integrity: sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ==} - '@aws-sdk/client-lambda@3.851.0': - resolution: {integrity: sha512-wChFgkDH4TepG9HdqVAVYLrczzab4PN2hogK3k/h2KJKoHFiSjY66tlDlZ/CueLk09u3PGMkVrDBDEs0znaXIA==} + '@aws-sdk/client-lambda@3.954.0': + resolution: {integrity: sha512-psVZGa+kaTRfU7mPW0mOawPXgHvDOR0VdB/NOourwQ9Ug55HHeDneJ6pt9MvNeE5/AKkwm8avLHTB2W6hYV8ng==} + engines: {node: '>=18.0.0'} + + '@aws-sdk/client-sso@3.954.0': + resolution: {integrity: sha512-FVyMAvlFhLK68DHWB1lSkCRTm25xl38bIZDd+jKt5+yDolCrG5+n9aIN8AA8jNO1HNGhZuMjSIQm9r5rGmJH8g==} engines: {node: '>=18.0.0'} - '@aws-sdk/client-sso@3.848.0': - resolution: {integrity: sha512-mD+gOwoeZQvbecVLGoCmY6pS7kg02BHesbtIxUj+PeBqYoZV5uLvjUOmuGfw1SfoSobKvS11urxC9S7zxU/Maw==} + '@aws-sdk/core@3.954.0': + resolution: {integrity: sha512-5oYO5RP+mvCNXNj8XnF9jZo0EP0LTseYOJVNQYcii1D9DJqzHL3HJWurYh7cXxz7G7eDyvVYA01O9Xpt34TdoA==} engines: {node: '>=18.0.0'} - '@aws-sdk/core@3.846.0': - resolution: {integrity: sha512-7CX0pM906r4WSS68fCTNMTtBCSkTtf3Wggssmx13gD40gcWEZXsU00KzPp1bYheNRyPlAq3rE22xt4wLPXbuxA==} + '@aws-sdk/credential-provider-env@3.954.0': + resolution: {integrity: sha512-2HNkqBjfsvyoRuPAiFh86JBFMFyaCNhL4VyH6XqwTGKZffjG7hdBmzXPy7AT7G3oFh1k/1Zc27v0qxaKoK7mBA==} engines: {node: '>=18.0.0'} - '@aws-sdk/credential-provider-env@3.846.0': - resolution: {integrity: sha512-QuCQZET9enja7AWVISY+mpFrEIeHzvkx/JEEbHYzHhUkxcnC2Kq2c0bB7hDihGD0AZd3Xsm653hk1O97qu69zg==} + '@aws-sdk/credential-provider-http@3.954.0': + resolution: {integrity: sha512-CrWD5300+NE1OYRnSVDxoG7G0b5cLIZb7yp+rNQ5Jq/kqnTmyJXpVAsivq+bQIDaGzPXhadzpAMIoo7K/aHaag==} engines: {node: '>=18.0.0'} - '@aws-sdk/credential-provider-http@3.846.0': - resolution: {integrity: sha512-Jh1iKUuepdmtreMYozV2ePsPcOF5W9p3U4tWhi3v6nDvz0GsBjzjAROW+BW8XMz9vAD3I9R+8VC3/aq63p5nlw==} + '@aws-sdk/credential-provider-ini@3.954.0': + resolution: {integrity: sha512-WAFD8pVwRSoBsuXcoD+s/hrdsP9Z0PNUedSgkOGExuJVAabpM2cIIMzYNsdHio9XFZUSqHkv8mF5mQXuIZvuzg==} engines: {node: '>=18.0.0'} - '@aws-sdk/credential-provider-ini@3.848.0': - resolution: {integrity: sha512-r6KWOG+En2xujuMhgZu7dzOZV3/M5U/5+PXrG8dLQ3rdPRB3vgp5tc56KMqLwm/EXKRzAOSuw/UE4HfNOAB8Hw==} + '@aws-sdk/credential-provider-login@3.954.0': + resolution: {integrity: sha512-EYqaBWwdVbVK7prmsmgTWLPptoWREplPkFMFscOpVmseDvf/0IjYNbNLLtfuhy/6L7ZBGI9wat2k4u0MRivvxA==} engines: {node: '>=18.0.0'} - '@aws-sdk/credential-provider-node@3.848.0': - resolution: {integrity: sha512-AblNesOqdzrfyASBCo1xW3uweiSro4Kft9/htdxLeCVU1KVOnFWA5P937MNahViRmIQm2sPBCqL8ZG0u9lnh5g==} + '@aws-sdk/credential-provider-node@3.954.0': + resolution: {integrity: sha512-UPBjw7Lnly5i+/rES8Z5U+nPaumzEUYOE/wrHkxyH6JjwFWn8w7R07fE5Z5cgYlIq1U1lQ7sxYwB3wHPpQ65Aw==} engines: {node: '>=18.0.0'} - '@aws-sdk/credential-provider-process@3.846.0': - resolution: {integrity: sha512-mEpwDYarJSH+CIXnnHN0QOe0MXI+HuPStD6gsv3z/7Q6ESl8KRWon3weFZCDnqpiJMUVavlDR0PPlAFg2MQoPg==} + '@aws-sdk/credential-provider-process@3.954.0': + resolution: {integrity: sha512-Y1/0O2LgbKM8iIgcVj/GNEQW6p90LVTCOzF2CI1pouoKqxmZ/1F7F66WHoa6XUOfKaCRj/R6nuMR3om9ThaM5A==} engines: {node: '>=18.0.0'} - '@aws-sdk/credential-provider-sso@3.848.0': - resolution: {integrity: sha512-pozlDXOwJZL0e7w+dqXLgzVDB7oCx4WvtY0sk6l4i07uFliWF/exupb6pIehFWvTUcOvn5aFTTqcQaEzAD5Wsg==} + '@aws-sdk/credential-provider-sso@3.954.0': + resolution: {integrity: sha512-UXxGfkp/plFRdyidMLvNul5zoLKmHhVQOCrD2OgR/lg9jNqNmJ7abF+Qu8abo902iDkhU21Qj4M398cx6l8Kng==} engines: {node: '>=18.0.0'} - '@aws-sdk/credential-provider-web-identity@3.848.0': - resolution: {integrity: sha512-D1fRpwPxtVDhcSc/D71exa2gYweV+ocp4D3brF0PgFd//JR3XahZ9W24rVnTQwYEcK9auiBZB89Ltv+WbWN8qw==} + '@aws-sdk/credential-provider-web-identity@3.954.0': + resolution: {integrity: sha512-XEyf1T08q1tG4zkTS4Dnf1cAQyrJUo/xlvi6XNpqGhY3bOmKUYE2h/K6eITIdytDL9VuCpWYQ6YRcIVtL29E0w==} engines: {node: '>=18.0.0'} - '@aws-sdk/middleware-host-header@3.840.0': - resolution: {integrity: sha512-ub+hXJAbAje94+Ya6c6eL7sYujoE8D4Bumu1NUI8TXjUhVVn0HzVWQjpRLshdLsUp1AW7XyeJaxyajRaJQ8+Xg==} + '@aws-sdk/middleware-host-header@3.953.0': + resolution: {integrity: sha512-jTGhfkONav+r4E6HLOrl5SzBqDmPByUYCkyB/c/3TVb8jX3wAZx8/q9bphKpCh+G5ARi3IdbSisgkZrJYqQ19Q==} engines: {node: '>=18.0.0'} - '@aws-sdk/middleware-logger@3.840.0': - resolution: {integrity: sha512-lSV8FvjpdllpGaRspywss4CtXV8M7NNNH+2/j86vMH+YCOZ6fu2T/TyFd/tHwZ92vDfHctWkRbQxg0bagqwovA==} + '@aws-sdk/middleware-logger@3.953.0': + resolution: {integrity: sha512-PlWdVYgcuptkIC0ZKqVUhWNtSHXJSx7U9V8J7dJjRmsXC40X7zpEycvrkzDMJjeTDGcCceYbyYAg/4X1lkcIMw==} engines: {node: '>=18.0.0'} - '@aws-sdk/middleware-recursion-detection@3.840.0': - resolution: {integrity: sha512-Gu7lGDyfddyhIkj1Z1JtrY5NHb5+x/CRiB87GjaSrKxkDaydtX2CU977JIABtt69l9wLbcGDIQ+W0uJ5xPof7g==} + '@aws-sdk/middleware-recursion-detection@3.953.0': + resolution: {integrity: sha512-cmIJx0gWeesUKK4YwgE+VQL3mpACr3/J24fbwnc1Z5tntC86b+HQFzU5vsBDw6lLwyD46dBgWdsXFh1jL+ZaFw==} engines: {node: '>=18.0.0'} - '@aws-sdk/middleware-user-agent@3.848.0': - resolution: {integrity: sha512-rjMuqSWJEf169/ByxvBqfdei1iaduAnfolTshsZxwcmLIUtbYrFUmts0HrLQqsAG8feGPpDLHA272oPl+NTCCA==} + '@aws-sdk/middleware-user-agent@3.954.0': + resolution: {integrity: sha512-5PX8JDe3dB2+MqXeGIhmgFnm2rbVsSxhz+Xyuu1oxLtbOn+a9UDA+sNBufEBjt3UxWy5qwEEY1fxdbXXayjlGg==} engines: {node: '>=18.0.0'} - '@aws-sdk/nested-clients@3.848.0': - resolution: {integrity: sha512-joLsyyo9u61jnZuyYzo1z7kmS7VgWRAkzSGESVzQHfOA1H2PYeUFek6vLT4+c9xMGrX/Z6B0tkRdzfdOPiatLg==} + '@aws-sdk/nested-clients@3.954.0': + resolution: {integrity: sha512-JLUhf35fTQIDPLk6G5KPggL9tV//Hjhy6+N2zZeis76LuBRNhKDq8z1CFyKhjf00vXi/tDYdn9D7y9emI+5Y/g==} engines: {node: '>=18.0.0'} - '@aws-sdk/region-config-resolver@3.840.0': - resolution: {integrity: sha512-Qjnxd/yDv9KpIMWr90ZDPtRj0v75AqGC92Lm9+oHXZ8p1MjG5JE2CW0HL8JRgK9iKzgKBL7pPQRXI8FkvEVfrA==} + '@aws-sdk/region-config-resolver@3.953.0': + resolution: {integrity: sha512-5MJgnsc+HLO+le0EK1cy92yrC7kyhGZSpaq8PcQvKs9qtXCXT5Tb6tMdkr5Y07JxYsYOV1omWBynvL6PWh08tQ==} engines: {node: '>=18.0.0'} - '@aws-sdk/token-providers@3.848.0': - resolution: {integrity: sha512-oNPyM4+Di2Umu0JJRFSxDcKQ35+Chl/rAwD47/bS0cDPI8yrao83mLXLeDqpRPHyQW4sXlP763FZcuAibC0+mg==} + '@aws-sdk/token-providers@3.954.0': + resolution: {integrity: sha512-rDyN3oQQKMOJgyQ9/LNbh4fAGAj8ePMGOAQzSP/kyzizmViI6STpBW1o/VRqiTgMNi1bvA9ZasDtfrJqcVt0iA==} engines: {node: '>=18.0.0'} - '@aws-sdk/types@3.840.0': - resolution: {integrity: sha512-xliuHaUFZxEx1NSXeLLZ9Dyu6+EJVQKEoD+yM+zqUo3YDZ7medKJWY6fIOKiPX/N7XbLdBYwajb15Q7IL8KkeA==} + '@aws-sdk/types@3.953.0': + resolution: {integrity: sha512-M9Iwg9kTyqTErI0vOTVVpcnTHWzS3VplQppy8MuL02EE+mJ0BIwpWfsaAPQW+/XnVpdNpWZTsHcNE29f1+hR8g==} engines: {node: '>=18.0.0'} - '@aws-sdk/util-endpoints@3.848.0': - resolution: {integrity: sha512-fY/NuFFCq/78liHvRyFKr+aqq1aA/uuVSANjzr5Ym8c+9Z3HRPE9OrExAHoMrZ6zC8tHerQwlsXYYH5XZ7H+ww==} + '@aws-sdk/util-endpoints@3.953.0': + resolution: {integrity: sha512-rjaS6jrFksopXvNg6YeN+D1lYwhcByORNlFuYesFvaQNtPOufbE5tJL4GJ3TMXyaY0uFR28N5BHHITPyWWfH/g==} engines: {node: '>=18.0.0'} - '@aws-sdk/util-locate-window@3.804.0': - resolution: {integrity: sha512-zVoRfpmBVPodYlnMjgVjfGoEZagyRF5IPn3Uo6ZvOZp24chnW/FRstH7ESDHDDRga4z3V+ElUQHKpFDXWyBW5A==} + '@aws-sdk/util-locate-window@3.953.0': + resolution: {integrity: sha512-mPxK+I1LcrgC/RSa3G5AMAn8eN2Ay0VOgw8lSRmV1jCtO+iYvNeCqOdxoJUjOW6I5BA4niIRWqVORuRP07776Q==} engines: {node: '>=18.0.0'} - '@aws-sdk/util-user-agent-browser@3.840.0': - resolution: {integrity: sha512-JdyZM3EhhL4PqwFpttZu1afDpPJCCc3eyZOLi+srpX11LsGj6sThf47TYQN75HT1CarZ7cCdQHGzP2uy3/xHfQ==} + '@aws-sdk/util-user-agent-browser@3.953.0': + resolution: {integrity: sha512-UF5NeqYesWuFao+u7LJvpV1SJCaLml5BtFZKUdTnNNMeN6jvV+dW/eQoFGpXF94RCqguX0XESmRuRRPQp+/rzQ==} - '@aws-sdk/util-user-agent-node@3.848.0': - resolution: {integrity: sha512-Zz1ft9NiLqbzNj/M0jVNxaoxI2F4tGXN0ZbZIj+KJ+PbJo+w5+Jo6d0UDAtbj3AEd79pjcCaP4OA9NTVzItUdw==} + '@aws-sdk/util-user-agent-node@3.954.0': + resolution: {integrity: sha512-fB5S5VOu7OFkeNzcblQlez4AjO5hgDFaa7phYt7716YWisY3RjAaQPlxgv+G3GltHHDJIfzEC5aRxdf62B9zMg==} engines: {node: '>=18.0.0'} peerDependencies: aws-crt: '>=1.0.0' @@ -354,24 +354,28 @@ packages: '@aws-sdk/util-utf8-browser@3.259.0': resolution: {integrity: sha512-UvFa/vR+e19XookZF8RzFZBrw2EUkQWxiBW0yYQAhvk3C+QVGl0H3ouca8LDBlBfQKXwmW3huo/59H8rwb1wJw==} - '@aws-sdk/xml-builder@3.821.0': - resolution: {integrity: sha512-DIIotRnefVL6DiaHtO6/21DhJ4JZnnIwdNbpwiAhdt/AVbttcE4yw925gsjur0OGv5BTYXQXU3YnANBYnZjuQA==} + '@aws-sdk/xml-builder@3.953.0': + resolution: {integrity: sha512-Zmrj21jQ2OeOJGr9spPiN00aQvXa/WUqRXcTVENhrMt+OFoSOfDFpYhUj9NQ09QmQ8KMWFoWuWW6iKurNqLvAA==} + engines: {node: '>=18.0.0'} + + '@aws/lambda-invoke-store@0.2.2': + resolution: {integrity: sha512-C0NBLsIqzDIae8HFw9YIrIBsbc0xTiOtt7fAukGPnqQ/+zZNaq+4jhuccltK0QuWHBnNm/a6kLIRA6GFiM10eg==} engines: {node: '>=18.0.0'} '@babel/code-frame@7.27.1': resolution: {integrity: sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==} engines: {node: '>=6.9.0'} - '@babel/compat-data@7.28.0': - resolution: {integrity: sha512-60X7qkglvrap8mn1lh2ebxXdZYtUcpd7gsmy9kLaBJ4i/WdY8PqTSdxyA8qraikqKQK5C1KRBKXqznrVapyNaw==} + '@babel/compat-data@7.28.5': + resolution: {integrity: sha512-6uFXyCayocRbqhZOB+6XcuZbkMNimwfVGFji8CTZnCzOHVGvDqzvitu1re2AU5LROliz7eQPhB8CpAMvnx9EjA==} engines: {node: '>=6.9.0'} - '@babel/core@7.28.0': - resolution: {integrity: sha512-UlLAnTPrFdNGoFtbSXwcGFQBtQZJCNjaN6hQNP3UPvuNXT1i82N26KL3dZeIpNalWywr9IuQuncaAfUaS1g6sQ==} + '@babel/core@7.28.5': + resolution: {integrity: sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==} engines: {node: '>=6.9.0'} - '@babel/generator@7.28.0': - resolution: {integrity: sha512-lJjzvrbEeWrhB4P3QBsH7tey117PjLZnDbLiQEKjQ/fNJTjuq4HSqgFA+UNSwZT8D7dxxbnuSBMsa1lrWzKlQg==} + '@babel/generator@7.28.5': + resolution: {integrity: sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ==} engines: {node: '>=6.9.0'} '@babel/helper-compilation-targets@7.27.2': @@ -386,8 +390,8 @@ packages: resolution: {integrity: sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==} engines: {node: '>=6.9.0'} - '@babel/helper-module-transforms@7.27.3': - resolution: {integrity: sha512-dSOvYwvyLsWBeIRyOeHXp5vPj5l1I011r52FM1+r1jCERv+aFXYk4whgQccYEGYxK2H3ZAIA8nuPkQ0HaUo3qg==} + '@babel/helper-module-transforms@7.28.3': + resolution: {integrity: sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 @@ -400,20 +404,20 @@ packages: resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} engines: {node: '>=6.9.0'} - '@babel/helper-validator-identifier@7.27.1': - resolution: {integrity: sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==} + '@babel/helper-validator-identifier@7.28.5': + resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==} engines: {node: '>=6.9.0'} '@babel/helper-validator-option@7.27.1': resolution: {integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==} engines: {node: '>=6.9.0'} - '@babel/helpers@7.28.2': - resolution: {integrity: sha512-/V9771t+EgXz62aCcyofnQhGM8DQACbRhvzKFsXKC9QM+5MadF8ZmIm0crDMaz3+o0h0zXfJnd4EhbYbxsrcFw==} + '@babel/helpers@7.28.4': + resolution: {integrity: sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==} engines: {node: '>=6.9.0'} - '@babel/parser@7.28.0': - resolution: {integrity: sha512-jVZGvOxOuNSsuQuLRTh13nU0AogFlw32w/MT+LV6D3sP5WdbW61E77RnkbaO2dUvmPAYrBDJXGn5gGS6tH4j8g==} + '@babel/parser@7.28.5': + resolution: {integrity: sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==} engines: {node: '>=6.0.0'} hasBin: true @@ -429,33 +433,31 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/runtime@7.28.2': - resolution: {integrity: sha512-KHp2IflsnGywDjBWDkR9iEqiWSpc8GIi0lgTT3mOElT0PP1tG26P4tmFI2YvAdzgq9RGyoHZQEIEdZy6Ec5xCA==} + '@babel/runtime@7.28.4': + resolution: {integrity: sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==} engines: {node: '>=6.9.0'} '@babel/template@7.27.2': resolution: {integrity: sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==} engines: {node: '>=6.9.0'} - '@babel/traverse@7.28.0': - resolution: {integrity: sha512-mGe7UK5wWyh0bKRfupsUchrQGqvDbZDbKJw+kcRGSmdHVYrv+ltd0pnpDTVpiTqnaBru9iEvA8pz8W46v0Amwg==} + '@babel/traverse@7.28.5': + resolution: {integrity: sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ==} engines: {node: '>=6.9.0'} - '@babel/types@7.28.2': - resolution: {integrity: sha512-ruv7Ae4J5dUYULmeXw1gmb7rYRz57OWCPM57pHojnLq/3Z1CK2lNSLTCVjxVk1F/TZHwOZZrOWi0ur95BbLxNQ==} + '@babel/types@7.28.5': + resolution: {integrity: sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==} engines: {node: '>=6.9.0'} - '@base-org/account@1.0.2': - resolution: {integrity: sha512-jVRmMgGWQSqL4EiKoj5koXPNnTbdf4a5h+ljRU0hL8wzbGJ0hM/ZyFm/j5VNrFAX5dLLmBoa9Tf+RRwyfTvdvQ==} - peerDependencies: - wagmi: '*' - peerDependenciesMeta: - wagmi: - optional: true + '@base-org/account@2.4.0': + resolution: {integrity: sha512-A4Umpi8B9/pqR78D1Yoze4xHyQaujioVRqqO3d6xuDFw9VRtjg6tK3bPlwE0aW+nVH/ntllCpPa2PbI8Rnjcug==} '@bytecodealliance/preview2-shim@0.17.0': resolution: {integrity: sha512-JorcEwe4ud0x5BS/Ar2aQWOQoFzjq/7jcnxYXCvSMh0oRm0dQXzOA+hqLDBnOMks1LLBA7dmiLLsEBl09Yd6iQ==} + '@coinbase/cdp-sdk@1.40.1': + resolution: {integrity: sha512-VZxAUYvWbqM4gw/ZHyr9fKBlCAKdMbBQzJxpV9rMUNkdulHIrj0cko2Mw3dyVyw+gdT62jAVxzVkPuQTRnECLw==} + '@coinbase/wallet-sdk@3.9.3': resolution: {integrity: sha512-N/A2DRIf0Y3PHc1XAMvbBUu4zisna6qAdqABMZwBMNEfWrXpAwx16pZGkYCLGE+Rvv1edbcB2LYDRnACNcmCiw==} @@ -466,8 +468,8 @@ packages: resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} engines: {node: '>=12'} - '@ecies/ciphers@0.2.4': - resolution: {integrity: sha512-t+iX+Wf5nRKyNzk8dviW3Ikb/280+aEJAnw9YXvCp2tYGPSkMki+NRY+8aNLmVFv3eNtMdvViPNOPxS8SZNP+w==} + '@ecies/ciphers@0.2.5': + resolution: {integrity: sha512-GalEZH4JgOMHYYcYmVqnFirFsjZHeoGMDt9IxEnM9F7GRUUyUksJ7Ou53L83WHJq3RWKD3AcBpo0iQh0oMpf8A==} engines: {bun: '>=1', deno: '>=2', node: '>=16'} peerDependencies: '@noble/ciphers': ^1.0.0 @@ -735,6 +737,11 @@ packages: resolution: {integrity: sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==} engines: {node: '>=14'} + '@gemini-wallet/core@0.3.2': + resolution: {integrity: sha512-Z4aHi3ECFf5oWYWM3F1rW83GJfB9OvhBYPTmb5q+VyK3uvzvS48lwo+jwh2eOoCRWEuT/crpb9Vwp2QaS5JqgQ==} + peerDependencies: + viem: '>=2.0.0' + '@isaacs/balanced-match@4.0.1': resolution: {integrity: sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==} engines: {node: 20 || >=22} @@ -743,22 +750,21 @@ packages: resolution: {integrity: sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==} engines: {node: 20 || >=22} - '@isaacs/cliui@8.0.2': - resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} - engines: {node: '>=12'} + '@jridgewell/gen-mapping@0.3.13': + resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} - '@jridgewell/gen-mapping@0.3.12': - resolution: {integrity: sha512-OuLGC46TjB5BbN1dH8JULVVZY4WTdkF7tV9Ys6wLL1rubZnCMstOhNHueU5bLCrnRuDhKPDM4g6sw4Bel5Gzqg==} + '@jridgewell/remapping@2.3.5': + resolution: {integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==} '@jridgewell/resolve-uri@3.1.2': resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} engines: {node: '>=6.0.0'} - '@jridgewell/sourcemap-codec@1.5.4': - resolution: {integrity: sha512-VT2+G1VQs/9oz078bLrYbecdZKs912zQlkelYpuf+SXF+QvZDYJlbx/LSx+meSAwdDFnF8FVXW92AVjjkVmgFw==} + '@jridgewell/sourcemap-codec@1.5.5': + resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} - '@jridgewell/trace-mapping@0.3.29': - resolution: {integrity: sha512-uw6guiW/gcAGPDhLmd77/6lW8QLeiV5RUTsAX46Db6oLhGaVj4lhnPwb184s1bkc8kdVg/+h988dro8GRDpmYQ==} + '@jridgewell/trace-mapping@0.3.31': + resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} '@jridgewell/trace-mapping@0.3.9': resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} @@ -800,6 +806,10 @@ packages: resolution: {integrity: sha512-1ugFO1UoirU2esS3juZanS/Fo8C8XYocCuBpfZI5N7ECtoG+zu0wF+uWZASik6CkO6w9n/Iebt4iI4pT0vptpg==} engines: {node: '>=16.0.0'} + '@metamask/rpc-errors@7.0.2': + resolution: {integrity: sha512-YYYHsVYd46XwY2QZzpGeU4PSdRhHdxnzkB8piWGvJW2xbikZ3R+epAYEL4q/K8bh9JPTucsUdwRFnACor1aOYw==} + engines: {node: ^18.20 || ^20.17 || >=22} + '@metamask/safe-event-emitter@2.0.0': resolution: {integrity: sha512-/kSXhY692qiV1MXu6EeOZvg5nECLclxNXcKCxJ3cXQgYuRymRHpdx/t7JXfsK+JLjwA1e1c1/SBrlQYpusC29Q==} @@ -807,8 +817,11 @@ packages: resolution: {integrity: sha512-5yb2gMI1BDm0JybZezeoX/3XhPDOtTbcFvpTXM9kxsoZjPZFh4XciqRbpD6N86HYZqWDhEaKUDuOyR0sQHEjMA==} engines: {node: '>=12.0.0'} - '@metamask/sdk-communication-layer@0.32.0': - resolution: {integrity: sha512-dmj/KFjMi1fsdZGIOtbhxdg3amxhKL/A5BqSU4uh/SyDKPub/OT+x5pX8bGjpTL1WPWY/Q0OIlvFyX3VWnT06Q==} + '@metamask/sdk-analytics@0.0.5': + resolution: {integrity: sha512-fDah+keS1RjSUlC8GmYXvx6Y26s3Ax1U9hGpWb6GSY5SAdmTSIqp2CvYy6yW0WgLhnYhW+6xERuD0eVqV63QIQ==} + + '@metamask/sdk-communication-layer@0.33.1': + resolution: {integrity: sha512-0bI9hkysxcfbZ/lk0T2+aKVo1j0ynQVTuB3sJ5ssPWlz+Z3VwveCkP1O7EVu1tsVVCb0YV5WxK9zmURu2FIiaA==} peerDependencies: cross-fetch: ^4.0.0 eciesjs: '*' @@ -816,16 +829,20 @@ packages: readable-stream: ^3.6.2 socket.io-client: ^4.5.1 - '@metamask/sdk-install-modal-web@0.32.0': - resolution: {integrity: sha512-TFoktj0JgfWnQaL3yFkApqNwcaqJ+dw4xcnrJueMP3aXkSNev2Ido+WVNOg4IIMxnmOrfAC9t0UJ0u/dC9MjOQ==} + '@metamask/sdk-install-modal-web@0.32.1': + resolution: {integrity: sha512-MGmAo6qSjf1tuYXhCu2EZLftq+DSt5Z7fsIKr2P+lDgdTPWgLfZB1tJKzNcwKKOdf6q9Qmmxn7lJuI/gq5LrKw==} - '@metamask/sdk@0.32.0': - resolution: {integrity: sha512-WmGAlP1oBuD9hk4CsdlG1WJFuPtYJY+dnTHJMeCyohTWD2GgkcLMUUuvu9lO1/NVzuOoSi1OrnjbuY1O/1NZ1g==} + '@metamask/sdk@0.33.1': + resolution: {integrity: sha512-1mcOQVGr9rSrVcbKPNVzbZ8eCl1K0FATsYH3WJ/MH4WcZDWGECWrXJPNMZoEAkLxWiMe8jOQBumg2pmcDa9zpQ==} '@metamask/superstruct@3.2.1': resolution: {integrity: sha512-fLgJnDOXFmuVlB38rUN5SmU7hAFQcCjrg3Vrxz67KTY7YHFnSNEKvX4avmEBdOI0yTCxZjwMCFEqsC8k2+Wd3g==} engines: {node: '>=16.0.0'} + '@metamask/utils@11.9.0': + resolution: {integrity: sha512-wRnoSDD9jTWOge/+reFviJQANhS+uy8Y+OEwRanp5mQeGTjBFmK1r2cTOnei2UCZRV1crXHzeJVSFEoDDcgRbA==} + engines: {node: ^18.18 || ^20.14 || >=22} + '@metamask/utils@5.0.2': resolution: {integrity: sha512-yfmE79bRQtnMzarnKfX7AEJBwFTxvTyw3nBQlu/5rmGXrjAeAMltoGxO62TFurxrQAFMNa/fEjIHNvungZp0+g==} engines: {node: '>=14.0.0'} @@ -868,8 +885,8 @@ packages: resolution: {integrity: sha512-k11yZxZg+t+gWvBbIswW0yoJlu8cHOC7dhunwOzoWH/mXGBiYyR4YY6hAEK/3EUs4UpB8la1RfdRpeGsFHkWsA==} engines: {node: ^14.21.3 || >=16} - '@noble/curves@1.9.4': - resolution: {integrity: sha512-2bKONnuM53lINoDrSmK8qP8W271ms7pygDhZt4SiLOoLwBtoHqeCFi6RG42V8zd3mLHuJFhU/Bmaqo4nX0/kBw==} + '@noble/curves@1.9.7': + resolution: {integrity: sha512-gbKGcRUYIjA3/zCCNaWDciTMFI0dCkvou3TL8Zmy5Nc7sJ47a0jtOeZoTaMxkuqRo9cRhjOdZJXegxYE5FN/xw==} engines: {node: ^14.21.3 || >=16} '@noble/hashes@1.2.0': @@ -917,37 +934,37 @@ packages: resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} engines: {node: '>= 8'} - '@nomicfoundation/edr-darwin-arm64@0.11.3': - resolution: {integrity: sha512-w0tksbdtSxz9nuzHKsfx4c2mwaD0+l5qKL2R290QdnN9gi9AV62p9DHkOgfBdyg6/a6ZlnQqnISi7C9avk/6VA==} - engines: {node: '>= 18'} + '@nomicfoundation/edr-darwin-arm64@0.12.0-next.17': + resolution: {integrity: sha512-gI9/9ysLeAid0+VSTBeutxOJ0/Rrh00niGkGL9+4lR577igDY+v55XGN0oBMST49ILS0f12J6ZY90LG8sxPXmQ==} + engines: {node: '>= 20'} - '@nomicfoundation/edr-darwin-x64@0.11.3': - resolution: {integrity: sha512-QR4jAFrPbOcrO7O2z2ESg+eUeIZPe2bPIlQYgiJ04ltbSGW27FblOzdd5+S3RoOD/dsZGKAvvy6dadBEl0NgoA==} - engines: {node: '>= 18'} + '@nomicfoundation/edr-darwin-x64@0.12.0-next.17': + resolution: {integrity: sha512-zSZtwf584RkIyb8awELDt7ctskogH0p4pmqOC4vhykc8ODOv2XLuG1IgeE4WgYhWGZOufbCtgLfpJQrWqN6mmw==} + engines: {node: '>= 20'} - '@nomicfoundation/edr-linux-arm64-gnu@0.11.3': - resolution: {integrity: sha512-Ktjv89RZZiUmOFPspuSBVJ61mBZQ2+HuLmV67InNlh9TSUec/iDjGIwAn59dx0bF/LOSrM7qg5od3KKac4LJDQ==} - engines: {node: '>= 18'} + '@nomicfoundation/edr-linux-arm64-gnu@0.12.0-next.17': + resolution: {integrity: sha512-WjdfgV6B7gT5Q0NXtSIWyeK8gzaJX5HK6/jclYVHarWuEtS1LFgePYgMjK8rmm7IRTkM9RsE/PCuQEP1nrSsuA==} + engines: {node: '>= 20'} - '@nomicfoundation/edr-linux-arm64-musl@0.11.3': - resolution: {integrity: sha512-B3sLJx1rL2E9pfdD4mApiwOZSrX0a/KQSBWdlq1uAhFKqkl00yZaY4LejgZndsJAa4iKGQJlGnw4HCGeVt0+jA==} - engines: {node: '>= 18'} + '@nomicfoundation/edr-linux-arm64-musl@0.12.0-next.17': + resolution: {integrity: sha512-26rObKhhCDb9JkZbToyr7JVZo4tSVAFvzoJSJVmvpOl0LOHrfFsgVQu2n/8cNkwMAqulPubKL2E0jdnmEoZjWA==} + engines: {node: '>= 20'} - '@nomicfoundation/edr-linux-x64-gnu@0.11.3': - resolution: {integrity: sha512-D/4cFKDXH6UYyKPu6J3Y8TzW11UzeQI0+wS9QcJzjlrrfKj0ENW7g9VihD1O2FvXkdkTjcCZYb6ai8MMTCsaVw==} - engines: {node: '>= 18'} + '@nomicfoundation/edr-linux-x64-gnu@0.12.0-next.17': + resolution: {integrity: sha512-dPkHScIf/CU6h6k3k4HNUnQyQcVSLKanviHCAcs5HkviiJPxvVtOMMvtNBxoIvKZRxGFxf2eutcqQW4ZV1wRQQ==} + engines: {node: '>= 20'} - '@nomicfoundation/edr-linux-x64-musl@0.11.3': - resolution: {integrity: sha512-ergXuIb4nIvmf+TqyiDX5tsE49311DrBky6+jNLgsGDTBaN1GS3OFwFS8I6Ri/GGn6xOaT8sKu3q7/m+WdlFzg==} - engines: {node: '>= 18'} + '@nomicfoundation/edr-linux-x64-musl@0.12.0-next.17': + resolution: {integrity: sha512-5Ixe/bpyWZxC3AjIb8EomAOK44ajemBVx/lZRHZiWSBlwQpbSWriYAtKjKcReQQPwuYVjnFpAD2AtuCvseIjHw==} + engines: {node: '>= 20'} - '@nomicfoundation/edr-win32-x64-msvc@0.11.3': - resolution: {integrity: sha512-snvEf+WB3OV0wj2A7kQ+ZQqBquMcrozSLXcdnMdEl7Tmn+KDCbmFKBt3Tk0X3qOU4RKQpLPnTxdM07TJNVtung==} - engines: {node: '>= 18'} + '@nomicfoundation/edr-win32-x64-msvc@0.12.0-next.17': + resolution: {integrity: sha512-29YlvdgofSdXG1mUzIuH4kMXu1lmVc1hvYWUGWEH59L+LaakdhfJ/Wu5izeclKkrTh729Amtk/Hk1m29kFOO8A==} + engines: {node: '>= 20'} - '@nomicfoundation/edr@0.11.3': - resolution: {integrity: sha512-kqILRkAd455Sd6v8mfP3C1/0tCOynJWY+Ir+k/9Boocu2kObCrsFgG+ZWB7fSBVdd9cPVSNrnhWS+V+PEo637g==} - engines: {node: '>= 18'} + '@nomicfoundation/edr@0.12.0-next.17': + resolution: {integrity: sha512-Y8Kwqd5JpBmI/Kst6NJ/bZ81FeJea9J6WEwoSRTZnEvwfqW9dk9PI8zJs2UJpOACL1fXEPvN+doETbxT9EhwXA==} + engines: {node: '>= 20'} '@nomicfoundation/hardhat-chai-matchers@2.1.0': resolution: {integrity: sha512-GPhBNafh1fCnVD9Y7BYvoLnblnvfcq3j8YDbO1gGe/1nOFWzGmV7gFu5DkwFXF+IpYsS+t96o9qc/mPu3V3Vfw==} @@ -957,29 +974,29 @@ packages: ethers: ^6.14.0 hardhat: ^2.26.0 - '@nomicfoundation/hardhat-ethers@3.1.0': - resolution: {integrity: sha512-jx6fw3Ms7QBwFGT2MU6ICG292z0P81u6g54JjSV105+FbTZOF4FJqPksLfDybxkkOeq28eDxbqq7vpxRYyIlxA==} + '@nomicfoundation/hardhat-ethers@3.1.3': + resolution: {integrity: sha512-208JcDeVIl+7Wu3MhFUUtiA8TJ7r2Rn3Wr+lSx9PfsDTKkbsAsWPY6N6wQ4mtzDv0/pB9nIbJhkjoHe1EsgNsA==} peerDependencies: ethers: ^6.14.0 - hardhat: ^2.26.0 + hardhat: ^2.28.0 - '@nomicfoundation/hardhat-ignition-ethers@0.15.14': - resolution: {integrity: sha512-eq+5n+c1DW18/Xp8/QrHBBvG5QaKUxYF/byol4f1jrnZ1zAy0OrqEa/oaNFWchhpLalX7d7suk/2EL0PbT0CDQ==} + '@nomicfoundation/hardhat-ignition-ethers@0.15.17': + resolution: {integrity: sha512-io6Wrp1dUsJ94xEI3pw6qkPfhc9TFA+e6/+o16yQ8pvBTFMjgK5x8wIHKrrIHr9L3bkuTMtmDjyN4doqO2IqFQ==} peerDependencies: '@nomicfoundation/hardhat-ethers': ^3.1.0 - '@nomicfoundation/hardhat-ignition': ^0.15.13 - '@nomicfoundation/ignition-core': ^0.15.13 + '@nomicfoundation/hardhat-ignition': ^0.15.16 + '@nomicfoundation/ignition-core': ^0.15.15 ethers: ^6.14.0 hardhat: ^2.26.0 - '@nomicfoundation/hardhat-ignition@0.15.13': - resolution: {integrity: sha512-G4XGPWvxs9DJhZ6PE1wdvKjHkjErWbsETf4c7YxO6GUz+MJGlw+PtgbnCwhL3tQzSq3oD4MB0LGi+sK0polpUA==} + '@nomicfoundation/hardhat-ignition@0.15.16': + resolution: {integrity: sha512-T0JTnuib7QcpsWkHCPLT7Z6F483EjTdcdjb1e00jqS9zTGCPqinPB66LLtR/duDLdvgoiCVS6K8WxTQkA/xR1Q==} peerDependencies: '@nomicfoundation/hardhat-verify': ^2.1.0 hardhat: ^2.26.0 - '@nomicfoundation/hardhat-network-helpers@1.1.0': - resolution: {integrity: sha512-ZS+NulZuR99NUHt2VwcgZvgeD6Y63qrbORNRuKO+lTowJxNVsrJ0zbRx1j5De6G3dOno5pVGvuYSq2QVG0qCYg==} + '@nomicfoundation/hardhat-network-helpers@1.1.2': + resolution: {integrity: sha512-p7HaUVDbLj7ikFivQVNhnfMHUBgiHYMwQWvGn9AriieuopGOELIrwj2KjyM2a6z70zai5YKO264Vwz+3UFJZPQ==} peerDependencies: hardhat: ^2.26.0 @@ -1005,16 +1022,16 @@ packages: typechain: ^8.3.0 typescript: '>=4.5.0' - '@nomicfoundation/hardhat-verify@2.1.0': - resolution: {integrity: sha512-ogRbwlzphOR2MK/TxDG/uOftEhVJtD81eBU32YZ/maqQOHYOPKymu7BvF9syp7b2fxID5/loEIvxizjW1yBvvQ==} + '@nomicfoundation/hardhat-verify@2.1.3': + resolution: {integrity: sha512-danbGjPp2WBhLkJdQy9/ARM3WQIK+7vwzE0urNem1qZJjh9f54Kf5f1xuQv8DvqewUAkuPxVt/7q4Grz5WjqSg==} peerDependencies: hardhat: ^2.26.0 - '@nomicfoundation/ignition-core@0.15.13': - resolution: {integrity: sha512-Z4T1WIbw0EqdsN9RxtnHeQXBi7P/piAmCu8bZmReIdDo/2h06qgKWxjDoNfc9VBFZJ0+Dx79tkgQR3ewxMDcpA==} + '@nomicfoundation/ignition-core@0.15.15': + resolution: {integrity: sha512-JdKFxYknTfOYtFXMN6iFJ1vALJPednuB+9p9OwGIRdoI6HYSh4ZBzyRURgyXtHFyaJ/SF9lBpsYV9/1zEpcYwg==} - '@nomicfoundation/ignition-ui@0.15.12': - resolution: {integrity: sha512-nQl8tusvmt1ANoyIj5RQl9tVSEmG0FnNbtwnWbTim+F8JLm4YLHWS0yEgYUZC+BEO3oS0D8r6V8a02JGZJgqiQ==} + '@nomicfoundation/ignition-ui@0.15.13': + resolution: {integrity: sha512-HbTszdN1iDHCkUS9hLeooqnLEW2U45FaqFwFEYT8nIno2prFZhG+n68JEERjmfFCB5u0WgbuJwk3CgLoqtSL7Q==} '@nomicfoundation/slang@0.18.3': resolution: {integrity: sha512-YqAWgckqbHM0/CZxi9Nlf4hjk9wUNLC9ngWCWBiqMxPIZmzsVKYuChdlrfeBPQyvQQBoOhbx+7C1005kLVQDZQ==} @@ -1087,8 +1104,8 @@ packages: '@nomicfoundation/hardhat-verify': optional: true - '@openzeppelin/upgrades-core@1.44.1': - resolution: {integrity: sha512-yqvDj7eC7m5kCDgqCxVFgk9sVo9SXP/fQFaExPousNfAJJbX+20l4fKZp17aXbNTpo1g+2205s6cR9VhFFOCaQ==} + '@openzeppelin/upgrades-core@1.44.2': + resolution: {integrity: sha512-m6iorjyhPK9ow5/trNs7qsBC/SOzJCO51pvvAF2W9nOiZ1t0RtCd+rlRmRmlWTv4M33V0wzIUeamJ2BPbzgUXA==} hasBin: true '@paulmillr/qr@0.2.1': @@ -1098,12 +1115,8 @@ packages: '@peculiar/asn1-schema@2.6.0': resolution: {integrity: sha512-xNLYLBFTBKkCzEZIw842BxytQQATQv+lDTCEMZ8C196iJcJJMBUZxrhSTxLaohMyKK8QlzRNTRkUmanucnDSqg==} - '@pkgjs/parseargs@0.11.0': - resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} - engines: {node: '>=14'} - - '@rainbow-me/rainbowkit@2.2.8': - resolution: {integrity: sha512-EdNIK2cdAT6GJ9G11wx7nCVfjqBfxh7dx/1DhPYrB+yg+VFrII6cM1PiMFVC9evD4mqVHe9mmLAt3nvlwDdiPQ==} + '@rainbow-me/rainbowkit@2.2.10': + resolution: {integrity: sha512-8+E4die1A2ovN9t3lWxWnwqTGEdFqThXDQRj+E4eDKuUKyymYD+66Gzm6S9yfg8E95c6hmGlavGUfYPtl1EagA==} engines: {node: '>=12.4'} peerDependencies: '@tanstack/react-query': '>=5.0.0' @@ -1144,103 +1157,113 @@ packages: '@rolldown/pluginutils@1.0.0-beta.27': resolution: {integrity: sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA==} - '@rollup/rollup-android-arm-eabi@4.45.1': - resolution: {integrity: sha512-NEySIFvMY0ZQO+utJkgoMiCAjMrGvnbDLHvcmlA33UXJpYBCvlBEbMMtV837uCkS+plG2umfhn0T5mMAxGrlRA==} + '@rollup/rollup-android-arm-eabi@4.53.5': + resolution: {integrity: sha512-iDGS/h7D8t7tvZ1t6+WPK04KD0MwzLZrG0se1hzBjSi5fyxlsiggoJHwh18PCFNn7tG43OWb6pdZ6Y+rMlmyNQ==} cpu: [arm] os: [android] - '@rollup/rollup-android-arm64@4.45.1': - resolution: {integrity: sha512-ujQ+sMXJkg4LRJaYreaVx7Z/VMgBBd89wGS4qMrdtfUFZ+TSY5Rs9asgjitLwzeIbhwdEhyj29zhst3L1lKsRQ==} + '@rollup/rollup-android-arm64@4.53.5': + resolution: {integrity: sha512-wrSAViWvZHBMMlWk6EJhvg8/rjxzyEhEdgfMMjREHEq11EtJ6IP6yfcCH57YAEca2Oe3FNCE9DSTgU70EIGmVw==} cpu: [arm64] os: [android] - '@rollup/rollup-darwin-arm64@4.45.1': - resolution: {integrity: sha512-FSncqHvqTm3lC6Y13xncsdOYfxGSLnP+73k815EfNmpewPs+EyM49haPS105Rh4aF5mJKywk9X0ogzLXZzN9lA==} + '@rollup/rollup-darwin-arm64@4.53.5': + resolution: {integrity: sha512-S87zZPBmRO6u1YXQLwpveZm4JfPpAa6oHBX7/ghSiGH3rz/KDgAu1rKdGutV+WUI6tKDMbaBJomhnT30Y2t4VQ==} cpu: [arm64] os: [darwin] - '@rollup/rollup-darwin-x64@4.45.1': - resolution: {integrity: sha512-2/vVn/husP5XI7Fsf/RlhDaQJ7x9zjvC81anIVbr4b/f0xtSmXQTFcGIQ/B1cXIYM6h2nAhJkdMHTnD7OtQ9Og==} + '@rollup/rollup-darwin-x64@4.53.5': + resolution: {integrity: sha512-YTbnsAaHo6VrAczISxgpTva8EkfQus0VPEVJCEaboHtZRIb6h6j0BNxRBOwnDciFTZLDPW5r+ZBmhL/+YpTZgA==} cpu: [x64] os: [darwin] - '@rollup/rollup-freebsd-arm64@4.45.1': - resolution: {integrity: sha512-4g1kaDxQItZsrkVTdYQ0bxu4ZIQ32cotoQbmsAnW1jAE4XCMbcBPDirX5fyUzdhVCKgPcrwWuucI8yrVRBw2+g==} + '@rollup/rollup-freebsd-arm64@4.53.5': + resolution: {integrity: sha512-1T8eY2J8rKJWzaznV7zedfdhD1BqVs1iqILhmHDq/bqCUZsrMt+j8VCTHhP0vdfbHK3e1IQ7VYx3jlKqwlf+vw==} cpu: [arm64] os: [freebsd] - '@rollup/rollup-freebsd-x64@4.45.1': - resolution: {integrity: sha512-L/6JsfiL74i3uK1Ti2ZFSNsp5NMiM4/kbbGEcOCps99aZx3g8SJMO1/9Y0n/qKlWZfn6sScf98lEOUe2mBvW9A==} + '@rollup/rollup-freebsd-x64@4.53.5': + resolution: {integrity: sha512-sHTiuXyBJApxRn+VFMaw1U+Qsz4kcNlxQ742snICYPrY+DDL8/ZbaC4DVIB7vgZmp3jiDaKA0WpBdP0aqPJoBQ==} cpu: [x64] os: [freebsd] - '@rollup/rollup-linux-arm-gnueabihf@4.45.1': - resolution: {integrity: sha512-RkdOTu2jK7brlu+ZwjMIZfdV2sSYHK2qR08FUWcIoqJC2eywHbXr0L8T/pONFwkGukQqERDheaGTeedG+rra6Q==} + '@rollup/rollup-linux-arm-gnueabihf@4.53.5': + resolution: {integrity: sha512-dV3T9MyAf0w8zPVLVBptVlzaXxka6xg1f16VAQmjg+4KMSTWDvhimI/Y6mp8oHwNrmnmVl9XxJ/w/mO4uIQONA==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm-musleabihf@4.45.1': - resolution: {integrity: sha512-3kJ8pgfBt6CIIr1o+HQA7OZ9mp/zDk3ctekGl9qn/pRBgrRgfwiffaUmqioUGN9hv0OHv2gxmvdKOkARCtRb8Q==} + '@rollup/rollup-linux-arm-musleabihf@4.53.5': + resolution: {integrity: sha512-wIGYC1x/hyjP+KAu9+ewDI+fi5XSNiUi9Bvg6KGAh2TsNMA3tSEs+Sh6jJ/r4BV/bx/CyWu2ue9kDnIdRyafcQ==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm64-gnu@4.45.1': - resolution: {integrity: sha512-k3dOKCfIVixWjG7OXTCOmDfJj3vbdhN0QYEqB+OuGArOChek22hn7Uy5A/gTDNAcCy5v2YcXRJ/Qcnm4/ma1xw==} + '@rollup/rollup-linux-arm64-gnu@4.53.5': + resolution: {integrity: sha512-Y+qVA0D9d0y2FRNiG9oM3Hut/DgODZbU9I8pLLPwAsU0tUKZ49cyV1tzmB/qRbSzGvY8lpgGkJuMyuhH7Ma+Vg==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-arm64-musl@4.45.1': - resolution: {integrity: sha512-PmI1vxQetnM58ZmDFl9/Uk2lpBBby6B6rF4muJc65uZbxCs0EA7hhKCk2PKlmZKuyVSHAyIw3+/SiuMLxKxWog==} + '@rollup/rollup-linux-arm64-musl@4.53.5': + resolution: {integrity: sha512-juaC4bEgJsyFVfqhtGLz8mbopaWD+WeSOYr5E16y+1of6KQjc0BpwZLuxkClqY1i8sco+MdyoXPNiCkQou09+g==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-loongarch64-gnu@4.45.1': - resolution: {integrity: sha512-9UmI0VzGmNJ28ibHW2GpE2nF0PBQqsyiS4kcJ5vK+wuwGnV5RlqdczVocDSUfGX/Na7/XINRVoUgJyFIgipoRg==} + '@rollup/rollup-linux-loong64-gnu@4.53.5': + resolution: {integrity: sha512-rIEC0hZ17A42iXtHX+EPJVL/CakHo+tT7W0pbzdAGuWOt2jxDFh7A/lRhsNHBcqL4T36+UiAgwO8pbmn3dE8wA==} cpu: [loong64] os: [linux] - '@rollup/rollup-linux-powerpc64le-gnu@4.45.1': - resolution: {integrity: sha512-7nR2KY8oEOUTD3pBAxIBBbZr0U7U+R9HDTPNy+5nVVHDXI4ikYniH1oxQz9VoB5PbBU1CZuDGHkLJkd3zLMWsg==} + '@rollup/rollup-linux-ppc64-gnu@4.53.5': + resolution: {integrity: sha512-T7l409NhUE552RcAOcmJHj3xyZ2h7vMWzcwQI0hvn5tqHh3oSoclf9WgTl+0QqffWFG8MEVZZP1/OBglKZx52Q==} cpu: [ppc64] os: [linux] - '@rollup/rollup-linux-riscv64-gnu@4.45.1': - resolution: {integrity: sha512-nlcl3jgUultKROfZijKjRQLUu9Ma0PeNv/VFHkZiKbXTBQXhpytS8CIj5/NfBeECZtY2FJQubm6ltIxm/ftxpw==} + '@rollup/rollup-linux-riscv64-gnu@4.53.5': + resolution: {integrity: sha512-7OK5/GhxbnrMcxIFoYfhV/TkknarkYC1hqUw1wU2xUN3TVRLNT5FmBv4KkheSG2xZ6IEbRAhTooTV2+R5Tk0lQ==} cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-riscv64-musl@4.45.1': - resolution: {integrity: sha512-HJV65KLS51rW0VY6rvZkiieiBnurSzpzore1bMKAhunQiECPuxsROvyeaot/tcK3A3aGnI+qTHqisrpSgQrpgA==} + '@rollup/rollup-linux-riscv64-musl@4.53.5': + resolution: {integrity: sha512-GwuDBE/PsXaTa76lO5eLJTyr2k8QkPipAyOrs4V/KJufHCZBJ495VCGJol35grx9xryk4V+2zd3Ri+3v7NPh+w==} cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-s390x-gnu@4.45.1': - resolution: {integrity: sha512-NITBOCv3Qqc6hhwFt7jLV78VEO/il4YcBzoMGGNxznLgRQf43VQDae0aAzKiBeEPIxnDrACiMgbqjuihx08OOw==} + '@rollup/rollup-linux-s390x-gnu@4.53.5': + resolution: {integrity: sha512-IAE1Ziyr1qNfnmiQLHBURAD+eh/zH1pIeJjeShleII7Vj8kyEm2PF77o+lf3WTHDpNJcu4IXJxNO0Zluro8bOw==} cpu: [s390x] os: [linux] - '@rollup/rollup-linux-x64-gnu@4.45.1': - resolution: {integrity: sha512-+E/lYl6qu1zqgPEnTrs4WysQtvc/Sh4fC2nByfFExqgYrqkKWp1tWIbe+ELhixnenSpBbLXNi6vbEEJ8M7fiHw==} + '@rollup/rollup-linux-x64-gnu@4.53.5': + resolution: {integrity: sha512-Pg6E+oP7GvZ4XwgRJBuSXZjcqpIW3yCBhK4BcsANvb47qMvAbCjR6E+1a/U2WXz1JJxp9/4Dno3/iSJLcm5auw==} cpu: [x64] os: [linux] - '@rollup/rollup-linux-x64-musl@4.45.1': - resolution: {integrity: sha512-a6WIAp89p3kpNoYStITT9RbTbTnqarU7D8N8F2CV+4Cl9fwCOZraLVuVFvlpsW0SbIiYtEnhCZBPLoNdRkjQFw==} + '@rollup/rollup-linux-x64-musl@4.53.5': + resolution: {integrity: sha512-txGtluxDKTxaMDzUduGP0wdfng24y1rygUMnmlUJ88fzCCULCLn7oE5kb2+tRB+MWq1QDZT6ObT5RrR8HFRKqg==} cpu: [x64] os: [linux] - '@rollup/rollup-win32-arm64-msvc@4.45.1': - resolution: {integrity: sha512-T5Bi/NS3fQiJeYdGvRpTAP5P02kqSOpqiopwhj0uaXB6nzs5JVi2XMJb18JUSKhCOX8+UE1UKQufyD6Or48dJg==} + '@rollup/rollup-openharmony-arm64@4.53.5': + resolution: {integrity: sha512-3DFiLPnTxiOQV993fMc+KO8zXHTcIjgaInrqlG8zDp1TlhYl6WgrOHuJkJQ6M8zHEcntSJsUp1XFZSY8C1DYbg==} + cpu: [arm64] + os: [openharmony] + + '@rollup/rollup-win32-arm64-msvc@4.53.5': + resolution: {integrity: sha512-nggc/wPpNTgjGg75hu+Q/3i32R00Lq1B6N1DO7MCU340MRKL3WZJMjA9U4K4gzy3dkZPXm9E1Nc81FItBVGRlA==} cpu: [arm64] os: [win32] - '@rollup/rollup-win32-ia32-msvc@4.45.1': - resolution: {integrity: sha512-lxV2Pako3ujjuUe9jiU3/s7KSrDfH6IgTSQOnDWr9aJ92YsFd7EurmClK0ly/t8dzMkDtd04g60WX6yl0sGfdw==} + '@rollup/rollup-win32-ia32-msvc@4.53.5': + resolution: {integrity: sha512-U/54pTbdQpPLBdEzCT6NBCFAfSZMvmjr0twhnD9f4EIvlm9wy3jjQ38yQj1AGznrNO65EWQMgm/QUjuIVrYF9w==} cpu: [ia32] os: [win32] - '@rollup/rollup-win32-x64-msvc@4.45.1': - resolution: {integrity: sha512-M/fKi4sasCdM8i0aWJjCSFm2qEnYRR8AMLG2kxp6wD13+tMGA4Z1tVAuHkNRjud5SW2EM3naLuK35w9twvf6aA==} + '@rollup/rollup-win32-x64-gnu@4.53.5': + resolution: {integrity: sha512-2NqKgZSuLH9SXBBV2dWNRCZmocgSOx8OJSdpRaEcRlIfX8YrKxUT6z0F1NpvDVhOsl190UFTRh2F2WDWWCYp3A==} + cpu: [x64] + os: [win32] + + '@rollup/rollup-win32-x64-msvc@4.53.5': + resolution: {integrity: sha512-JRpZUhCfhZ4keB5v0fe02gQJy05GqboPOaxvjugW04RLSYYoB/9t2lx2u/tMs/Na/1NXfY8QYjgRljRpN+MjTQ==} cpu: [x64] os: [win32] @@ -1327,217 +1350,485 @@ packages: resolution: {integrity: sha512-zaYmoH0NWWtvnJjC9/CBseXMtKHm/tm40sz3YfJRxeQjyzRqNQPgivpd9R/oDJCYj999mzdW382p/qi2ypjLww==} engines: {node: '>=6'} - '@smithy/abort-controller@4.0.4': - resolution: {integrity: sha512-gJnEjZMvigPDQWHrW3oPrFhQtkrgqBkyjj3pCIdF3A5M6vsZODG93KNlfJprv6bp4245bdT32fsHK4kkH3KYDA==} + '@smithy/abort-controller@4.2.6': + resolution: {integrity: sha512-P7JD4J+wxHMpGxqIg6SHno2tPkZbBUBLbPpR5/T1DEUvw/mEaINBMaPFZNM7lA+ToSCZ36j6nMHa+5kej+fhGg==} engines: {node: '>=18.0.0'} - '@smithy/config-resolver@4.1.4': - resolution: {integrity: sha512-prmU+rDddxHOH0oNcwemL+SwnzcG65sBF2yXRO7aeXIn/xTlq2pX7JLVbkBnVLowHLg4/OL4+jBmv9hVrVGS+w==} + '@smithy/config-resolver@4.4.4': + resolution: {integrity: sha512-s3U5ChS21DwU54kMmZ0UJumoS5cg0+rGVZvN6f5Lp6EbAVi0ZyP+qDSHdewfmXKUgNK1j3z45JyzulkDukrjAA==} engines: {node: '>=18.0.0'} - '@smithy/core@3.7.2': - resolution: {integrity: sha512-JoLw59sT5Bm8SAjFCYZyuCGxK8y3vovmoVbZWLDPTH5XpPEIwpFd9m90jjVMwoypDuB/SdVgje5Y4T7w50lJaw==} + '@smithy/core@3.19.0': + resolution: {integrity: sha512-Y9oHXpBcXQgYHOcAEmxjkDilUbSTkgKjoHYed3WaYUH8jngq8lPWDBSpjHblJ9uOgBdy5mh3pzebrScDdYr29w==} engines: {node: '>=18.0.0'} - '@smithy/credential-provider-imds@4.0.6': - resolution: {integrity: sha512-hKMWcANhUiNbCJouYkZ9V3+/Qf9pteR1dnwgdyzR09R4ODEYx8BbUysHwRSyex4rZ9zapddZhLFTnT4ZijR4pw==} + '@smithy/credential-provider-imds@4.2.6': + resolution: {integrity: sha512-xBmawExyTzOjbhzkZwg+vVm/khg28kG+rj2sbGlULjFd1jI70sv/cbpaR0Ev4Yfd6CpDUDRMe64cTqR//wAOyA==} engines: {node: '>=18.0.0'} - '@smithy/eventstream-codec@4.0.4': - resolution: {integrity: sha512-7XoWfZqWb/QoR/rAU4VSi0mWnO2vu9/ltS6JZ5ZSZv0eovLVfDfu0/AX4ub33RsJTOth3TiFWSHS5YdztvFnig==} + '@smithy/eventstream-codec@4.2.6': + resolution: {integrity: sha512-OZfsI+YRG26XZik/jKMMg37acnBSbUiK/8nETW3uM3mLj+0tMmFXdHQw1e5WEd/IHN8BGOh3te91SNDe2o4RHg==} engines: {node: '>=18.0.0'} - '@smithy/eventstream-serde-browser@4.0.4': - resolution: {integrity: sha512-3fb/9SYaYqbpy/z/H3yIi0bYKyAa89y6xPmIqwr2vQiUT2St+avRt8UKwsWt9fEdEasc5d/V+QjrviRaX1JRFA==} + '@smithy/eventstream-serde-browser@4.2.6': + resolution: {integrity: sha512-6OiaAaEbLB6dEkRbQyNzFSJv5HDvly3Mc6q/qcPd2uS/g3szR8wAIkh7UndAFKfMypNSTuZ6eCBmgCLR5LacTg==} engines: {node: '>=18.0.0'} - '@smithy/eventstream-serde-config-resolver@4.1.2': - resolution: {integrity: sha512-JGtambizrWP50xHgbzZI04IWU7LdI0nh/wGbqH3sJesYToMi2j/DcoElqyOcqEIG/D4tNyxgRuaqBXWE3zOFhQ==} + '@smithy/eventstream-serde-config-resolver@4.3.6': + resolution: {integrity: sha512-xP5YXbOVRVN8A4pDnSUkEUsL9fYFU6VNhxo8tgr13YnMbf3Pn4xVr+hSyLVjS1Frfi1Uk03ET5Bwml4+0CeYEw==} engines: {node: '>=18.0.0'} - '@smithy/eventstream-serde-node@4.0.4': - resolution: {integrity: sha512-RD6UwNZ5zISpOWPuhVgRz60GkSIp0dy1fuZmj4RYmqLVRtejFqQ16WmfYDdoSoAjlp1LX+FnZo+/hkdmyyGZ1w==} + '@smithy/eventstream-serde-node@4.2.6': + resolution: {integrity: sha512-jhH7nJuaOpnTFcuZpWK9dqb6Ge2yGi1okTo0W6wkJrfwAm2vwmO74tF1v07JmrSyHBcKLQATEexclJw9K1Vj7w==} engines: {node: '>=18.0.0'} - '@smithy/eventstream-serde-universal@4.0.4': - resolution: {integrity: sha512-UeJpOmLGhq1SLox79QWw/0n2PFX+oPRE1ZyRMxPIaFEfCqWaqpB7BU9C8kpPOGEhLF7AwEqfFbtwNxGy4ReENA==} + '@smithy/eventstream-serde-universal@4.2.6': + resolution: {integrity: sha512-olIfZ230B64TvPD6b0tPvrEp2eB0FkyL3KvDlqF4RVmIc/kn3orzXnV6DTQdOOW5UU+M5zKY3/BU47X420/oPw==} engines: {node: '>=18.0.0'} - '@smithy/fetch-http-handler@5.1.0': - resolution: {integrity: sha512-mADw7MS0bYe2OGKkHYMaqarOXuDwRbO6ArD91XhHcl2ynjGCFF+hvqf0LyQcYxkA1zaWjefSkU7Ne9mqgApSgQ==} + '@smithy/fetch-http-handler@5.3.7': + resolution: {integrity: sha512-fcVap4QwqmzQwQK9QU3keeEpCzTjnP9NJ171vI7GnD7nbkAIcP9biZhDUx88uRH9BabSsQDS0unUps88uZvFIQ==} engines: {node: '>=18.0.0'} - '@smithy/hash-node@4.0.4': - resolution: {integrity: sha512-qnbTPUhCVnCgBp4z4BUJUhOEkVwxiEi1cyFM+Zj6o+aY8OFGxUQleKWq8ltgp3dujuhXojIvJWdoqpm6dVO3lQ==} + '@smithy/hash-node@4.2.6': + resolution: {integrity: sha512-k3Dy9VNR37wfMh2/1RHkFf/e0rMyN0pjY0FdyY6ItJRjENYyVPRMwad6ZR1S9HFm6tTuIOd9pqKBmtJ4VHxvxg==} engines: {node: '>=18.0.0'} - '@smithy/invalid-dependency@4.0.4': - resolution: {integrity: sha512-bNYMi7WKTJHu0gn26wg8OscncTt1t2b8KcsZxvOv56XA6cyXtOAAAaNP7+m45xfppXfOatXF3Sb1MNsLUgVLTw==} + '@smithy/invalid-dependency@4.2.6': + resolution: {integrity: sha512-E4t/V/q2T46RY21fpfznd1iSLTvCXKNKo4zJ1QuEFN4SE9gKfu2vb6bgq35LpufkQ+SETWIC7ZAf2GGvTlBaMQ==} engines: {node: '>=18.0.0'} '@smithy/is-array-buffer@2.2.0': resolution: {integrity: sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==} engines: {node: '>=14.0.0'} - '@smithy/is-array-buffer@4.0.0': - resolution: {integrity: sha512-saYhF8ZZNoJDTvJBEWgeBccCg+yvp1CX+ed12yORU3NilJScfc6gfch2oVb4QgxZrGUx3/ZJlb+c/dJbyupxlw==} + '@smithy/is-array-buffer@4.2.0': + resolution: {integrity: sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ==} engines: {node: '>=18.0.0'} - '@smithy/middleware-content-length@4.0.4': - resolution: {integrity: sha512-F7gDyfI2BB1Kc+4M6rpuOLne5LOcEknH1n6UQB69qv+HucXBR1rkzXBnQTB2q46sFy1PM/zuSJOB532yc8bg3w==} + '@smithy/middleware-content-length@4.2.6': + resolution: {integrity: sha512-0cjqjyfj+Gls30ntq45SsBtqF3dfJQCeqQPyGz58Pk8OgrAr5YiB7ZvDzjCA94p4r6DCI4qLm7FKobqBjf515w==} engines: {node: '>=18.0.0'} - '@smithy/middleware-endpoint@4.1.17': - resolution: {integrity: sha512-S3hSGLKmHG1m35p/MObQCBCdRsrpbPU8B129BVzRqRfDvQqPMQ14iO4LyRw+7LNizYc605COYAcjqgawqi+6jA==} + '@smithy/middleware-endpoint@4.4.0': + resolution: {integrity: sha512-M6qWfUNny6NFNy8amrCGIb9TfOMUkHVtg9bHtEFGRgfH7A7AtPpn/fcrToGPjVDK1ECuMVvqGQOXcZxmu9K+7A==} engines: {node: '>=18.0.0'} - '@smithy/middleware-retry@4.1.18': - resolution: {integrity: sha512-bYLZ4DkoxSsPxpdmeapvAKy7rM5+25gR7PGxq2iMiecmbrRGBHj9s75N74Ylg+aBiw9i5jIowC/cLU2NR0qH8w==} + '@smithy/middleware-retry@4.4.16': + resolution: {integrity: sha512-XPpNhNRzm3vhYm7YCsyw3AtmWggJbg1wNGAoqb7NBYr5XA5isMRv14jgbYyUV6IvbTBFZQdf2QpeW43LrRdStQ==} engines: {node: '>=18.0.0'} - '@smithy/middleware-serde@4.0.8': - resolution: {integrity: sha512-iSSl7HJoJaGyMIoNn2B7czghOVwJ9nD7TMvLhMWeSB5vt0TnEYyRRqPJu/TqW76WScaNvYYB8nRoiBHR9S1Ddw==} + '@smithy/middleware-serde@4.2.7': + resolution: {integrity: sha512-PFMVHVPgtFECeu4iZ+4SX6VOQT0+dIpm4jSPLLL6JLSkp9RohGqKBKD0cbiXdeIFS08Forp0UHI6kc0gIHenSA==} engines: {node: '>=18.0.0'} - '@smithy/middleware-stack@4.0.4': - resolution: {integrity: sha512-kagK5ggDrBUCCzI93ft6DjteNSfY8Ulr83UtySog/h09lTIOAJ/xUSObutanlPT0nhoHAkpmW9V5K8oPyLh+QA==} + '@smithy/middleware-stack@4.2.6': + resolution: {integrity: sha512-JSbALU3G+JS4kyBZPqnJ3hxIYwOVRV7r9GNQMS6j5VsQDo5+Es5nddLfr9TQlxZLNHPvKSh+XSB0OuWGfSWFcA==} engines: {node: '>=18.0.0'} - '@smithy/node-config-provider@4.1.3': - resolution: {integrity: sha512-HGHQr2s59qaU1lrVH6MbLlmOBxadtzTsoO4c+bF5asdgVik3I8o7JIOzoeqWc5MjVa+vD36/LWE0iXKpNqooRw==} + '@smithy/node-config-provider@4.3.6': + resolution: {integrity: sha512-fYEyL59Qe82Ha1p97YQTMEQPJYmBS+ux76foqluaTVWoG9Px5J53w6NvXZNE3wP7lIicLDF7Vj1Em18XTX7fsA==} engines: {node: '>=18.0.0'} - '@smithy/node-http-handler@4.1.0': - resolution: {integrity: sha512-vqfSiHz2v8b3TTTrdXi03vNz1KLYYS3bhHCDv36FYDqxT7jvTll1mMnCrkD+gOvgwybuunh/2VmvOMqwBegxEg==} + '@smithy/node-http-handler@4.4.6': + resolution: {integrity: sha512-Gsb9jf4ido5BhPfani4ggyrKDd3ZK+vTFWmUaZeFg5G3E5nhFmqiTzAIbHqmPs1sARuJawDiGMGR/nY+Gw6+aQ==} engines: {node: '>=18.0.0'} - '@smithy/property-provider@4.0.4': - resolution: {integrity: sha512-qHJ2sSgu4FqF4U/5UUp4DhXNmdTrgmoAai6oQiM+c5RZ/sbDwJ12qxB1M6FnP+Tn/ggkPZf9ccn4jqKSINaquw==} + '@smithy/property-provider@4.2.6': + resolution: {integrity: sha512-a/tGSLPtaia2krbRdwR4xbZKO8lU67DjMk/jfY4QKt4PRlKML+2tL/gmAuhNdFDioO6wOq0sXkfnddNFH9mNUA==} engines: {node: '>=18.0.0'} - '@smithy/protocol-http@5.1.2': - resolution: {integrity: sha512-rOG5cNLBXovxIrICSBm95dLqzfvxjEmuZx4KK3hWwPFHGdW3lxY0fZNXfv2zebfRO7sJZ5pKJYHScsqopeIWtQ==} + '@smithy/protocol-http@5.3.6': + resolution: {integrity: sha512-qLRZzP2+PqhE3OSwvY2jpBbP0WKTZ9opTsn+6IWYI0SKVpbG+imcfNxXPq9fj5XeaUTr7odpsNpK6dmoiM1gJQ==} engines: {node: '>=18.0.0'} - '@smithy/querystring-builder@4.0.4': - resolution: {integrity: sha512-SwREZcDnEYoh9tLNgMbpop+UTGq44Hl9tdj3rf+yeLcfH7+J8OXEBaMc2kDxtyRHu8BhSg9ADEx0gFHvpJgU8w==} + '@smithy/querystring-builder@4.2.6': + resolution: {integrity: sha512-MeM9fTAiD3HvoInK/aA8mgJaKQDvm8N0dKy6EiFaCfgpovQr4CaOkJC28XqlSRABM+sHdSQXbC8NZ0DShBMHqg==} engines: {node: '>=18.0.0'} - '@smithy/querystring-parser@4.0.4': - resolution: {integrity: sha512-6yZf53i/qB8gRHH/l2ZwUG5xgkPgQF15/KxH0DdXMDHjesA9MeZje/853ifkSY0x4m5S+dfDZ+c4x439PF0M2w==} + '@smithy/querystring-parser@4.2.6': + resolution: {integrity: sha512-YmWxl32SQRw/kIRccSOxzS/Ib8/b5/f9ex0r5PR40jRJg8X1wgM3KrR2In+8zvOGVhRSXgvyQpw9yOSlmfmSnA==} engines: {node: '>=18.0.0'} - '@smithy/service-error-classification@4.0.6': - resolution: {integrity: sha512-RRoTDL//7xi4tn5FrN2NzH17jbgmnKidUqd4KvquT0954/i6CXXkh1884jBiunq24g9cGtPBEXlU40W6EpNOOg==} + '@smithy/service-error-classification@4.2.6': + resolution: {integrity: sha512-Q73XBrzJlGTut2nf5RglSntHKgAG0+KiTJdO5QQblLfr4TdliGwIAha1iZIjwisc3rA5ulzqwwsYC6xrclxVQg==} engines: {node: '>=18.0.0'} - '@smithy/shared-ini-file-loader@4.0.4': - resolution: {integrity: sha512-63X0260LoFBjrHifPDs+nM9tV0VMkOTl4JRMYNuKh/f5PauSjowTfvF3LogfkWdcPoxsA9UjqEOgjeYIbhb7Nw==} + '@smithy/shared-ini-file-loader@4.4.1': + resolution: {integrity: sha512-tph+oQYPbpN6NamF030hx1gb5YN2Plog+GLaRHpoEDwp8+ZPG26rIJvStG9hkWzN2HBn3HcWg0sHeB0tmkYzqA==} engines: {node: '>=18.0.0'} - '@smithy/signature-v4@5.1.2': - resolution: {integrity: sha512-d3+U/VpX7a60seHziWnVZOHuEgJlclufjkS6zhXvxcJgkJq4UWdH5eOBLzHRMx6gXjsdT9h6lfpmLzbrdupHgQ==} + '@smithy/signature-v4@5.3.6': + resolution: {integrity: sha512-P1TXDHuQMadTMTOBv4oElZMURU4uyEhxhHfn+qOc2iofW9Rd4sZtBGx58Lzk112rIGVEYZT8eUMK4NftpewpRA==} engines: {node: '>=18.0.0'} - '@smithy/smithy-client@4.4.9': - resolution: {integrity: sha512-mbMg8mIUAWwMmb74LoYiArP04zWElPzDoA1jVOp3or0cjlDMgoS6WTC3QXK0Vxoc9I4zdrX0tq6qsOmaIoTWEQ==} + '@smithy/smithy-client@4.10.1': + resolution: {integrity: sha512-1ovWdxzYprhq+mWqiGZlt3kF69LJthuQcfY9BIyHx9MywTFKzFapluku1QXoaBB43GCsLDxNqS+1v30ure69AA==} engines: {node: '>=18.0.0'} - '@smithy/types@4.3.1': - resolution: {integrity: sha512-UqKOQBL2x6+HWl3P+3QqFD4ncKq0I8Nuz9QItGv5WuKuMHuuwlhvqcZCoXGfc+P1QmfJE7VieykoYYmrOoFJxA==} + '@smithy/types@4.10.0': + resolution: {integrity: sha512-K9mY7V/f3Ul+/Gz4LJANZ3vJ/yiBIwCyxe0sPT4vNJK63Srvd+Yk1IzP0t+nE7XFSpIGtzR71yljtnqpUTYFlQ==} engines: {node: '>=18.0.0'} - '@smithy/url-parser@4.0.4': - resolution: {integrity: sha512-eMkc144MuN7B0TDA4U2fKs+BqczVbk3W+qIvcoCY6D1JY3hnAdCuhCZODC+GAeaxj0p6Jroz4+XMUn3PCxQQeQ==} + '@smithy/url-parser@4.2.6': + resolution: {integrity: sha512-tVoyzJ2vXp4R3/aeV4EQjBDmCuWxRa8eo3KybL7Xv4wEM16nObYh7H1sNfcuLWHAAAzb0RVyxUz1S3sGj4X+Tg==} engines: {node: '>=18.0.0'} - '@smithy/util-base64@4.0.0': - resolution: {integrity: sha512-CvHfCmO2mchox9kjrtzoHkWHxjHZzaFojLc8quxXY7WAAMAg43nuxwv95tATVgQFNDwd4M9S1qFzj40Ul41Kmg==} + '@smithy/util-base64@4.3.0': + resolution: {integrity: sha512-GkXZ59JfyxsIwNTWFnjmFEI8kZpRNIBfxKjv09+nkAWPt/4aGaEWMM04m4sxgNVWkbt2MdSvE3KF/PfX4nFedQ==} engines: {node: '>=18.0.0'} - '@smithy/util-body-length-browser@4.0.0': - resolution: {integrity: sha512-sNi3DL0/k64/LO3A256M+m3CDdG6V7WKWHdAiBBMUN8S3hK3aMPhwnPik2A/a2ONN+9doY9UxaLfgqsIRg69QA==} + '@smithy/util-body-length-browser@4.2.0': + resolution: {integrity: sha512-Fkoh/I76szMKJnBXWPdFkQJl2r9SjPt3cMzLdOB6eJ4Pnpas8hVoWPYemX/peO0yrrvldgCUVJqOAjUrOLjbxg==} engines: {node: '>=18.0.0'} - '@smithy/util-body-length-node@4.0.0': - resolution: {integrity: sha512-q0iDP3VsZzqJyje8xJWEJCNIu3lktUGVoSy1KB0UWym2CL1siV3artm+u1DFYTLejpsrdGyCSWBdGNjJzfDPjg==} + '@smithy/util-body-length-node@4.2.1': + resolution: {integrity: sha512-h53dz/pISVrVrfxV1iqXlx5pRg3V2YWFcSQyPyXZRrZoZj4R4DeWRDo1a7dd3CPTcFi3kE+98tuNyD2axyZReA==} engines: {node: '>=18.0.0'} '@smithy/util-buffer-from@2.2.0': resolution: {integrity: sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==} engines: {node: '>=14.0.0'} - '@smithy/util-buffer-from@4.0.0': - resolution: {integrity: sha512-9TOQ7781sZvddgO8nxueKi3+yGvkY35kotA0Y6BWRajAv8jjmigQ1sBwz0UX47pQMYXJPahSKEKYFgt+rXdcug==} + '@smithy/util-buffer-from@4.2.0': + resolution: {integrity: sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew==} engines: {node: '>=18.0.0'} - '@smithy/util-config-provider@4.0.0': - resolution: {integrity: sha512-L1RBVzLyfE8OXH+1hsJ8p+acNUSirQnWQ6/EgpchV88G6zGBTDPdXiiExei6Z1wR2RxYvxY/XLw6AMNCCt8H3w==} + '@smithy/util-config-provider@4.2.0': + resolution: {integrity: sha512-YEjpl6XJ36FTKmD+kRJJWYvrHeUvm5ykaUS5xK+6oXffQPHeEM4/nXlZPe+Wu0lsgRUcNZiliYNh/y7q9c2y6Q==} engines: {node: '>=18.0.0'} - '@smithy/util-defaults-mode-browser@4.0.25': - resolution: {integrity: sha512-pxEWsxIsOPLfKNXvpgFHBGFC3pKYKUFhrud1kyooO9CJai6aaKDHfT10Mi5iiipPXN/JhKAu3qX9o75+X85OdQ==} + '@smithy/util-defaults-mode-browser@4.3.15': + resolution: {integrity: sha512-LiZQVAg/oO8kueX4c+oMls5njaD2cRLXRfcjlTYjhIqmwHnCwkQO5B3dMQH0c5PACILxGAQf6Mxsq7CjlDc76A==} engines: {node: '>=18.0.0'} - '@smithy/util-defaults-mode-node@4.0.25': - resolution: {integrity: sha512-+w4n4hKFayeCyELZLfsSQG5mCC3TwSkmRHv4+el5CzFU8ToQpYGhpV7mrRzqlwKkntlPilT1HJy1TVeEvEjWOQ==} + '@smithy/util-defaults-mode-node@4.2.18': + resolution: {integrity: sha512-Kw2J+KzYm9C9Z9nY6+W0tEnoZOofstVCMTshli9jhQbQCy64rueGfKzPfuFBnVUqZD9JobxTh2DzHmPkp/Va/Q==} engines: {node: '>=18.0.0'} - '@smithy/util-endpoints@3.0.6': - resolution: {integrity: sha512-YARl3tFL3WgPuLzljRUnrS2ngLiUtkwhQtj8PAL13XZSyUiNLQxwG3fBBq3QXFqGFUXepIN73pINp3y8c2nBmA==} + '@smithy/util-endpoints@3.2.6': + resolution: {integrity: sha512-v60VNM2+mPvgHCBXEfMCYrQ0RepP6u6xvbAkMenfe4Mi872CqNkJzgcnQL837e8NdeDxBgrWQRTluKq5Lqdhfg==} engines: {node: '>=18.0.0'} - '@smithy/util-hex-encoding@4.0.0': - resolution: {integrity: sha512-Yk5mLhHtfIgW2W2WQZWSg5kuMZCVbvhFmC7rV4IO2QqnZdbEFPmQnCcGMAX2z/8Qj3B9hYYNjZOhWym+RwhePw==} + '@smithy/util-hex-encoding@4.2.0': + resolution: {integrity: sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw==} engines: {node: '>=18.0.0'} - '@smithy/util-middleware@4.0.4': - resolution: {integrity: sha512-9MLKmkBmf4PRb0ONJikCbCwORACcil6gUWojwARCClT7RmLzF04hUR4WdRprIXal7XVyrddadYNfp2eF3nrvtQ==} + '@smithy/util-middleware@4.2.6': + resolution: {integrity: sha512-qrvXUkxBSAFomM3/OEMuDVwjh4wtqK8D2uDZPShzIqOylPst6gor2Cdp6+XrH4dyksAWq/bE2aSDYBTTnj0Rxg==} engines: {node: '>=18.0.0'} - '@smithy/util-retry@4.0.6': - resolution: {integrity: sha512-+YekoF2CaSMv6zKrA6iI/N9yva3Gzn4L6n35Luydweu5MMPYpiGZlWqehPHDHyNbnyaYlz/WJyYAZnC+loBDZg==} + '@smithy/util-retry@4.2.6': + resolution: {integrity: sha512-x7CeDQLPQ9cb6xN7fRJEjlP9NyGW/YeXWc4j/RUhg4I+H60F0PEeRc2c/z3rm9zmsdiMFzpV/rT+4UHW6KM1SA==} engines: {node: '>=18.0.0'} - '@smithy/util-stream@4.2.3': - resolution: {integrity: sha512-cQn412DWHHFNKrQfbHY8vSFI3nTROY1aIKji9N0tpp8gUABRilr7wdf8fqBbSlXresobM+tQFNk6I+0LXK/YZg==} + '@smithy/util-stream@4.5.7': + resolution: {integrity: sha512-Uuy4S5Aj4oF6k1z+i2OtIBJUns4mlg29Ph4S+CqjR+f4XXpSFVgTCYLzMszHJTicYDBxKFtwq2/QSEDSS5l02A==} engines: {node: '>=18.0.0'} - '@smithy/util-uri-escape@4.0.0': - resolution: {integrity: sha512-77yfbCbQMtgtTylO9itEAdpPXSog3ZxMe09AEhm0dU0NLTalV70ghDZFR+Nfi1C60jnJoh/Re4090/DuZh2Omg==} + '@smithy/util-uri-escape@4.2.0': + resolution: {integrity: sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA==} engines: {node: '>=18.0.0'} '@smithy/util-utf8@2.3.0': resolution: {integrity: sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==} engines: {node: '>=14.0.0'} - '@smithy/util-utf8@4.0.0': - resolution: {integrity: sha512-b+zebfKCfRdgNJDknHCob3O7FpeYQN6ZG6YLExMcasDHsCXlsXCEuiPZeLnJLpwa5dvPetGlnGCiMHuLwGvFow==} + '@smithy/util-utf8@4.2.0': + resolution: {integrity: sha512-zBPfuzoI8xyBtR2P6WQj63Rz8i3AmfAaJLuNG8dWsfvPe8lO4aCPYLn879mEgHndZH1zQ2oXmG8O1GGzzaoZiw==} + engines: {node: '>=18.0.0'} + + '@smithy/util-waiter@4.2.6': + resolution: {integrity: sha512-xU9HwUSik9UUCJmm530yvBy0AwlQFICveKmqvaaTukKkXEAhyiBdHtSrhPrH3rH+uz0ykyaE3LdgsX86C6mDCQ==} engines: {node: '>=18.0.0'} - '@smithy/util-waiter@4.0.6': - resolution: {integrity: sha512-slcr1wdRbX7NFphXZOxtxRNA7hXAAtJAXJDE/wdoMAos27SIquVCKiSqfB6/28YzQ8FCsB5NKkhdM5gMADbqxg==} + '@smithy/uuid@1.1.0': + resolution: {integrity: sha512-4aUIteuyxtBUhVdiQqcDhKFitwfd9hqoSDYY2KRXiWtgoWJ9Bmise+KfEPDiVHWeJepvF8xJO9/9+WDIciMFFw==} engines: {node: '>=18.0.0'} '@socket.io/component-emitter@3.1.2': resolution: {integrity: sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==} + '@solana-program/system@0.8.1': + resolution: {integrity: sha512-71U9Mzdpw8HQtfgfJSL5xKZbLMRnza2Llsfk7gGnmg2waqK+o8MMH4YNma8xXS1UmOBptXIiNvoZ3p7cmOVktg==} + peerDependencies: + '@solana/kit': ^3.0 + + '@solana-program/token@0.6.0': + resolution: {integrity: sha512-omkZh4Tt9rre4wzWHNOhOEHyenXQku3xyc/UrKvShexA/Qlhza67q7uRwmwEDUs4QqoDBidSZPooOmepnA/jig==} + peerDependencies: + '@solana/kit': ^3.0 + + '@solana/accounts@3.0.3': + resolution: {integrity: sha512-KqlePrlZaHXfu8YQTCxN204ZuVm9o68CCcUr6l27MG2cuRUtEM1Ta0iR8JFkRUAEfZJC4Cu0ZDjK/v49loXjZQ==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/addresses@3.0.3': + resolution: {integrity: sha512-AuMwKhJI89ANqiuJ/fawcwxNKkSeHH9CApZd2xelQQLS7X8uxAOovpcmEgiObQuiVP944s9ScGUT62Bdul9qYg==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/assertions@3.0.3': + resolution: {integrity: sha512-2qspxdbWp2y62dfCIlqeWQr4g+hE8FYSSwcaP6itwMwGRb8393yDGCJfI/znuzJh6m/XVWhMHIgFgsBwnevCmg==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/buffer-layout@4.0.1': + resolution: {integrity: sha512-E1ImOIAD1tBZFRdjeM4/pzTiTApC0AOBGwyAMS4fwIodCWArzJ3DWdoh8cKxeFM2fElkxBh2Aqts1BPC373rHA==} + engines: {node: '>=5.10'} + + '@solana/codecs-core@2.3.0': + resolution: {integrity: sha512-oG+VZzN6YhBHIoSKgS5ESM9VIGzhWjEHEGNPSibiDTxFhsFWxNaz8LbMDPjBUE69r9wmdGLkrQ+wVPbnJcZPvw==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/codecs-core@3.0.3': + resolution: {integrity: sha512-emKykJ3h1DmnDOY29Uv9eJXP8E/FHzvlUBJ6te+5EbKdFjj7vdlKYPfDxOI6iGdXTY+YC/ELtbNBh6QwF2uEDQ==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/codecs-data-structures@3.0.3': + resolution: {integrity: sha512-R15cLp8riJvToXziW8lP6AMSwsztGhEnwgyGmll32Mo0Yjq+hduW2/fJrA/TJs6tA/OgTzMQjlxgk009EqZHCw==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/codecs-numbers@2.3.0': + resolution: {integrity: sha512-jFvvwKJKffvG7Iz9dmN51OGB7JBcy2CJ6Xf3NqD/VP90xak66m/Lg48T01u5IQ/hc15mChVHiBm+HHuOFDUrQg==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/codecs-numbers@3.0.3': + resolution: {integrity: sha512-pfXkH9J0glrM8qj6389GAn30+cJOxzXLR2FsPOHCUMXrqLhGjMMZAWhsQkpOQ37SGc/7EiQsT/gmyGC7gxHqJQ==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/codecs-strings@3.0.3': + resolution: {integrity: sha512-VHBXnnTVtcQ1j+7Vrz+qSYo38no+jiHRdGnhFspRXEHNJbllzwKqgBE7YN3qoIXH+MKxgJUcwO5KHmdzf8Wn2A==} + engines: {node: '>=20.18.0'} + peerDependencies: + fastestsmallesttextencoderdecoder: ^1.0.22 + typescript: '>=5.3.3' + + '@solana/codecs@3.0.3': + resolution: {integrity: sha512-GOHwTlIQsCoJx9Ryr6cEf0FHKAQ7pY4aO4xgncAftrv0lveTQ1rPP2inQ1QT0gJllsIa8nwbfXAADs9nNJxQDA==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/errors@2.3.0': + resolution: {integrity: sha512-66RI9MAbwYV0UtP7kGcTBVLxJgUxoZGm8Fbc0ah+lGiAw17Gugco6+9GrJCV83VyF2mDWyYnYM9qdI3yjgpnaQ==} + engines: {node: '>=20.18.0'} + hasBin: true + peerDependencies: + typescript: '>=5.3.3' + + '@solana/errors@3.0.3': + resolution: {integrity: sha512-1l84xJlHNva6io62PcYfUamwWlc0eM95nHgCrKX0g0cLoC6D6QHYPCEbEVkR+C5UtP9JDgyQM8MFiv+Ei5tO9Q==} + engines: {node: '>=20.18.0'} + hasBin: true + peerDependencies: + typescript: '>=5.3.3' + + '@solana/fast-stable-stringify@3.0.3': + resolution: {integrity: sha512-ED0pxB6lSEYvg+vOd5hcuQrgzEDnOrURFgp1ZOY+lQhJkQU6xo+P829NcJZQVP1rdU2/YQPAKJKEseyfe9VMIw==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/functional@3.0.3': + resolution: {integrity: sha512-2qX1kKANn8995vOOh5S9AmF4ItGZcfbny0w28Eqy8AFh+GMnSDN4gqpmV2LvxBI9HibXZptGH3RVOMk82h1Mpw==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/instruction-plans@3.0.3': + resolution: {integrity: sha512-eqoaPtWtmLTTpdvbt4BZF5H6FIlJtXi9H7qLOM1dLYonkOX2Ncezx5NDCZ9tMb2qxVMF4IocYsQnNSnMfjQF1w==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/instructions@3.0.3': + resolution: {integrity: sha512-4csIi8YUDb5j/J+gDzmYtOvq7ZWLbCxj4t0xKn+fPrBk/FD2pK29KVT3Fu7j4Lh1/ojunQUP9X4NHwUexY3PnA==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/keys@3.0.3': + resolution: {integrity: sha512-tp8oK9tMadtSIc4vF4aXXWkPd4oU5XPW8nf28NgrGDWGt25fUHIydKjkf2hPtMt9i1WfRyQZ33B5P3dnsNqcPQ==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/kit@3.0.3': + resolution: {integrity: sha512-CEEhCDmkvztd1zbgADsEQhmj9GyWOOGeW1hZD+gtwbBSF5YN1uofS/pex5MIh/VIqKRj+A2UnYWI1V+9+q/lyQ==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/nominal-types@3.0.3': + resolution: {integrity: sha512-aZavCiexeUAoMHRQg4s1AHkH3wscbOb70diyfjhwZVgFz1uUsFez7csPp9tNFkNolnadVb2gky7yBk3IImQJ6A==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/options@3.0.3': + resolution: {integrity: sha512-jarsmnQ63RN0JPC5j9sgUat07NrL9PC71XU7pUItd6LOHtu4+wJMio3l5mT0DHVfkfbFLL6iI6+QmXSVhTNF3g==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/programs@3.0.3': + resolution: {integrity: sha512-JZlVE3/AeSNDuH3aEzCZoDu8GTXkMpGXxf93zXLzbxfxhiQ/kHrReN4XE/JWZ/uGWbaFZGR5B3UtdN2QsoZL7w==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/promises@3.0.3': + resolution: {integrity: sha512-K+UflGBVxj30XQMHTylHHZJdKH5QG3oj5k2s42GrZ/Wbu72oapVJySMBgpK45+p90t8/LEqV6rRPyTXlet9J+Q==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/rpc-api@3.0.3': + resolution: {integrity: sha512-Yym9/Ama62OY69rAZgbOCAy1QlqaWAyb0VlqFuwSaZV1pkFCCFSwWEJEsiN1n8pb2ZP+RtwNvmYixvWizx9yvA==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/rpc-parsed-types@3.0.3': + resolution: {integrity: sha512-/koM05IM2fU91kYDQxXil3VBNlOfcP+gXE0js1sdGz8KonGuLsF61CiKB5xt6u1KEXhRyDdXYLjf63JarL4Ozg==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/rpc-spec-types@3.0.3': + resolution: {integrity: sha512-A6Jt8SRRetnN3CeGAvGJxigA9zYRslGgWcSjueAZGvPX+MesFxEUjSWZCfl+FogVFvwkqfkgQZQbPAGZQFJQ6Q==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/rpc-spec@3.0.3': + resolution: {integrity: sha512-MZn5/8BebB6MQ4Gstw6zyfWsFAZYAyLzMK+AUf/rSfT8tPmWiJ/mcxnxqOXvFup/l6D67U8pyGpIoFqwCeZqqA==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/rpc-subscriptions-api@3.0.3': + resolution: {integrity: sha512-MGgVK3PUS15qsjuhimpzGZrKD/CTTvS0mAlQ0Jw84zsr1RJVdQJK/F0igu07BVd172eTZL8d90NoAQ3dahW5pA==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/rpc-subscriptions-channel-websocket@3.0.3': + resolution: {integrity: sha512-zUzUlb8Cwnw+SHlsLrSqyBRtOJKGc+FvSNJo/vWAkLShoV0wUDMPv7VvhTngJx3B/3ANfrOZ4i08i9QfYPAvpQ==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + ws: ^8.18.0 + + '@solana/rpc-subscriptions-spec@3.0.3': + resolution: {integrity: sha512-9KpQ32OBJWS85mn6q3gkM0AjQe1LKYlMU7gpJRrla/lvXxNLhI95tz5K6StctpUreVmRWTVkNamHE69uUQyY8A==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/rpc-subscriptions@3.0.3': + resolution: {integrity: sha512-LRvz6NaqvtsYFd32KwZ+rwYQ9XCs+DWjV8BvBLsJpt9/NWSuHf/7Sy/vvP6qtKxut692H/TMvHnC4iulg0WmiQ==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/rpc-transformers@3.0.3': + resolution: {integrity: sha512-lzdaZM/dG3s19Tsk4mkJA5JBoS1eX9DnD7z62gkDwrwJDkDBzkAJT9aLcsYFfTmwTfIp6uU2UPgGYc97i1wezw==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/rpc-transport-http@3.0.3': + resolution: {integrity: sha512-bIXFwr2LR5A97Z46dI661MJPbHnPfcShBjFzOS/8Rnr8P4ho3j/9EUtjDrsqoxGJT3SLWj5OlyXAlaDAvVTOUQ==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/rpc-types@3.0.3': + resolution: {integrity: sha512-petWQ5xSny9UfmC3Qp2owyhNU0w9SyBww4+v7tSVyXMcCC9v6j/XsqTeimH1S0qQUllnv0/FY83ohFaxofmZ6Q==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/rpc@3.0.3': + resolution: {integrity: sha512-3oukAaLK78GegkKcm6iNmRnO4mFeNz+BMvA8T56oizoBNKiRVEq/6DFzVX/LkmZ+wvD601pAB3uCdrTPcC0YKQ==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/signers@3.0.3': + resolution: {integrity: sha512-UwCd/uPYTZiwd283JKVyOWLLN5sIgMBqGDyUmNU3vo9hcmXKv5ZGm/9TvwMY2z35sXWuIOcj7etxJ8OoWc/ObQ==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/subscribable@3.0.3': + resolution: {integrity: sha512-FJ27LKGHLQ5GGttPvTOLQDLrrOZEgvaJhB7yYaHAhPk25+p+erBaQpjePhfkMyUbL1FQbxn1SUJmS6jUuaPjlQ==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/sysvars@3.0.3': + resolution: {integrity: sha512-GnHew+QeKCs2f9ow+20swEJMH4mDfJA/QhtPgOPTYQx/z69J4IieYJ7fZenSHnA//lJ45fVdNdmy1trypvPLBQ==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/transaction-confirmation@3.0.3': + resolution: {integrity: sha512-dXx0OLtR95LMuARgi2dDQlL1QYmk56DOou5q9wKymmeV3JTvfDExeWXnOgjRBBq/dEfj4ugN1aZuTaS18UirFw==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/transaction-messages@3.0.3': + resolution: {integrity: sha512-s+6NWRnBhnnjFWV4x2tzBzoWa6e5LiIxIvJlWwVQBFkc8fMGY04w7jkFh0PM08t/QFKeXBEWkyBDa/TFYdkWug==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/transactions@3.0.3': + resolution: {integrity: sha512-iMX+n9j4ON7H1nKlWEbMqMOpKYC6yVGxKKmWHT1KdLRG7v+03I4DnDeFoI+Zmw56FA+7Bbne8jwwX60Q1vk/MQ==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/web3.js@1.98.4': + resolution: {integrity: sha512-vv9lfnvjUsRiq//+j5pBdXig0IQdtzA0BRZ3bXEP4KaIyF1CcaydWqgyzQgfZMNIsWNWmG+AUHwPy4AHOD6gpw==} + '@solidity-parser/parser@0.14.5': resolution: {integrity: sha512-6dKnHZn7fg/iQATVEzqyUOyEidbn05q7YA2mQ9hC0MMXhhV3/JrsxmFSYZAcr7j1yUP700LLhTruvJ3MiQmjJg==} '@solidity-parser/parser@0.20.2': resolution: {integrity: sha512-rbu0bzwNvMcwAjH86hiEAcOeRI2EeK8zCkHDrFykh/Al8mvJeFmjy3UrE7GYQjNwOgbGUUtCn5/k8CB8zIu7QA==} - '@tanstack/query-core@5.83.0': - resolution: {integrity: sha512-0M8dA+amXUkyz5cVUm/B+zSk3xkQAcuXuz5/Q/LveT4ots2rBpPTZOzd7yJa2Utsf8D2Upl5KyjhHRY+9lB/XA==} + '@swc/helpers@0.5.17': + resolution: {integrity: sha512-5IKx/Y13RsYd+sauPb2x+U/xZikHjolzfuDgTAl/Tdf3Q8rslRvC19NKDLgAJQ6wsqADk10ntlv08nPFw/gO/A==} + + '@tanstack/query-core@5.90.12': + resolution: {integrity: sha512-T1/8t5DhV/SisWjDnaiU2drl6ySvsHj1bHBCWNXd+/T+Hh1cf6JodyEYMd5sgwm+b/mETT4EV3H+zCVczCU5hg==} - '@tanstack/react-query@5.83.0': - resolution: {integrity: sha512-/XGYhZ3foc5H0VM2jLSD/NyBRIOK4q9kfeml4+0x2DlL6xVuAcVEW+hTlTapAmejObg0i3eNqhkr2dT+eciwoQ==} + '@tanstack/react-query@5.90.12': + resolution: {integrity: sha512-graRZspg7EoEaw0a8faiUASCyJrqjKPdqJ9EwuDRUF9mEYJ1YPczI9H+/agJ0mOJkPCJDk0lsz5QTrLZ/jQ2rg==} peerDependencies: react: ^18 || ^19 - '@tsconfig/node10@1.0.11': - resolution: {integrity: sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==} + '@tsconfig/node10@1.0.12': + resolution: {integrity: sha512-UCYBaeFvM11aU2y3YPZ//O5Rhj+xKyzy7mvcIoAjASbigy8mHMryP5cK7dgjlz2hWxh1g5pLw084E0a/wlUSFQ==} '@tsconfig/node12@1.0.11': resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==} @@ -1572,8 +1863,8 @@ packages: '@types/babel__template@7.4.4': resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==} - '@types/babel__traverse@7.20.7': - resolution: {integrity: sha512-dkO5fhS7+/oos4ciWxyEyjWe48zmG6wbCheo/G2ZnHx4fs3EU6YC6UM8rk56gAjNJ9P3MTH2jo5jb92/K6wbng==} + '@types/babel__traverse@7.28.0': + resolution: {integrity: sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==} '@types/bn.js@5.2.0': resolution: {integrity: sha512-DLbJ1BPqxvQhIGbeu8VbUC1DiAiahHtAYvA0ZEAa4P31F7IaArc8z3C3BRQdWX4mtLQuABG4yzp76ZrS02Ui1Q==} @@ -1584,12 +1875,15 @@ packages: '@types/chai@4.3.20': resolution: {integrity: sha512-/pC9HAB5I/xMlc5FP77qjCnI16ChlJfW0tGa0IUcFn38VJrTV6DeZ60NU5KZBtaOZqjdpwTWohz5HU1RrhiYxQ==} - '@types/chai@5.2.2': - resolution: {integrity: sha512-8kB30R7Hwqf40JPiKhVzodJs2Qc1ZJ5zuT3uzw5Hq/dhNCl3G3l83jfpdI1e20BP348+fV7VIL/+FxaXkqBmWg==} + '@types/chai@5.2.3': + resolution: {integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==} '@types/concat-stream@1.6.1': resolution: {integrity: sha512-eHE4cQPoj6ngxBZMvVf6Hw7Mh4jMW4U9lpGmS5GBPB9RYxlFg+CHaVN7ErNY4W9XfLIEn20b4VDYaIrbq0q4uA==} + '@types/connect@3.4.38': + resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==} + '@types/debug@4.1.12': resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==} @@ -1605,6 +1899,9 @@ packages: '@types/glob@7.2.0': resolution: {integrity: sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==} + '@types/lodash@4.17.21': + resolution: {integrity: sha512-FOvQ0YPD5NOfPgMzJihoT+Za5pdkDJWcbpuj1DjaKZIr/gxodQjY/uWEFlTNqW2ugXHUiL8lRQgw63dzKHZdeQ==} + '@types/minimatch@6.0.0': resolution: {integrity: sha512-zmPitbQ8+6zNutpwgcQuLcsEpn/Cj54Kbn7L5pX0Os5kdWplB7xPgEh/g+SWOB/qmows2gpuCaPyduq8ZZRnxA==} deprecated: This is a stub types definition. minimatch provides its own type definitions, so you do not need this installed. @@ -1618,8 +1915,11 @@ packages: '@types/node@10.17.60': resolution: {integrity: sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==} - '@types/node@20.19.9': - resolution: {integrity: sha512-cuVNgarYWZqxRJDQHEB58GEONhOK79QVR/qYx4S7kcUObQvUwvFnYxJuuHUKm2aieN9X3yZB4LZsuYNU1Qphsw==} + '@types/node@12.20.55': + resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==} + + '@types/node@20.19.27': + resolution: {integrity: sha512-N2clP5pJhB2YnZJ3PIHFk5RkygRX5WO/5f0WC08tp0wd+sv0rsJk3MqWn3CbNmT2J505a5336jaQj4ph1AdMug==} '@types/node@22.7.5': resolution: {integrity: sha512-jML7s2NAzMWc//QSJ1a3prpk78cOPchGvXJsC3C6R6PSMoooztvRVQEz89gmBTBY1SPMaqo5teB4uNHPdetShQ==} @@ -1644,15 +1944,24 @@ packages: peerDependencies: '@types/react': ^18.0.0 - '@types/react@18.3.23': - resolution: {integrity: sha512-/LDXMQh55EzZQ0uVAZmKKhfENivEvWz6E+EYzh+/MCjMhNsotd+ZHhBGIjFDTi6+fz0OhQQQLbTgdQIxxCsC0w==} + '@types/react@18.3.27': + resolution: {integrity: sha512-cisd7gxkzjBKU2GgdYrTdtQx1SORymWyaAFhaxQPK9bYO9ot3Y5OikQRvY0VYQtvwjeQnizCINJAenh/V7MK2w==} - '@types/secp256k1@4.0.6': - resolution: {integrity: sha512-hHxJU6PAEUn0TP4S/ZOzuTUvJWuZ6eIKeNKb5RBpODvSl6hp1Wrw4s7ATY50rklRCScUDpHzVA/DQdSjJ3UoYQ==} + '@types/secp256k1@4.0.7': + resolution: {integrity: sha512-Rcvjl6vARGAKRO6jHeKMatGrvOMGrR/AR11N1x2LqintPCyDZ7NBhrh238Z2VZc7aM7KIwnFpFQ7fnfK4H/9Qw==} '@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==} + + '@types/ws@7.4.7': + resolution: {integrity: sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww==} + + '@types/ws@8.18.1': + resolution: {integrity: sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==} + '@uniswap/lib@4.0.1-alpha': resolution: {integrity: sha512-f6UIliwBbRsgVLxIaBANF6w09tYqc6Y/qXdsrbEmXHyFA7ILiKrIwRFXe1yOg8M3cksgVsO9N7yuL2DdCGQKBA==} engines: {node: '>=10'} @@ -1718,18 +2027,18 @@ packages: '@vitest/utils@3.2.4': resolution: {integrity: sha512-fB2V0JFrQSMsCo9HiSq3Ezpdv4iYaXRG1Sx8edX3MwxfyNn83mKiGzOcH+Fkxt4MHxr3y42fQi1oeAInqgX2QA==} - '@wagmi/connectors@5.9.0': - resolution: {integrity: sha512-ZJDPGi74zMTOeF4CjUxDcS6IKKWumu7+XMMaIsEHL3kILTCGji4w6KKA5OHDsM2021hffeGMjBnlJ6myroUUXw==} + '@wagmi/connectors@6.2.0': + resolution: {integrity: sha512-2NfkbqhNWdjfibb4abRMrn7u6rPjEGolMfApXss6HCDVt9AW2oVC6k8Q5FouzpJezElxLJSagWz9FW1zaRlanA==} peerDependencies: - '@wagmi/core': 2.18.0 + '@wagmi/core': 2.22.1 typescript: '>=5.0.4' viem: 2.x peerDependenciesMeta: typescript: optional: true - '@wagmi/core@2.18.0': - resolution: {integrity: sha512-33Wc/nnc/Q4qrqSL0F8BIDsG0iFTPrB4avjL/9vIE2DrA3GS3scVnrn6OtxpyF2TrwDZVfA+XUmfvoKuqtWPgw==} + '@wagmi/core@2.22.1': + resolution: {integrity: sha512-cG/xwQWsBEcKgRTkQVhH29cbpbs/TdcUJVFXCyri3ZknxhMyGv0YEjTcrNpRgt2SaswL1KrvslSNYKKo+5YEAg==} peerDependencies: '@tanstack/query-core': '>=5.0.0' typescript: '>=5.0.4' @@ -1831,6 +2140,17 @@ packages: abbrev@1.0.9: resolution: {integrity: sha512-LEyx4aLEC3x6T0UguF6YILf+ntvmOaWsVfENmIW0E9H09vKlLDGelMjjSm0jkDHALj8A8quZ/HapKNigzwge+Q==} + 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: @@ -1842,8 +2162,8 @@ packages: zod: optional: true - abitype@1.1.0: - resolution: {integrity: sha512-6Vh4HcRxNMLA0puzPjM5GBgT4aAcFGKZzSgAXvuZ27shJP6NEpielTuqbBmZILR5/xd0PizkBGy5hReKz9jl5A==} + abitype@1.2.3: + resolution: {integrity: sha512-Ofer5QUnuUdTFsBRwARMoWKOH1ND5ehwYhJ3OJ/BQO+StkwQjHw0XyVh4vDttzHB7QOFhPHa/o413PJ82gU/Tg==} peerDependencies: typescript: '>=5.0.4' zod: ^3.22.0 || ^4.0.0 @@ -1876,6 +2196,10 @@ packages: resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} engines: {node: '>= 6.0.0'} + agentkeepalive@4.6.0: + resolution: {integrity: sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ==} + engines: {node: '>= 8.0.0'} + aggregate-error@3.1.0: resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==} engines: {node: '>=8'} @@ -1883,8 +2207,8 @@ packages: ajv@8.17.1: resolution: {integrity: sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==} - amazon-cognito-identity-js@6.3.15: - resolution: {integrity: sha512-G2mzTlGYHKYh9oZDO0Gk94xVQ4iY9GYWBaYScbDYvz05ps6dqi0IvdNx1Lxi7oA3tjS5X+mUN7/svFJJdOB9YA==} + amazon-cognito-identity-js@6.3.16: + resolution: {integrity: sha512-HPGSBGD6Q36t99puWh0LnptxO/4icnk2kqIQ9cTJ2tFQo5NMUnWQIgtrTAk8nm+caqUbjDzXzG56GBjI2tS6jQ==} amdefine@1.0.1: resolution: {integrity: sha512-S2Hw0TtNkMJhIabBwIojKL9YHO5T0n5eNqWJ7Lrlel/zDbftQpxpapi8tZs3X1HWa+u+QeydGmzzNU0m09+Rcg==} @@ -1909,10 +2233,6 @@ packages: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} - ansi-regex@6.1.0: - resolution: {integrity: sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==} - engines: {node: '>=12'} - ansi-styles@3.2.1: resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} engines: {node: '>=4'} @@ -1921,10 +2241,6 @@ packages: resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} engines: {node: '>=8'} - ansi-styles@6.2.1: - resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} - engines: {node: '>=12'} - antlr4ts@0.5.0-alpha.4: resolution: {integrity: sha512-WPQDt1B74OfPv/IMS2ekXAKkTZIHl88uMetg6q3OTqgFxZ/dxDXI0EWLyZid/1Pe6hTftyg5N7gel5wNAGxXyQ==} @@ -2001,8 +2317,8 @@ packages: resolution: {integrity: sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==} engines: {node: '>=8.0.0'} - autoprefixer@10.4.21: - resolution: {integrity: sha512-O+A6LWV5LDHSJD3LjHYoNi4VLsj/Whi7k6zG12xTYaU4cQ8oxQGckXNX8cRHK5yOZ/ppVHe0ZBXGzSV9jXdVbQ==} + autoprefixer@10.4.23: + resolution: {integrity: sha512-YYTXSFulfwytnjAPlw8QHncHJmlvFKtczb8InXaAx9Q0LbfDnfEYDE55omerIJKihhmU61Ft+cAOSzQVaBUmeA==} engines: {node: ^10 || ^12 || >=14} hasBin: true peerDependencies: @@ -2012,8 +2328,13 @@ packages: resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} engines: {node: '>= 0.4'} - axios@1.11.0: - resolution: {integrity: sha512-1Lx3WLFQWm3ooKDYZD1eXmoGO9fxYQjrycfHFC8P0sCfQVXyROp0p9PFWBehewBOdCwHc+f/b8I0fMto5eSfwA==} + axios-retry@4.5.0: + resolution: {integrity: sha512-aR99oXhpEDGo0UuAlYcn2iGRds30k366Zfa05XWScR9QaQD4JYiP3/1Qt1u7YlefUOK+cn0CcwoL1oefavQUlQ==} + peerDependencies: + axios: 0.x || 1.x + + axios@1.13.2: + resolution: {integrity: sha512-VPk9ebNqPcy5lRGuSlKx752IlDatOjT9paPlm8A7yOuW2Fbvp4X3JznJtT4f0GzGLLiWE9W8onz51SqLYwzGaA==} balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} @@ -2030,6 +2351,10 @@ packages: base64-sol@1.0.1: resolution: {integrity: sha512-ld3cCNMeXt4uJXmLZBHFGMvVpK9KsLVEhPpFRXnvSVAqABKbuNZg/+dsq3NuM+wxFLb/UrVkz7m1ciWmkMfTbg==} + baseline-browser-mapping@2.9.10: + resolution: {integrity: sha512-2VIKvDx8Z1a9rTB2eCkdPE5nSe28XnA+qivGnWHoB40hMMt/h1hSz0960Zqsn6ZyxWXUie0EBdElKv8may20AA==} + hasBin: true + bech32@1.1.4: resolution: {integrity: sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==} @@ -2055,8 +2380,11 @@ packages: bn.js@5.2.2: resolution: {integrity: sha512-v2YAxEmKaBLahNwE1mjp4WON6huMNeuDvagFZW+ASCuA/ku0bXR9hSMw0XpiqMoA3+rmnyck/tPRSFQkoC9Cuw==} - bowser@2.11.0: - resolution: {integrity: sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA==} + borsh@0.7.0: + resolution: {integrity: sha512-CLCsZGIBCFnPtkNnieW/a8wmreDmfUtjU2m9yHrzPXIlNbqVs0AQrSatSG6vdNYUqdc83tkQi2eHfF98ubzQLA==} + + bowser@2.13.1: + resolution: {integrity: sha512-OHawaAbjwx6rqICCKgSG0SAnT05bzd7ppyKLVUITZpANBaaMFBAsaNkto3LoQ31tyFP5kNujE8Cdx85G9VzOkw==} boxen@5.1.2: resolution: {integrity: sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ==} @@ -2081,8 +2409,8 @@ packages: browserify-aes@1.2.0: resolution: {integrity: sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==} - browserslist@4.25.1: - resolution: {integrity: sha512-KGj0KoOMXLpSNkkEI6Z6mShmQy0bc1I+T7K9N81k4WWMrfz+6fQ6es80B/YLAeRoKvjYE1YSHHOW1qe9xIVzHw==} + browserslist@4.28.1: + resolution: {integrity: sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true @@ -2143,14 +2471,14 @@ packages: resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} engines: {node: '>=10'} - caniuse-lite@1.0.30001727: - resolution: {integrity: sha512-pB68nIHmbN6L/4C6MH1DokyR3bYqFwjaSs/sWDHGj4CTcFtQUQMuJftVwWkXq7mNWOybD3KhUv3oWHoGxgP14Q==} + caniuse-lite@1.0.30001760: + resolution: {integrity: sha512-7AAMPcueWELt1p3mi13HR/LHH0TJLT11cnwDJEs3xA4+CK/PLKeO9Kl1oru24htkyUKtkGCvAx4ohB0Ttry8Dw==} caseless@0.12.0: resolution: {integrity: sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==} - cbor@10.0.9: - resolution: {integrity: sha512-KEWYehb/vJkRmigctVQLsz73Us2RNnITo/wOwQV5AtZpLGH1r2PPlsNHdsX460YuHZCyhLklbYzAOuJfOeg34Q==} + cbor@10.0.11: + resolution: {integrity: sha512-vIwORDd/WyB8Nc23o2zNN5RrtFGlR6Fca61TtjkUXueI3Jf2DOZDl1zsshvBntZ3wZHBM9ztjnkXSmzQDaq3WA==} engines: {node: '>=20'} cbor@8.1.0: @@ -2170,8 +2498,8 @@ packages: resolution: {integrity: sha512-RITGBfijLkBddZvnn8jdqoTypxvqbOLYQkGGxXzeFjVHvudaPw0HNFD9x928/eUwYWd2dPCugVqspGALTZZQKw==} engines: {node: '>=4'} - chai@5.2.1: - resolution: {integrity: sha512-5nFxhUrX0PqtyogoYOA8IPswy5sZFTOsBFl/9bNsmDLgsxYTzSZQJDPppDnZPTQbzSEm0hqGjWPzRemQCYbD6A==} + chai@5.3.3: + resolution: {integrity: sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==} engines: {node: '>=18'} chalk@2.4.2: @@ -2182,6 +2510,10 @@ packages: resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} engines: {node: '>=10'} + chalk@5.6.2: + resolution: {integrity: sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==} + engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + charenc@0.0.2: resolution: {integrity: sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==} @@ -2203,8 +2535,8 @@ packages: ci-info@2.0.0: resolution: {integrity: sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==} - cipher-base@1.0.6: - resolution: {integrity: sha512-3Ek9H3X6pj5TgenXYtNWdaBon1tgYCaebd+XPg0keyjEbEfkD4KkmAxkQ/i1vYvxdcT5nscLBfq9VJRmCBcFSw==} + cipher-base@1.0.7: + resolution: {integrity: sha512-Mz9QMT5fJe7bKI7MH31UilT5cEK5EHHRCccw/YRFsRY47AuNgaV6HY3rscp0/I4Q+tTW/5zoqpSeRRI54TkDWA==} engines: {node: '>= 0.10'} clean-stack@2.2.0: @@ -2265,6 +2597,17 @@ packages: resolution: {integrity: sha512-sH5ZSPr+7UStsloltmDh7Ce5fb8XPlHyoPzTpyyMuYCtervL65+ubVZ6Q61cFtFl62UyJlc8/JwERRbAFPUqgw==} engines: {node: '>=8.0.0'} + commander@14.0.0: + resolution: {integrity: sha512-2uM9rYjPvyq39NwLRqaiLtWHyDC1FvryJDa2ATTVims5YAS4PupsEQsDvP14FqhFr0P49CYDugi59xaxJlTXRA==} + engines: {node: '>=20'} + + commander@14.0.2: + resolution: {integrity: sha512-TywoWNNRbhoD0BXs1P3ZEScW8W5iKrnbithIl0YH+uCmBd0QpPOA8yc82DS3BIE5Ma6FnBVUsJ7wVUDz4dvOWQ==} + engines: {node: '>=20'} + + commander@2.20.3: + resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} + commander@4.1.1: resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} engines: {node: '>= 6'} @@ -2301,9 +2644,6 @@ packages: engines: {node: '>=0.8'} hasBin: true - create-hash@1.1.3: - resolution: {integrity: sha512-snRpch/kwQhcdlnZKYanNF1m0RDlrCdSKQaH87w1FCFPVPNCQ/Il9QJKAX2jVBZddRdaHBMC+zXa9Gw9tmkNUA==} - create-hash@1.2.0: resolution: {integrity: sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==} @@ -2319,10 +2659,6 @@ packages: 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==} @@ -2338,11 +2674,11 @@ packages: engines: {node: '>=4'} hasBin: true - csstype@3.1.3: - resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} + csstype@3.2.3: + resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} - cuer@0.0.2: - resolution: {integrity: sha512-MG1BYnnSLqBnO0dOBS1Qm/TEc9DnFa9Sz2jMA24OF4hGzs8UuPjpKBMkRPF3lrpC+7b3EzULwooX9djcvsM8IA==} + cuer@0.0.3: + resolution: {integrity: sha512-f/UNxRMRCYtfLEGECAViByA3JNflZImOk11G9hwSd+44jvzrc99J35u5l+fbdQ2+ZG441GvOpaeGYBmWquZsbQ==} peerDependencies: react: '>=18' react-dom: '>=18' @@ -2361,8 +2697,8 @@ packages: death@1.1.0: resolution: {integrity: sha512-vsV6S4KVHvTGxbEcij7hkWRv0It+sGGWVOM67dQde/o5Xjnr+KmLjxWJii2uEObIrt1CcM9w0Yaovx+iOlIL+w==} - debug@4.3.7: - resolution: {integrity: sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==} + debug@4.3.4: + resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} engines: {node: '>=6.0'} peerDependencies: supports-color: '*' @@ -2370,8 +2706,8 @@ packages: supports-color: optional: true - debug@4.4.1: - resolution: {integrity: sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==} + debug@4.4.3: + resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} engines: {node: '>=6.0'} peerDependencies: supports-color: '*' @@ -2391,8 +2727,8 @@ packages: resolution: {integrity: sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==} engines: {node: '>=0.10'} - dedent@1.6.0: - resolution: {integrity: sha512-F1Z+5UCFpmQUzJa11agbyPVMbpgT/qA3/SKyJ1jyBgm7dUcUEa8v9JwDkerSQXfakBwFljIxhOJqGkjUwZ9FSA==} + dedent@1.7.1: + resolution: {integrity: sha512-9JmrhGZpOlEgOLdQgSm0zxFaYoQon408V1v49aqTWuXENVlnCuY9JBZcXZiCsZQWDjTm5Qf/nIvAy77mXDAjEg==} peerDependencies: babel-plugin-macros: ^3.1.0 peerDependenciesMeta: @@ -2428,6 +2764,10 @@ packages: 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'} @@ -2450,8 +2790,8 @@ packages: detect-node-es@1.1.0: resolution: {integrity: sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==} - dexie@4.0.11: - resolution: {integrity: sha512-SOKO002EqlvBYYKQSew3iymBoN2EQ4BDw/3yprjh7kAfFzjBYkaMNa/pZvcA7HSWlcKSQb9XhPe3wKyQ0x4A8A==} + dexie@4.2.1: + resolution: {integrity: sha512-Ckej0NS6jxQ4Po3OrSQBFddayRhTCic2DoCAG5zacOfOVB9P2Q5Xc5uL/nVa7ZVs+HdMnvUPzLFCB/JwpB6Csg==} didyoumean@1.2.2: resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==} @@ -2488,15 +2828,12 @@ packages: duplexify@4.1.3: resolution: {integrity: sha512-M3BmBhwJRZsSx38lZyhE53Csddgzl5R7xGJNk7CVddZD6CcmwMCH8J+7AprIrQKH7TonKxaCjcv27Qmf+sQ+oA==} - eastasianwidth@0.2.0: - resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} - - eciesjs@0.4.15: - resolution: {integrity: sha512-r6kEJXDKecVOCj2nLMuXK/FCPeurW33+3JRpfXVbjLja3XUYFfD9I/JBreH6sUyzcm3G/YQboBjMla6poKeSdA==} + eciesjs@0.4.16: + resolution: {integrity: sha512-dS5cbA9rA2VR4Ybuvhg6jvdmp46ubLn3E+px8cG/35aEDNclrqoCjg6mt0HYZ/M+OoESS3jSkCrqk1kWAEhWAw==} engines: {bun: '>=1', deno: '>=2', node: '>=16'} - electron-to-chromium@1.5.191: - resolution: {integrity: sha512-xcwe9ELcuxYLUFqZZxL19Z6HVKcvNkIwhbHUz7L3us6u12yR+7uY89dSl570f/IqNthx8dAw3tojG7i4Ni4tDA==} + electron-to-chromium@1.5.267: + resolution: {integrity: sha512-0Drusm6MVRXSOJpGbaSVgcQsuB4hEkMpHXaVstcPmhu5LIedxs1xNK/nIxmQIU/RPC0+1/o0AVZfBTkTNJOdUw==} elliptic@6.6.1: resolution: {integrity: sha512-RaddvvMatK2LJHqFJ+YA4WysVN5Ita9E35botqIYspQ4TkRAlCicdzKOjlyv/1Za5RyTNn7di//eEV0uTAfe3g==} @@ -2504,9 +2841,6 @@ packages: emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} - emoji-regex@9.2.2: - resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} - encode-utf8@1.0.3: resolution: {integrity: sha512-ucAnuBEhUK4boH2HjVYG5Q2mQyPorvv0u/ocS+zhdw0S8AlHYY+GOFhP1Gio5z4icpP2ivFSvhtFjQi8+T9ppw==} @@ -2550,6 +2884,12 @@ packages: 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==} + + es6-promisify@5.0.0: + resolution: {integrity: sha512-C+d6UdsYDk0lMebHNR4S2NybQMMngAOnOwYBQjTOiv0MkoJMP0Myw2mgpDLBcpfCmRLxyFqYhS/CfOENq4SJhQ==} + esbuild@0.21.5: resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==} engines: {node: '>=12'} @@ -2634,8 +2974,8 @@ packages: ethers@5.8.0: resolution: {integrity: sha512-DUq+7fHrCg1aPDFCHx6UIPb3nmt2XMpM7Y/g2gLhsl3lIBqeAfOJIl1qEvRf2uq3BiKxmh6Fh5pfp2ieyek7Kg==} - ethers@6.15.0: - resolution: {integrity: sha512-Kf/3ZW54L4UT0pZtsY/rf+EkBU7Qi5nnhonjUb8yTXcxH3cdcWrV2cRyk0Xk/4jK6OoHhxxZHriyhje20If2hQ==} + ethers@6.16.0: + resolution: {integrity: sha512-U1wulmetNymijEhpSEQ7Ct/P/Jw9/e7R1j5XIbPRydgV2DjLVMsULDlNksq3RQnFgKoLlZf88ijYtWEXcPa07A==} engines: {node: '>=14.0.0'} ethjs-unit@0.1.6: @@ -2655,14 +2995,18 @@ packages: evp_bytestokey@1.0.3: resolution: {integrity: sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==} - expect-type@1.2.2: - resolution: {integrity: sha512-JhFGDVJ7tmDJItKhYgJCGLOWjuK9vPxiXoUFLwLDc99NlmklilbiQJwoctZtt13+xMw91MCk/REan6MWHqDjyA==} + expect-type@1.3.0: + resolution: {integrity: sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==} engines: {node: '>=12.0.0'} 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'} + fast-base64-decode@1.0.0: resolution: {integrity: sha512-qwaScUgUGBYeDNRnbc/KyllVU88Jk1pRHPStuF/lO7B0/RTRLj7U0lkdTAutlBblY08rwZDff6tNU9cjv6j//Q==} @@ -2683,18 +3027,25 @@ packages: fast-safe-stringify@2.1.1: resolution: {integrity: sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==} - fast-uri@3.0.6: - resolution: {integrity: sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==} + fast-stable-stringify@1.0.0: + resolution: {integrity: sha512-wpYMUmFu5f00Sm0cj2pfivpmawLZ0NKdviQ4w9zJeR8JVtOpOxHmLaJuj0vxvGqMJQWyP/COUkF75/57OKyRag==} + + fast-uri@3.1.0: + resolution: {integrity: sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==} fast-xml-parser@5.2.5: resolution: {integrity: sha512-pfX9uG9Ki0yekDHx2SiuRIyFdyAr1kMIMitPvb0YBo8SUfKvia7w7FIyd/l6av85pFYRhZscS75MwMnbvY+hcQ==} hasBin: true + fastestsmallesttextencoderdecoder@1.0.22: + resolution: {integrity: sha512-Pb8d48e+oIuY4MaM64Cd7OW1gt4nxCHs7/ddPPZ/Ic3sg8yVGM7O9wDvZ7us6ScaUupzM+pfBolwtYhN1IxBIw==} + fastq@1.19.1: resolution: {integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==} - fdir@6.4.6: - resolution: {integrity: sha512-hiFoqpyZcfNm1yc4u8oWCf9A2c4D3QjCrks3zmoVKVxpQRzmPNar1hUJcBG2RQHvEVGDN+Jm81ZheVLAQMK6+w==} + fdir@6.5.0: + resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} + engines: {node: '>=12.0.0'} peerDependencies: picomatch: ^3 || ^4 peerDependenciesMeta: @@ -2725,8 +3076,8 @@ packages: resolution: {integrity: sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==} hasBin: true - follow-redirects@1.15.9: - resolution: {integrity: sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==} + follow-redirects@1.15.11: + resolution: {integrity: sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==} engines: {node: '>=4.0'} peerDependencies: debug: '*' @@ -2738,26 +3089,22 @@ packages: resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==} engines: {node: '>= 0.4'} - foreground-child@3.3.1: - resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==} - engines: {node: '>=14'} - form-data@2.5.5: resolution: {integrity: sha512-jqdObeR2rxZZbPSGL+3VckHMYtu+f9//KXBsVny6JSX/pa38Fy+bGjuG8eW/H6USNQWhLi8Num++cU2yOCNz4A==} engines: {node: '>= 0.12'} - form-data@4.0.4: - resolution: {integrity: sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==} + form-data@4.0.5: + resolution: {integrity: sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==} engines: {node: '>= 6'} fp-ts@1.19.3: resolution: {integrity: sha512-H5KQDspykdHuztLTg+ajGN0Z2qUjcEf3Ybxc6hLt0k7/zPkn29XnKnxlBPyW2XIddWrGaJBzBl4VLYOtk39yZg==} - fraction.js@4.3.7: - resolution: {integrity: sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==} + fraction.js@5.3.4: + resolution: {integrity: sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ==} - framer-motion@12.23.9: - resolution: {integrity: sha512-TqEHXj8LWfQSKqfdr5Y4mYltYLw96deu6/K9kGDd+ysqRJPNwF9nb5mZcrLmybHbU7gcJ+HQar41U3UTGanbbQ==} + framer-motion@12.23.26: + resolution: {integrity: sha512-cPcIhgR42xBn1Uj+PzOyheMtZ73H927+uWPDVhUMqxy8UHt6Okavb6xIz9J/phFUHUj0OncR6UvMfJTXoc/LKA==} peerDependencies: '@emotion/is-prop-valid': '*' react: ^18.0.0 || ^19.0.0 @@ -2800,6 +3147,10 @@ packages: 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'} @@ -2839,10 +3190,6 @@ packages: resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} engines: {node: '>=10.13.0'} - glob@10.4.5: - resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} - hasBin: true - glob@5.0.15: resolution: {integrity: sha512-c9IPMazfRITpmAAKi22dK1VKxGDX9ehhqfABDriL/lzO92xcUKEJPQHrVA/2YHSNFB4iFlykVmWvwo48nr3OxA==} deprecated: Glob versions prior to v9 are no longer supported @@ -2879,8 +3226,8 @@ packages: graceful-fs@4.2.11: resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} - h3@1.15.3: - resolution: {integrity: sha512-z6GknHqyX0h9aQaTx22VZDf6QyZn+0Nh+Ym8O/u0SGSkyF5cuTJYKlc8MkzW3Nzf9LE1ivcpmYC3FUGpywhuUQ==} + h3@1.15.4: + resolution: {integrity: sha512-z5cFQWDffyOe4vQ9xIqNfCZdV4p//vy6fBnr8Q1AWnVZ0teurKMG66rLj++TKwKPUP3u7iMUvrvKaEUiQw2QWQ==} handlebars@4.7.8: resolution: {integrity: sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==} @@ -2898,8 +3245,8 @@ packages: peerDependencies: hardhat: ^2.0.2 - hardhat@2.26.1: - resolution: {integrity: sha512-CXWuUaTtehxiHPCdlitntctfeYRgujmXkNX5gnrD5jdA6HhRQt+WWBZE/gHXbE29y/wDmmUL2d652rI0ctjqjw==} + hardhat@2.28.0: + resolution: {integrity: sha512-A3yBISI18EcnY2IR7Ny2xZF33Q3qH01yrWapeWbyGOiJm/386SasWjbHRHYgUlZ3YWJETIMh7wYfMUaXrofTDQ==} hasBin: true peerDependencies: ts-node: '*' @@ -2933,12 +3280,9 @@ packages: resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} engines: {node: '>= 0.4'} - hash-base@2.0.2: - resolution: {integrity: sha512-0TROgQ1/SxE6KmxWSvXHvRj90/Xo1JvZShofnYF+f6ZsGtR4eES7WfrQzPalmyagfKZCXpVnitiRebZulWsbiw==} - - hash-base@3.1.0: - resolution: {integrity: sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==} - engines: {node: '>=4'} + hash-base@3.1.2: + resolution: {integrity: sha512-Bb33KbowVTIj5s7Ked1OsqHUeCpz//tPwR+E2zJgJKo9Z5XolZ9b6bdUgjmYlwnWhoOQKoTd1TYToZGn5mAYOg==} + engines: {node: '>= 0.8'} hash.js@1.1.7: resolution: {integrity: sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==} @@ -2957,12 +3301,16 @@ packages: hmac-drbg@1.0.1: resolution: {integrity: sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==} + hono@4.11.1: + resolution: {integrity: sha512-KsFcH0xxHes0J4zaQgWbYwmz3UPOOskdqZmItstUG93+Wk1ePBLkLGwbP9zlmh1BFUiL8Qp+Xfu9P7feJWpGNg==} + engines: {node: '>=16.9.0'} + http-basic@8.1.3: resolution: {integrity: sha512-/EcDMwJZh3mABI2NhGfHOGOeOZITqfkEO4p/xK+l3NpyncIHUQBoMvCSF/b5GqvKtySC2srL/GGG3+EtlqlmCw==} engines: {node: '>=6.0.0'} - http-errors@2.0.0: - resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} + http-errors@2.0.1: + resolution: {integrity: sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==} engines: {node: '>= 0.8'} http-response-object@3.0.2: @@ -2972,6 +3320,9 @@ packages: resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} engines: {node: '>= 6'} + humanize-ms@1.2.1: + resolution: {integrity: sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==} + iconv-lite@0.4.24: resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} engines: {node: '>=0.10.0'} @@ -3027,6 +3378,9 @@ packages: resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} engines: {node: '>=8'} + 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'} @@ -3047,8 +3401,8 @@ packages: resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} engines: {node: '>=8'} - is-generator-function@1.1.0: - resolution: {integrity: sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==} + is-generator-function@1.1.2: + resolution: {integrity: sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==} engines: {node: '>= 0.4'} is-glob@4.0.3: @@ -3071,6 +3425,10 @@ packages: 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'} @@ -3095,6 +3453,11 @@ packages: isomorphic-unfetch@3.1.0: resolution: {integrity: sha512-geDJjpoZ8N0kWexiwkX8F9NkTsXhetLPVbZFQ+JTW239QNOwvB0gniuR1Wc6f0AMTn7/mFGyXvHTifrCp/GH8Q==} + isomorphic-ws@4.0.1: + resolution: {integrity: sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w==} + peerDependencies: + ws: '*' + isows@1.0.6: resolution: {integrity: sha512-lPHCayd40oW98/I0uvgaHKWCSvkzY27LjWLbtzOm64yQ+G3Q5npjjbdppU65iZXkK1Zt+kH9pfegli0AYfwYYw==} peerDependencies: @@ -3105,13 +3468,18 @@ packages: peerDependencies: ws: '*' - jackspeak@3.4.3: - resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} + jayson@4.2.0: + resolution: {integrity: sha512-VfJ9t1YLwacIubLhONk0KFeosUBwstRWQ0IRT1KDjEjnVnSOVHC3uwugyV7L0c7R9lpVyrUGT2XWiBA1UTtpyg==} + engines: {node: '>=8'} + hasBin: true jiti@1.21.7: resolution: {integrity: sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==} hasBin: true + jose@6.1.3: + resolution: {integrity: sha512-0TpaTfihd4QMNwrz/ob2Bp7X04yuxJkjRGi4aKmOqwhov54i6u79oCv7T+C7lo70MKH6BesI3vscD1yb/yzKXQ==} + js-cookie@2.2.1: resolution: {integrity: sha512-HvdH2LzI/EAZcUwA8+0nKNtWHqS+ZmijLA30RwZA0bo7ToCckjK5MkGhjED9KoRcXO6BaGI3I9UIzSA1FKFPOQ==} @@ -3124,12 +3492,12 @@ packages: js-tokens@9.0.1: resolution: {integrity: sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==} - js-yaml@3.14.1: - resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} + js-yaml@3.14.2: + resolution: {integrity: sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==} hasBin: true - js-yaml@4.1.0: - resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} + js-yaml@4.1.1: + resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==} hasBin: true jsesc@3.1.0: @@ -3162,8 +3530,8 @@ packages: jsonfile@4.0.0: resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} - jsonfile@6.1.0: - resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} + jsonfile@6.2.0: + resolution: {integrity: sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==} jsonschema@1.5.0: resolution: {integrity: sha512-K+A9hhqbn0f3pJX17Q/7H6yQfD/5OXgdrR5UE12gMXCiN9D5Xq2o5mddV2QEcX/bjla99ASsAAQUyMCCRWAEhw==} @@ -3238,8 +3606,8 @@ packages: loupe@2.3.7: resolution: {integrity: sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==} - loupe@3.2.0: - resolution: {integrity: sha512-2NCfZcT5VGVNX9mSZIxLRkEAegDGBpuQZBy13desuHeVORmBDyAET4TkJr4SjqQy3A8JDofMN6LpkK8Xcm/dlw==} + loupe@3.2.1: + resolution: {integrity: sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==} lru-cache@10.4.3: resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} @@ -3255,8 +3623,8 @@ packages: peerDependencies: react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0 - magic-string@0.30.17: - resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==} + magic-string@0.30.21: + resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} make-error@1.3.6: resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} @@ -3271,6 +3639,9 @@ packages: md5.js@1.3.5: resolution: {integrity: sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==} + md5@2.3.0: + resolution: {integrity: sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g==} + media-query-parser@2.0.2: resolution: {integrity: sha512-1N4qp+jE0pL5Xv4uEcwVUhIkwdUO3S/9gML90nqKA7v7FcOS5vUtatfzok9S9U1EJU8dHWlcv95WLnKmmxZI9w==} @@ -3309,8 +3680,8 @@ packages: minimalistic-crypto-utils@1.0.1: resolution: {integrity: sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==} - minimatch@10.0.3: - resolution: {integrity: sha512-IPZ167aShDZZUMdRk66cyQAW3qr0WzbHkPdMYa8bzZhlHhO3jALbKdxcaak7W9FfT2rZNpQuUu4Od7ILEpXSaw==} + minimatch@10.1.1: + resolution: {integrity: sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==} engines: {node: 20 || >=22} minimatch@3.1.2: @@ -3327,10 +3698,6 @@ packages: minimist@1.2.8: resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} - minipass@7.1.2: - resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} - engines: {node: '>=16 || 14 >=14.17'} - mipd@0.0.7: resolution: {integrity: sha512-aAPZPNDQ3uMTdKbuO2YmAw2TxLHO0moa4YKAyETM/DTj5FloZo+a+8tU+iv4GmW+sOxKLSRwcSFuczk+Cpt6fg==} peerDependencies: @@ -3359,12 +3726,15 @@ packages: modern-ahocorasick@1.1.0: resolution: {integrity: sha512-sEKPVl2rM+MNVkGQt3ChdmD8YsigmXdn5NifZn6jiwn9LRJpWm8F3guhaqrJT/JOat6pwpbXEk6kv+b9DMIjsQ==} - motion-dom@12.23.9: - resolution: {integrity: sha512-6Sv++iWS8XMFCgU1qwKj9l4xuC47Hp4+2jvPfyTXkqDg2tTzSgX6nWKD4kNFXk0k7llO59LZTPuJigza4A2K1A==} + motion-dom@12.23.23: + resolution: {integrity: sha512-n5yolOs0TQQBRUFImrRfs/+6X4p3Q4n1dUEqt/H58Vx7OW6RF+foWEgmTVDhIWJIMXOuNNL0apKH2S16en9eiA==} motion-utils@12.23.6: resolution: {integrity: sha512-eAWoPgr4eFEOFfg2WjIsMoqJTW6Z8MTUCgn/GZ3VRpClWBdnbjryiA3ZSNLyxCTmCQx4RmYX6jX1iWHbenUPNQ==} + ms@2.1.2: + resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} + ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} @@ -3396,8 +3766,8 @@ packages: node-emoji@1.11.0: resolution: {integrity: sha512-wo2DpQkQp7Sjm2A0cq+sN7EHKO6Sl0ctXeBdFZrL9T9+UywORbufTcTZxom8YqpLQt/FqNMUkOpkZrJVYSKD3A==} - node-fetch-native@1.6.6: - resolution: {integrity: sha512-8Mc2HhqPdlIfedsuZoc3yioPuzp6b+L5jRCRY1QzuWZh2EGJVQrGppC6V6cF0bLdbW0+O2YpqCA25aF/1lvipQ==} + node-fetch-native@1.6.7: + resolution: {integrity: sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q==} node-fetch@2.7.0: resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} @@ -3412,11 +3782,11 @@ packages: resolution: {integrity: sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==} hasBin: true - node-mock-http@1.0.1: - resolution: {integrity: sha512-0gJJgENizp4ghds/Ywu2FCmcRsgBTmRQzYPZm61wy+Em2sBarSka0OhQS5huLBg6od1zkNpnWMCZloQDFVvOMQ==} + node-mock-http@1.0.4: + resolution: {integrity: sha512-8DY+kFsDkNXy1sJglUfuODx1/opAGJGyrTuFqEoN90oRc2Vk0ZbD4K2qmKXBBEhZQzdKHIVfEJpDU8Ak2NJEvQ==} - node-releases@2.0.19: - resolution: {integrity: sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==} + node-releases@2.0.27: + resolution: {integrity: sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==} nofilter@3.1.0: resolution: {integrity: sha512-l2NNj07e9afPnhAhvgVrCD/oy2Ai1yfLpuo3EpiO1jFTsB4sFz6oIfAfSZyQzVpkZQ9xS8ZS5g1jCBgq4Hwo0g==} @@ -3430,10 +3800,6 @@ packages: resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} engines: {node: '>=0.10.0'} - normalize-range@0.1.2: - resolution: {integrity: sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==} - engines: {node: '>=0.10.0'} - number-to-bn@1.7.0: resolution: {integrity: sha512-wsJ9gfSz1/s4ZsJN01lyonwuxA1tml6X1yBDnfpMglypcBRFZZkus26EdPSlqS5GJfYddVZa22p3VNb3z5m5Ig==} engines: {node: '>=6.5.0', npm: '>=3'} @@ -3456,8 +3822,8 @@ packages: obliterator@2.0.5: resolution: {integrity: sha512-42CPE9AhahZRsMNslczq0ctAEtqk8Eka26QofnqC346BZdHDySk3LWka23LI7ULIw11NmltpiLagIq8gBozxTw==} - ofetch@1.4.1: - resolution: {integrity: sha512-QZj2DfGplQAr2oj9KzceK9Hwz6Whxazmn85yYeVuS3u9XTMOGMRx0kO95MQ+vLsj/S/NwBDMMLU5hpxvI6Tklw==} + ofetch@1.5.1: + resolution: {integrity: sha512-2W4oUZlVaqAPAil6FUg/difl6YhqhUR7x2eZY4bQCko22UXg3hptq9KLQdqFClV+Wu85UX7hNtdGTngi/1BxcA==} on-exit-leak-free@0.2.0: resolution: {integrity: sha512-dqaz3u44QbRXQooZLTUKU41ZrzYrcvLISVgbrzbyCMxpmSLJvZ3ZamIJIZ29P6OhZIkNIQKosdeM6t1LYbA9hg==} @@ -3465,6 +3831,12 @@ packages: once@1.4.0: resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + openapi-fetch@0.13.8: + resolution: {integrity: sha512-yJ4QKRyNxE44baQ9mY5+r/kAzZ8yXMemtNAOFwOzRXJscdjSxxzWSNlyBAr+o5JjkUw9Lc3W7OIoca0cY3PYnQ==} + + openapi-typescript-helpers@0.0.15: + resolution: {integrity: sha512-opyTPaunsklCBpTK8JGef6mfPhLSnyy5a0IN9vKtx3+4aExf+KxEqYwIy3hqkedXIB97u357uLMJsOnm3GVjsw==} + optionator@0.8.3: resolution: {integrity: sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==} engines: {node: '>= 0.8.0'} @@ -3476,6 +3848,14 @@ packages: resolution: {integrity: sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==} engines: {node: '>=0.10.0'} + ox@0.10.5: + resolution: {integrity: sha512-mXJRiZswmX46abrzNkJpTN9sPJ/Rhevsp5Dfg0z80D55aoLNmEV4oN+/+feSNW593c2CnHavMqSVBanpJ0lUkQ==} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + ox@0.6.7: resolution: {integrity: sha512-17Gk/eFsFRAZ80p5eKqv89a57uXjd3NgIf1CaXojATPBuujVc/fQSVhBeAU9JCRB+k7J50WQAyWTxK19T9GgbA==} peerDependencies: @@ -3492,8 +3872,8 @@ packages: typescript: optional: true - ox@0.9.3: - resolution: {integrity: sha512-KzyJP+fPV4uhuuqrTZyok4DC7vFzi7HLUFiUNEmpbyh59htKWkOC98IONC1zgXJPbHAhQgqs6B0Z6StCGhmQvg==} + ox@0.9.17: + resolution: {integrity: sha512-rKAnhzhRU3Xh3hiko+i1ZxywZ55eWQzeS/Q4HRKLx2PqfHOolisZHErSsJVipGlmQKHW5qwOED/GighEw9dbLg==} peerDependencies: typescript: '>=5.4.0' peerDependenciesMeta: @@ -3524,9 +3904,6 @@ packages: resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} engines: {node: '>=6'} - package-json-from-dist@1.0.1: - resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} - parse-cache-control@1.0.1: resolution: {integrity: sha512-60zvsJReQPX5/QP0Kzfd/VrpjScIQ7SHBW6bFCYfEP+fp0Eppr1SHhIO5nd1PjZtvclzSzES9D/p5nFJurwfWg==} @@ -3538,17 +3915,9 @@ packages: resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} engines: {node: '>=0.10.0'} - path-key@3.1.1: - resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} - engines: {node: '>=8'} - path-parse@1.0.7: resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} - path-scurry@1.11.1: - resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} - engines: {node: '>=16 || 14 >=14.18'} - path-type@4.0.0: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} engines: {node: '>=8'} @@ -3563,9 +3932,9 @@ packages: resolution: {integrity: sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==} engines: {node: '>= 14.16'} - pbkdf2@3.1.3: - resolution: {integrity: sha512-wfRLBZ0feWRhCIkoMB6ete7czJcnNnqRpcoWQBLqatqXXmelSRqfdDK4F3u9T2s2cXas/hQJcryI/4lAL+XTlA==} - engines: {node: '>=0.12'} + pbkdf2@3.1.5: + resolution: {integrity: sha512-Q3CG/cYvCO1ye4QKkuH7EXxs3VC/rI1/trd+qX2+PolbaKG0H+bgcZzrTt96mMyRtejk+JMCiLUn3y29W8qmFQ==} + engines: {node: '>= 0.10'} picocolors@1.1.1: resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} @@ -3616,6 +3985,38 @@ packages: resolution: {integrity: sha512-M7LhCsdNbNgiLYiP4WjsfLUuFmCfnjdF6jKe2R9NKl4WFN+HZPGHJZ9lnLP7f9ZnKe3U9nuWD0szirmj+migUg==} engines: {node: '>=12.0.0'} + 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'} @@ -3626,22 +4027,28 @@ packages: peerDependencies: postcss: ^8.0.0 - postcss-js@4.0.1: - resolution: {integrity: sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==} + postcss-js@4.1.0: + resolution: {integrity: sha512-oIAOTqgIo7q2EOwbhb8UalYePMvYoIeRY2YKntdpFQXNosSu3vLrniGgmH9OKs/qAkfoj5oB3le/7mINW1LCfw==} engines: {node: ^12 || ^14 || >= 16} peerDependencies: postcss: ^8.4.21 - postcss-load-config@4.0.2: - resolution: {integrity: sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==} - engines: {node: '>= 14'} + postcss-load-config@6.0.1: + resolution: {integrity: sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==} + engines: {node: '>= 18'} peerDependencies: + jiti: '>=1.21.0' postcss: '>=8.0.9' - ts-node: '>=9.0.0' + tsx: ^4.8.1 + yaml: ^2.4.2 peerDependenciesMeta: + jiti: + optional: true postcss: optional: true - ts-node: + tsx: + optional: true + yaml: optional: true postcss-nested@6.2.0: @@ -3664,8 +4071,8 @@ packages: preact@10.24.2: resolution: {integrity: sha512-1cSoF0aCC8uaARATfrlz4VCBqE8LwZwRfLgkxJOQwAlQt6ayTmi0D9OF7nXid1POI5SZidFuG9CnlXbDfLqY/Q==} - preact@10.26.9: - resolution: {integrity: sha512-SSjF9vcnF27mJK1XyFMNJzFd5u3pQiATFqoaDy03XuN00u4ziveVVEGt5RKJrDR8MHE/wJo9Nnad56RLzS2RMA==} + preact@10.28.0: + resolution: {integrity: sha512-rytDAoiXr3+t6OIP3WGlDd0ouCUG1iCWzkcY3++Nreuoi17y6T5i/zRhe6uYfoVcxq6YU+sBtJouuRDsq8vvqA==} prelude-ls@1.1.2: resolution: {integrity: sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==} @@ -3708,8 +4115,8 @@ packages: resolution: {integrity: sha512-KTqnxsgGiQ6ZAzZCVlJH5eOjSnvlyEgx1m8bkRJfOhmGRqfo5KLvmAlACQkrjEtOQ4B7wF9TdSLIs9O90MX9xA==} engines: {node: '>=16.0.0'} - qr@0.5.0: - resolution: {integrity: sha512-LtnyJsepKCMzfmHBZKVNo1g29kS+8ZbuxE9294EsRhHgVVpy4x8eFw9o4J9SIolDHoDYuaEIY+z8UjiCv/eudA==} + qr@0.5.3: + resolution: {integrity: sha512-BSrGdNXa8z6PfEYWtvITV21mQ4asR4UCj38Fa3MUUoFAtYzFK/swEQXF+OeBuNbHPFfs3PzpZuK0BXizWXgFOQ==} engines: {node: '>= 20.19.0'} qrcode@1.5.3: @@ -3737,8 +4144,8 @@ packages: randombytes@2.1.0: resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} - raw-body@2.5.2: - resolution: {integrity: sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==} + raw-body@2.5.3: + resolution: {integrity: sha512-s4VSOf6yN0rvbRZGxs8Om5CWj6seneMwK3oDb4lWDH0UPhWcxwOWw5+qk24bxq87szX1ydrwylIOp2uG1ojUpA==} engines: {node: '>= 0.8'} react-dom@18.3.1: @@ -3847,8 +4254,8 @@ packages: resolve@1.17.0: resolution: {integrity: sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==} - resolve@1.22.10: - resolution: {integrity: sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==} + resolve@1.22.11: + resolution: {integrity: sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==} engines: {node: '>= 0.4'} hasBin: true @@ -3864,21 +4271,22 @@ packages: resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} - ripemd160@2.0.1: - resolution: {integrity: sha512-J7f4wutN8mdbV08MJnXibYpCOPHR+yzy+iQ/AsjMv2j8cLavQ8VGagDFUwwTAdF8FmRKVeNpbTTEwNHCW1g94w==} - - ripemd160@2.0.2: - resolution: {integrity: sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==} + ripemd160@2.0.3: + resolution: {integrity: sha512-5Di9UC0+8h1L6ZD2d7awM7E/T4uA1fJRlx6zk/NvdCCVEoAnFqvHmCuNeIKoCeIixBX/q8uM+6ycDvF8woqosA==} + engines: {node: '>= 0.8'} rlp@2.2.7: resolution: {integrity: sha512-d5gdPmgQ0Z+AklL2NVXr/IoSjNZFfTVvQWzL/AM2AOcSzYP2xjlb0AC8YyCLc41MSNf6P6QVtjgPdmVtzb+4lQ==} hasBin: true - rollup@4.45.1: - resolution: {integrity: sha512-4iya7Jb76fVpQyLoiVpzUrsjQ12r3dM7fIVz+4NwoYvZOShknRmiv+iu9CClZml5ZLGb0XMcYLutK6w9tgxHDw==} + rollup@4.53.5: + resolution: {integrity: sha512-iTNAbFSlRpcHeeWu73ywU/8KuU/LZmNCSxp6fjQkJBD3ivUb8tpDrXhIxEzA05HlYMEwmtaUnb3RP+YNv162OQ==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true + rpc-websockets@9.3.2: + resolution: {integrity: sha512-VuW2xJDnl1k8n8kjbdRSWawPRkwaVqUQNjE1TdeTawf0y0abGhtVJFTXCLfgpgGDBkO/Fj6kny8Dc/nvOW78MA==} + run-parallel@1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} @@ -3921,8 +4329,8 @@ packages: resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} hasBin: true - semver@7.7.2: - resolution: {integrity: sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==} + semver@7.7.3: + resolution: {integrity: sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==} engines: {node: '>=10'} hasBin: true @@ -3950,14 +4358,6 @@ packages: sha1@1.1.1: resolution: {integrity: sha512-dZBS6OrMjtgVkopB1Gmo4RQCDKiZsqcpAQpkV/aaj+FCrCg8r4I4qMkDPQjBgLIxlmu9k4nUbWq6ohXahOneYA==} - shebang-command@2.0.0: - resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} - engines: {node: '>=8'} - - shebang-regex@3.0.0: - resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} - engines: {node: '>=8'} - shelljs@0.8.5: resolution: {integrity: sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==} engines: {node: '>=4'} @@ -3985,10 +4385,6 @@ packages: signal-exit@3.0.7: resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} - signal-exit@4.1.0: - resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} - engines: {node: '>=14'} - sisteransi@1.0.5: resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} @@ -4013,11 +4409,11 @@ packages: engines: {node: '>=10.0.0'} hasBin: true - solidity-ast@0.4.60: - resolution: {integrity: sha512-UwhasmQ37ji1ul8cIp0XlrQ/+SVQhy09gGqJH4jnwdo2TgI6YIByzi0PI5QvIGcIdFOs1pbSmJW1pnWB7AVh2w==} + solidity-ast@0.4.61: + resolution: {integrity: sha512-OYBJYcYyG7gLV0VuXl9CUrvgJXjV/v0XnR4+1YomVe3q+QyENQXJJxAEASUz4vN6lMAl+C8RSRSr5MBAz09f6w==} - solidity-coverage@0.8.16: - resolution: {integrity: sha512-qKqgm8TPpcnCK0HCDLJrjbOA2tQNEJY4dHX/LSSQ9iwYFS973MwjtgYn2Iv3vfCEQJTj5xtm4cuUMzlJsJSMbg==} + solidity-coverage@0.8.17: + resolution: {integrity: sha512-5P8vnB6qVX9tt1MfuONtCTEaEGO/O4WuEidPHIAJjx4sktHHKhO3rFvnE0q8L30nWJPTrcqGQMT7jpE29B2qow==} hasBin: true peerDependencies: hardhat: ^2.11.0 @@ -4061,12 +4457,18 @@ packages: resolution: {integrity: sha512-WjlahMgHmCJpqzU8bIBy4qtsZdU9lRlcZE3Lvyej6t4tuOuv1vk57OW3MBrj6hXBFx/nNoC9MPMTcr5YA7NQbg==} engines: {node: '>=6'} - statuses@2.0.1: - resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} + statuses@2.0.2: + resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==} engines: {node: '>= 0.8'} - std-env@3.9.0: - resolution: {integrity: sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw==} + std-env@3.10.0: + resolution: {integrity: sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==} + + stream-chain@2.2.5: + resolution: {integrity: sha512-1TJmBx6aSWqZ4tx7aTpBDXK0/e2hhcNSTV8+CbFJtDjbb+I1mZ8lHit0Grw9GRT+6JbIrrDd8esncgBi8aBXGA==} + + stream-json@1.9.1: + resolution: {integrity: sha512-uWkjJ+2Nt/LO9Z/JyKZbMusL8Dkh97uUBTv3AJQ74y07lVahLY4eEFsPsE97pxYBwr8nnjMAIch5eqI0gPShyw==} stream-shift@1.0.3: resolution: {integrity: sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ==} @@ -4086,10 +4488,6 @@ packages: resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} engines: {node: '>=8'} - string-width@5.1.2: - resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} - engines: {node: '>=12'} - string_decoder@1.1.1: resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} @@ -4104,10 +4502,6 @@ packages: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} engines: {node: '>=8'} - strip-ansi@7.1.0: - resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} - engines: {node: '>=12'} - strip-hex-prefix@1.0.0: resolution: {integrity: sha512-q8d4ue7JGEiVcypji1bALTos+0pWtyGlivAWyPuTkHzuTCJqrK9sWxYQZUq6Nq3cuyv3bm734IhHvHtGGURU6A==} engines: {node: '>=6.5.0', npm: '>=3'} @@ -4116,14 +4510,14 @@ packages: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} - strip-literal@3.0.0: - resolution: {integrity: sha512-TcccoMhJOM3OebGhSBEmp3UZ2SfDMZUEBdRA/9ynfLi8yYajyWX3JiXArcJt4Umh4vISpspkQIY8ZZoCqjbviA==} + strip-literal@3.1.0: + resolution: {integrity: sha512-8r3mkIM/2+PpjHoOtiAW8Rg3jJLHaV7xPwG+YRGrv6FP0wwk/toTpATxWYOW0BKdWwl82VT2tFYi5DlROa0Mxg==} - strnum@2.1.1: - resolution: {integrity: sha512-7ZvoFTiCnGxBtDqJ//Cu6fWtZtc7Y3x+QOirG15wztbdngGSkht27o2pyGWrVy0b4WAy3jbKmnoK6g5VlVNUUw==} + strnum@2.1.2: + resolution: {integrity: sha512-l63NF9y/cLROq/yqKXSLtcMeeyOfnSQlfMSlzFt/K73oIaD8DGaQWd7Z34X9GPiKqP5rbSh84Hl4bOlLcjiSrQ==} - sucrase@3.35.0: - resolution: {integrity: sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==} + sucrase@3.35.1: + resolution: {integrity: sha512-DhuTmvZWux4H1UOnWMB3sk0sbaCVOoQZjv8u1rDoTV0HTdGem9hkAZtl4JZy8P2z4Bg0nT+YMeOFyVr4zcG5Tw==} engines: {node: '>=16 || 14 >=14.17'} hasBin: true @@ -4131,6 +4525,10 @@ packages: 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@3.2.3: resolution: {integrity: sha512-Jds2VIYDrlp5ui7t8abHN2bjAu4LV/q4N2KivFPpGH0lrka0BMq/33AmECUXlKPcHigkNaqfXRENFju+rlcy+A==} engines: {node: '>=0.8.0'} @@ -4166,11 +4564,14 @@ packages: resolution: {integrity: sha512-9kY+CygyYM6j02t5YFHbNz2FN5QmYGv9zAjVp4lCDjlCw7amdckXlEt/bjMhUIfj4ThGRE4gCUH5+yGnNuPo5A==} engines: {node: '>=10.0.0'} - tailwindcss@3.4.17: - resolution: {integrity: sha512-w33E2aCvSDP0tW9RZuNXadXlkHXqFzSkQew/aIa2i/Sj8fThxwovwlXHSPXTbAHwEIhBFXAedUhP2tueAKP8Og==} + tailwindcss@3.4.19: + resolution: {integrity: sha512-3ofp+LL8E+pK/JuPLPggVAIaEuhvIz4qNcf3nA1Xn2o/7fb7s/TYpHhwGDv1ZU3PkBluUVaF8PyCHcm48cKLWQ==} engines: {node: '>=14.0.0'} hasBin: true + text-encoding-utf-8@1.0.2: + resolution: {integrity: sha512-8bw4MY9WjdsD2aMtO0OzOCY3pXGYNx2d2FfHRVUKkiCPDWjKuOlhLVASS+pD7VkLTVjW268LYJHwsnPFlBpbAg==} + then-request@6.0.2: resolution: {integrity: sha512-3ZBiG7JvP3wbDzA9iNY5zJQcHL4jn/0BWtXIkagfz7QgOL/LqjCEOBQuJNZfu0XYnv5JhKh+cDxCPM4ILrqruA==} engines: {node: '>=6.0.0'} @@ -4194,8 +4595,8 @@ packages: tinyexec@0.3.2: resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==} - tinyglobby@0.2.14: - resolution: {integrity: sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==} + tinyglobby@0.2.15: + resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} engines: {node: '>=12.0.0'} tinypool@1.1.1: @@ -4206,16 +4607,16 @@ packages: resolution: {integrity: sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==} engines: {node: '>=14.0.0'} - tinyspy@4.0.3: - resolution: {integrity: sha512-t2T/WLB2WRgZ9EpE4jgPJ9w+i66UZfDc8wHh0xrwiRNN+UwH98GIJkTeZqX9rg0i0ptwzqW+uYeIF0T4F8LR7A==} + tinyspy@4.0.4: + resolution: {integrity: sha512-azl+t0z7pw/z958Gy9svOTuzqIk6xq+NSheJzn5MMWtWTFywIacg2wUlzKFGtt3cthx0r2SxMK0yzJOR0IES7Q==} engines: {node: '>=14.0.0'} tmp@0.0.33: resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==} engines: {node: '>=0.6.0'} - to-buffer@1.2.1: - resolution: {integrity: sha512-tB82LpAIWjhLYbqjx3X4zEeHN6M8CiuOEy2JY8SEQVdYRe3CCHOFaqrBW1doLDrfpWhplcW7BL+bO3/6S3pcDQ==} + to-buffer@1.2.2: + resolution: {integrity: sha512-db0E3UJjcFhpDhAF4tLo03oli3pwl3dbnzXOUIlRKrp+ldk/VUxzpWYZENsw2SZiuBjHAk7DfB0VU7NKdpb6sw==} engines: {node: '>= 0.4'} to-regex-range@5.0.1: @@ -4303,8 +4704,8 @@ packages: typedarray@0.0.6: resolution: {integrity: sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==} - typescript@5.8.3: - resolution: {integrity: sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==} + typescript@5.9.3: + resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} engines: {node: '>=14.17'} hasBin: true @@ -4316,8 +4717,8 @@ packages: resolution: {integrity: sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg==} engines: {node: '>=8'} - ua-parser-js@1.0.40: - resolution: {integrity: sha512-z6PJ8Lml+v3ichVojCiB8toQJBuwR42ySM4ezjXIqXK3M0HczmKQ3LF4rhU55PfD99KEEXQG6yb7iOMyvYuHew==} + ua-parser-js@1.0.41: + resolution: {integrity: sha512-LbBDqdIC5s8iROCUjMbW1f5dJQTEFB1+KO9ogbvlb3nm9n4YHa5p4KTvFPWvh2Hs8gZMBuiB1/8+pdfe/tDPug==} hasBin: true ufo@1.6.1: @@ -4340,12 +4741,15 @@ packages: undici-types@6.21.0: resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} + undici-types@7.16.0: + resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==} + undici@5.29.0: resolution: {integrity: sha512-raqeBD6NQK4SkWhQzeYKd1KmIG6dllBOTt55Rmkt4HtI9mwdWtJljnrXjAFUBLTSN67HWrOIZ3EPF4kjUw80Bg==} engines: {node: '>=14.0'} - undici@6.21.3: - resolution: {integrity: sha512-gBLkYIlEnSp8pFbT64yFgGE6UIB9tAkhukC23PmMDCe5Nd+cRqKxSjw5y54MK2AZMgZfJWMaNE4nYUHgi1XEOw==} + undici@6.22.0: + resolution: {integrity: sha512-hU/10obOIu62MGYjdskASR3CUAiYaFTtC9Pa6vHyf//mAipSvSQg6od2CnJswq7fvzNS3zJhxoRkgNVaHurWKw==} engines: {node: '>=18.17'} unfetch@4.2.0: @@ -4363,8 +4767,8 @@ packages: resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} engines: {node: '>= 0.8'} - unstorage@1.16.1: - resolution: {integrity: sha512-gdpZ3guLDhz+zWIlYP1UwQ259tG5T5vYRzDaHMkQ1bBY1SQPutvZnrRjTFaWUUpseErJIgAZS51h6NOcZVZiqQ==} + unstorage@1.17.3: + resolution: {integrity: sha512-i+JYyy0DoKmQ3FximTHbGadmIYb8JEpq7lxUjnjeB702bCPum0vzo6oy5Mfu0lpqISw7hCyMW2yj4nWC8bqJ3Q==} peerDependencies: '@azure/app-configuration': ^1.8.0 '@azure/cosmos': ^4.2.0 @@ -4378,6 +4782,7 @@ packages: '@planetscale/database': ^1.19.0 '@upstash/redis': ^1.34.3 '@vercel/blob': '>=0.27.1' + '@vercel/functions': ^2.2.12 || ^3.0.0 '@vercel/kv': ^1.0.1 aws4fetch: ^1.0.20 db0: '>=0.2.1' @@ -4409,6 +4814,8 @@ packages: optional: true '@vercel/blob': optional: true + '@vercel/functions': + optional: true '@vercel/kv': optional: true aws4fetch: @@ -4422,8 +4829,8 @@ packages: uploadthing: optional: true - update-browserslist-db@1.1.3: - resolution: {integrity: sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==} + update-browserslist-db@1.2.3: + resolution: {integrity: sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==} hasBin: true peerDependencies: browserslist: '>= 4.21.0' @@ -4502,8 +4909,8 @@ packages: typescript: optional: true - viem@2.37.5: - resolution: {integrity: sha512-bLKvKgLcge6KWBMLk8iP9weu5tHNr0hkxPNwQd+YQrHEgek7ogTBBeE10T0V6blwBMYmeZFZHLnMhDmPjp63/A==} + viem@2.43.1: + resolution: {integrity: sha512-S33pBNlRvOlVv4+L94Z8ydCMDB1j0cuHFUvaC28i6OTxw3uY1P4M3h1YDFK8YC1H9/lIbeBTTvCRhi0FqU/2iw==} peerDependencies: typescript: '>=5.0.4' peerDependenciesMeta: @@ -4520,8 +4927,8 @@ packages: peerDependencies: vite: ^2 || ^3 || ^4 || ^5 || ^6 || ^7 - vite@5.4.19: - resolution: {integrity: sha512-qO3aKv3HoQC8QKiNSTuUM1l9o/XX3+c+VTgLHbJWHZGeTPVAg2XwazI9UWzoxjIJCGCV2zU60uqMzjeLZuULqA==} + vite@5.4.21: + resolution: {integrity: sha512-o5a9xKjbtuhY6Bi5S3+HvbRERmouabWbyUcpXXUA1u+GNUKoROi9byOJ8M0nHbHYHkYICiMlqxkg1KkYmm25Sw==} engines: {node: ^18.0.0 || >=20.0.0} hasBin: true peerDependencies: @@ -4579,8 +4986,8 @@ packages: jsdom: optional: true - wagmi@2.16.0: - resolution: {integrity: sha512-zXbYp9bt79A+XkStOiGaf2aDy+3B/vH0aHWP8Fc9dyzElOCXqeAzKTwvyrTGsSOHehHmGzo/KPkfc+e/HerJ5A==} + wagmi@2.19.5: + resolution: {integrity: sha512-RQUfKMv6U+EcSNNGiPbdkDtJwtuFxZWLmvDiQmjjBgkuPulUwDJsKhi7gjynzJdsx2yDqhHCXkKsbbfbIsHfcQ==} peerDependencies: '@tanstack/react-query': '>=5.0.0' react: '>=18' @@ -4614,11 +5021,6 @@ packages: resolution: {integrity: sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==} hasBin: true - which@2.0.2: - resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} - engines: {node: '>= 8'} - hasBin: true - why-is-node-running@2.3.0: resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==} engines: {node: '>=8'} @@ -4650,10 +5052,6 @@ packages: resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} engines: {node: '>=10'} - wrap-ansi@8.1.0: - resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} - engines: {node: '>=12'} - wrappy@1.0.2: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} @@ -4723,11 +5121,6 @@ packages: yallist@3.1.1: resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} - yaml@2.8.0: - resolution: {integrity: sha512-4lLa/EcQCB0cJkyts+FpIRx5G/llPxfP6VQU5KByHEhLxY3IJCH0f0Hy1MHI8sClTvsIb8qwRJ6R/ZdlDJ/leQ==} - engines: {node: '>= 14.6'} - hasBin: true - yargs-parser@18.1.3: resolution: {integrity: sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==} engines: {node: '>=6'} @@ -4759,6 +5152,12 @@ packages: zod@3.22.4: resolution: {integrity: sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==} + zod@3.25.76: + resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==} + + zod@4.2.1: + resolution: {integrity: sha512-0wZ1IRqGGhMP76gLqz8EyfBXKk0J2qo2+H3fi4mcUP/KtTocoX08nmIAHl1Z2kJIZbZee8KOpBCSNPRgauucjw==} + zustand@5.0.0: resolution: {integrity: sha512-LE+VcmbartOPM+auOjCCLQOsQ05zUTp8RkgwRzefUk+2jISdMMFnxvyTjA4YNWr5ZGXYbVsEMZosttuxUBkojQ==} engines: {node: '>=12.20.0'} @@ -4795,6 +5194,24 @@ packages: use-sync-external-store: optional: true + zustand@5.0.9: + resolution: {integrity: sha512-ALBtUj0AfjJt3uNRQoL1tL2tMvj6Gp/6e39dnfT6uzpelGru8v1tPOGBzayOWbPJvujM8JojDk3E1LxeFisBNg==} + 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: '@account-abstraction/contracts@0.8.0': @@ -4804,19 +5221,14 @@ snapshots: '@adraffy/ens-normalize@1.10.1': {} - '@adraffy/ens-normalize@1.11.0': {} + '@adraffy/ens-normalize@1.11.1': {} '@alloc/quick-lru@5.2.0': {} - '@ampproject/remapping@2.3.0': - dependencies: - '@jridgewell/gen-mapping': 0.3.12 - '@jridgewell/trace-mapping': 0.3.29 - '@aws-crypto/crc32@5.2.0': dependencies: '@aws-crypto/util': 5.2.0 - '@aws-sdk/types': 3.840.0 + '@aws-sdk/types': 3.953.0 tslib: 2.8.1 '@aws-crypto/sha256-browser@5.2.0': @@ -4824,21 +5236,21 @@ snapshots: '@aws-crypto/sha256-js': 5.2.0 '@aws-crypto/supports-web-crypto': 5.2.0 '@aws-crypto/util': 5.2.0 - '@aws-sdk/types': 3.840.0 - '@aws-sdk/util-locate-window': 3.804.0 + '@aws-sdk/types': 3.953.0 + '@aws-sdk/util-locate-window': 3.953.0 '@smithy/util-utf8': 2.3.0 tslib: 2.8.1 '@aws-crypto/sha256-js@1.2.2': dependencies: '@aws-crypto/util': 1.2.2 - '@aws-sdk/types': 3.840.0 + '@aws-sdk/types': 3.953.0 tslib: 1.14.1 '@aws-crypto/sha256-js@5.2.0': dependencies: '@aws-crypto/util': 5.2.0 - '@aws-sdk/types': 3.840.0 + '@aws-sdk/types': 3.953.0 tslib: 2.8.1 '@aws-crypto/supports-web-crypto@5.2.0': @@ -4847,391 +5259,407 @@ snapshots: '@aws-crypto/util@1.2.2': dependencies: - '@aws-sdk/types': 3.840.0 + '@aws-sdk/types': 3.953.0 '@aws-sdk/util-utf8-browser': 3.259.0 tslib: 1.14.1 '@aws-crypto/util@5.2.0': dependencies: - '@aws-sdk/types': 3.840.0 + '@aws-sdk/types': 3.953.0 '@smithy/util-utf8': 2.3.0 tslib: 2.8.1 - '@aws-sdk/client-lambda@3.851.0': + '@aws-sdk/client-lambda@3.954.0': dependencies: '@aws-crypto/sha256-browser': 5.2.0 '@aws-crypto/sha256-js': 5.2.0 - '@aws-sdk/core': 3.846.0 - '@aws-sdk/credential-provider-node': 3.848.0 - '@aws-sdk/middleware-host-header': 3.840.0 - '@aws-sdk/middleware-logger': 3.840.0 - '@aws-sdk/middleware-recursion-detection': 3.840.0 - '@aws-sdk/middleware-user-agent': 3.848.0 - '@aws-sdk/region-config-resolver': 3.840.0 - '@aws-sdk/types': 3.840.0 - '@aws-sdk/util-endpoints': 3.848.0 - '@aws-sdk/util-user-agent-browser': 3.840.0 - '@aws-sdk/util-user-agent-node': 3.848.0 - '@smithy/config-resolver': 4.1.4 - '@smithy/core': 3.7.2 - '@smithy/eventstream-serde-browser': 4.0.4 - '@smithy/eventstream-serde-config-resolver': 4.1.2 - '@smithy/eventstream-serde-node': 4.0.4 - '@smithy/fetch-http-handler': 5.1.0 - '@smithy/hash-node': 4.0.4 - '@smithy/invalid-dependency': 4.0.4 - '@smithy/middleware-content-length': 4.0.4 - '@smithy/middleware-endpoint': 4.1.17 - '@smithy/middleware-retry': 4.1.18 - '@smithy/middleware-serde': 4.0.8 - '@smithy/middleware-stack': 4.0.4 - '@smithy/node-config-provider': 4.1.3 - '@smithy/node-http-handler': 4.1.0 - '@smithy/protocol-http': 5.1.2 - '@smithy/smithy-client': 4.4.9 - '@smithy/types': 4.3.1 - '@smithy/url-parser': 4.0.4 - '@smithy/util-base64': 4.0.0 - '@smithy/util-body-length-browser': 4.0.0 - '@smithy/util-body-length-node': 4.0.0 - '@smithy/util-defaults-mode-browser': 4.0.25 - '@smithy/util-defaults-mode-node': 4.0.25 - '@smithy/util-endpoints': 3.0.6 - '@smithy/util-middleware': 4.0.4 - '@smithy/util-retry': 4.0.6 - '@smithy/util-stream': 4.2.3 - '@smithy/util-utf8': 4.0.0 - '@smithy/util-waiter': 4.0.6 + '@aws-sdk/core': 3.954.0 + '@aws-sdk/credential-provider-node': 3.954.0 + '@aws-sdk/middleware-host-header': 3.953.0 + '@aws-sdk/middleware-logger': 3.953.0 + '@aws-sdk/middleware-recursion-detection': 3.953.0 + '@aws-sdk/middleware-user-agent': 3.954.0 + '@aws-sdk/region-config-resolver': 3.953.0 + '@aws-sdk/types': 3.953.0 + '@aws-sdk/util-endpoints': 3.953.0 + '@aws-sdk/util-user-agent-browser': 3.953.0 + '@aws-sdk/util-user-agent-node': 3.954.0 + '@smithy/config-resolver': 4.4.4 + '@smithy/core': 3.19.0 + '@smithy/eventstream-serde-browser': 4.2.6 + '@smithy/eventstream-serde-config-resolver': 4.3.6 + '@smithy/eventstream-serde-node': 4.2.6 + '@smithy/fetch-http-handler': 5.3.7 + '@smithy/hash-node': 4.2.6 + '@smithy/invalid-dependency': 4.2.6 + '@smithy/middleware-content-length': 4.2.6 + '@smithy/middleware-endpoint': 4.4.0 + '@smithy/middleware-retry': 4.4.16 + '@smithy/middleware-serde': 4.2.7 + '@smithy/middleware-stack': 4.2.6 + '@smithy/node-config-provider': 4.3.6 + '@smithy/node-http-handler': 4.4.6 + '@smithy/protocol-http': 5.3.6 + '@smithy/smithy-client': 4.10.1 + '@smithy/types': 4.10.0 + '@smithy/url-parser': 4.2.6 + '@smithy/util-base64': 4.3.0 + '@smithy/util-body-length-browser': 4.2.0 + '@smithy/util-body-length-node': 4.2.1 + '@smithy/util-defaults-mode-browser': 4.3.15 + '@smithy/util-defaults-mode-node': 4.2.18 + '@smithy/util-endpoints': 3.2.6 + '@smithy/util-middleware': 4.2.6 + '@smithy/util-retry': 4.2.6 + '@smithy/util-stream': 4.5.7 + '@smithy/util-utf8': 4.2.0 + '@smithy/util-waiter': 4.2.6 tslib: 2.8.1 transitivePeerDependencies: - aws-crt - '@aws-sdk/client-sso@3.848.0': + '@aws-sdk/client-sso@3.954.0': dependencies: '@aws-crypto/sha256-browser': 5.2.0 '@aws-crypto/sha256-js': 5.2.0 - '@aws-sdk/core': 3.846.0 - '@aws-sdk/middleware-host-header': 3.840.0 - '@aws-sdk/middleware-logger': 3.840.0 - '@aws-sdk/middleware-recursion-detection': 3.840.0 - '@aws-sdk/middleware-user-agent': 3.848.0 - '@aws-sdk/region-config-resolver': 3.840.0 - '@aws-sdk/types': 3.840.0 - '@aws-sdk/util-endpoints': 3.848.0 - '@aws-sdk/util-user-agent-browser': 3.840.0 - '@aws-sdk/util-user-agent-node': 3.848.0 - '@smithy/config-resolver': 4.1.4 - '@smithy/core': 3.7.2 - '@smithy/fetch-http-handler': 5.1.0 - '@smithy/hash-node': 4.0.4 - '@smithy/invalid-dependency': 4.0.4 - '@smithy/middleware-content-length': 4.0.4 - '@smithy/middleware-endpoint': 4.1.17 - '@smithy/middleware-retry': 4.1.18 - '@smithy/middleware-serde': 4.0.8 - '@smithy/middleware-stack': 4.0.4 - '@smithy/node-config-provider': 4.1.3 - '@smithy/node-http-handler': 4.1.0 - '@smithy/protocol-http': 5.1.2 - '@smithy/smithy-client': 4.4.9 - '@smithy/types': 4.3.1 - '@smithy/url-parser': 4.0.4 - '@smithy/util-base64': 4.0.0 - '@smithy/util-body-length-browser': 4.0.0 - '@smithy/util-body-length-node': 4.0.0 - '@smithy/util-defaults-mode-browser': 4.0.25 - '@smithy/util-defaults-mode-node': 4.0.25 - '@smithy/util-endpoints': 3.0.6 - '@smithy/util-middleware': 4.0.4 - '@smithy/util-retry': 4.0.6 - '@smithy/util-utf8': 4.0.0 + '@aws-sdk/core': 3.954.0 + '@aws-sdk/middleware-host-header': 3.953.0 + '@aws-sdk/middleware-logger': 3.953.0 + '@aws-sdk/middleware-recursion-detection': 3.953.0 + '@aws-sdk/middleware-user-agent': 3.954.0 + '@aws-sdk/region-config-resolver': 3.953.0 + '@aws-sdk/types': 3.953.0 + '@aws-sdk/util-endpoints': 3.953.0 + '@aws-sdk/util-user-agent-browser': 3.953.0 + '@aws-sdk/util-user-agent-node': 3.954.0 + '@smithy/config-resolver': 4.4.4 + '@smithy/core': 3.19.0 + '@smithy/fetch-http-handler': 5.3.7 + '@smithy/hash-node': 4.2.6 + '@smithy/invalid-dependency': 4.2.6 + '@smithy/middleware-content-length': 4.2.6 + '@smithy/middleware-endpoint': 4.4.0 + '@smithy/middleware-retry': 4.4.16 + '@smithy/middleware-serde': 4.2.7 + '@smithy/middleware-stack': 4.2.6 + '@smithy/node-config-provider': 4.3.6 + '@smithy/node-http-handler': 4.4.6 + '@smithy/protocol-http': 5.3.6 + '@smithy/smithy-client': 4.10.1 + '@smithy/types': 4.10.0 + '@smithy/url-parser': 4.2.6 + '@smithy/util-base64': 4.3.0 + '@smithy/util-body-length-browser': 4.2.0 + '@smithy/util-body-length-node': 4.2.1 + '@smithy/util-defaults-mode-browser': 4.3.15 + '@smithy/util-defaults-mode-node': 4.2.18 + '@smithy/util-endpoints': 3.2.6 + '@smithy/util-middleware': 4.2.6 + '@smithy/util-retry': 4.2.6 + '@smithy/util-utf8': 4.2.0 tslib: 2.8.1 transitivePeerDependencies: - aws-crt - '@aws-sdk/core@3.846.0': - dependencies: - '@aws-sdk/types': 3.840.0 - '@aws-sdk/xml-builder': 3.821.0 - '@smithy/core': 3.7.2 - '@smithy/node-config-provider': 4.1.3 - '@smithy/property-provider': 4.0.4 - '@smithy/protocol-http': 5.1.2 - '@smithy/signature-v4': 5.1.2 - '@smithy/smithy-client': 4.4.9 - '@smithy/types': 4.3.1 - '@smithy/util-base64': 4.0.0 - '@smithy/util-body-length-browser': 4.0.0 - '@smithy/util-middleware': 4.0.4 - '@smithy/util-utf8': 4.0.0 - fast-xml-parser: 5.2.5 + '@aws-sdk/core@3.954.0': + dependencies: + '@aws-sdk/types': 3.953.0 + '@aws-sdk/xml-builder': 3.953.0 + '@smithy/core': 3.19.0 + '@smithy/node-config-provider': 4.3.6 + '@smithy/property-provider': 4.2.6 + '@smithy/protocol-http': 5.3.6 + '@smithy/signature-v4': 5.3.6 + '@smithy/smithy-client': 4.10.1 + '@smithy/types': 4.10.0 + '@smithy/util-base64': 4.3.0 + '@smithy/util-middleware': 4.2.6 + '@smithy/util-utf8': 4.2.0 tslib: 2.8.1 - '@aws-sdk/credential-provider-env@3.846.0': + '@aws-sdk/credential-provider-env@3.954.0': dependencies: - '@aws-sdk/core': 3.846.0 - '@aws-sdk/types': 3.840.0 - '@smithy/property-provider': 4.0.4 - '@smithy/types': 4.3.1 + '@aws-sdk/core': 3.954.0 + '@aws-sdk/types': 3.953.0 + '@smithy/property-provider': 4.2.6 + '@smithy/types': 4.10.0 + tslib: 2.8.1 + + '@aws-sdk/credential-provider-http@3.954.0': + dependencies: + '@aws-sdk/core': 3.954.0 + '@aws-sdk/types': 3.953.0 + '@smithy/fetch-http-handler': 5.3.7 + '@smithy/node-http-handler': 4.4.6 + '@smithy/property-provider': 4.2.6 + '@smithy/protocol-http': 5.3.6 + '@smithy/smithy-client': 4.10.1 + '@smithy/types': 4.10.0 + '@smithy/util-stream': 4.5.7 tslib: 2.8.1 - '@aws-sdk/credential-provider-http@3.846.0': - dependencies: - '@aws-sdk/core': 3.846.0 - '@aws-sdk/types': 3.840.0 - '@smithy/fetch-http-handler': 5.1.0 - '@smithy/node-http-handler': 4.1.0 - '@smithy/property-provider': 4.0.4 - '@smithy/protocol-http': 5.1.2 - '@smithy/smithy-client': 4.4.9 - '@smithy/types': 4.3.1 - '@smithy/util-stream': 4.2.3 + '@aws-sdk/credential-provider-ini@3.954.0': + dependencies: + '@aws-sdk/core': 3.954.0 + '@aws-sdk/credential-provider-env': 3.954.0 + '@aws-sdk/credential-provider-http': 3.954.0 + '@aws-sdk/credential-provider-login': 3.954.0 + '@aws-sdk/credential-provider-process': 3.954.0 + '@aws-sdk/credential-provider-sso': 3.954.0 + '@aws-sdk/credential-provider-web-identity': 3.954.0 + '@aws-sdk/nested-clients': 3.954.0 + '@aws-sdk/types': 3.953.0 + '@smithy/credential-provider-imds': 4.2.6 + '@smithy/property-provider': 4.2.6 + '@smithy/shared-ini-file-loader': 4.4.1 + '@smithy/types': 4.10.0 tslib: 2.8.1 + transitivePeerDependencies: + - aws-crt - '@aws-sdk/credential-provider-ini@3.848.0': - dependencies: - '@aws-sdk/core': 3.846.0 - '@aws-sdk/credential-provider-env': 3.846.0 - '@aws-sdk/credential-provider-http': 3.846.0 - '@aws-sdk/credential-provider-process': 3.846.0 - '@aws-sdk/credential-provider-sso': 3.848.0 - '@aws-sdk/credential-provider-web-identity': 3.848.0 - '@aws-sdk/nested-clients': 3.848.0 - '@aws-sdk/types': 3.840.0 - '@smithy/credential-provider-imds': 4.0.6 - '@smithy/property-provider': 4.0.4 - '@smithy/shared-ini-file-loader': 4.0.4 - '@smithy/types': 4.3.1 + '@aws-sdk/credential-provider-login@3.954.0': + dependencies: + '@aws-sdk/core': 3.954.0 + '@aws-sdk/nested-clients': 3.954.0 + '@aws-sdk/types': 3.953.0 + '@smithy/property-provider': 4.2.6 + '@smithy/protocol-http': 5.3.6 + '@smithy/shared-ini-file-loader': 4.4.1 + '@smithy/types': 4.10.0 tslib: 2.8.1 transitivePeerDependencies: - aws-crt - '@aws-sdk/credential-provider-node@3.848.0': - dependencies: - '@aws-sdk/credential-provider-env': 3.846.0 - '@aws-sdk/credential-provider-http': 3.846.0 - '@aws-sdk/credential-provider-ini': 3.848.0 - '@aws-sdk/credential-provider-process': 3.846.0 - '@aws-sdk/credential-provider-sso': 3.848.0 - '@aws-sdk/credential-provider-web-identity': 3.848.0 - '@aws-sdk/types': 3.840.0 - '@smithy/credential-provider-imds': 4.0.6 - '@smithy/property-provider': 4.0.4 - '@smithy/shared-ini-file-loader': 4.0.4 - '@smithy/types': 4.3.1 + '@aws-sdk/credential-provider-node@3.954.0': + dependencies: + '@aws-sdk/credential-provider-env': 3.954.0 + '@aws-sdk/credential-provider-http': 3.954.0 + '@aws-sdk/credential-provider-ini': 3.954.0 + '@aws-sdk/credential-provider-process': 3.954.0 + '@aws-sdk/credential-provider-sso': 3.954.0 + '@aws-sdk/credential-provider-web-identity': 3.954.0 + '@aws-sdk/types': 3.953.0 + '@smithy/credential-provider-imds': 4.2.6 + '@smithy/property-provider': 4.2.6 + '@smithy/shared-ini-file-loader': 4.4.1 + '@smithy/types': 4.10.0 tslib: 2.8.1 transitivePeerDependencies: - aws-crt - '@aws-sdk/credential-provider-process@3.846.0': + '@aws-sdk/credential-provider-process@3.954.0': dependencies: - '@aws-sdk/core': 3.846.0 - '@aws-sdk/types': 3.840.0 - '@smithy/property-provider': 4.0.4 - '@smithy/shared-ini-file-loader': 4.0.4 - '@smithy/types': 4.3.1 + '@aws-sdk/core': 3.954.0 + '@aws-sdk/types': 3.953.0 + '@smithy/property-provider': 4.2.6 + '@smithy/shared-ini-file-loader': 4.4.1 + '@smithy/types': 4.10.0 tslib: 2.8.1 - '@aws-sdk/credential-provider-sso@3.848.0': + '@aws-sdk/credential-provider-sso@3.954.0': dependencies: - '@aws-sdk/client-sso': 3.848.0 - '@aws-sdk/core': 3.846.0 - '@aws-sdk/token-providers': 3.848.0 - '@aws-sdk/types': 3.840.0 - '@smithy/property-provider': 4.0.4 - '@smithy/shared-ini-file-loader': 4.0.4 - '@smithy/types': 4.3.1 + '@aws-sdk/client-sso': 3.954.0 + '@aws-sdk/core': 3.954.0 + '@aws-sdk/token-providers': 3.954.0 + '@aws-sdk/types': 3.953.0 + '@smithy/property-provider': 4.2.6 + '@smithy/shared-ini-file-loader': 4.4.1 + '@smithy/types': 4.10.0 tslib: 2.8.1 transitivePeerDependencies: - aws-crt - '@aws-sdk/credential-provider-web-identity@3.848.0': + '@aws-sdk/credential-provider-web-identity@3.954.0': dependencies: - '@aws-sdk/core': 3.846.0 - '@aws-sdk/nested-clients': 3.848.0 - '@aws-sdk/types': 3.840.0 - '@smithy/property-provider': 4.0.4 - '@smithy/types': 4.3.1 + '@aws-sdk/core': 3.954.0 + '@aws-sdk/nested-clients': 3.954.0 + '@aws-sdk/types': 3.953.0 + '@smithy/property-provider': 4.2.6 + '@smithy/shared-ini-file-loader': 4.4.1 + '@smithy/types': 4.10.0 tslib: 2.8.1 transitivePeerDependencies: - aws-crt - '@aws-sdk/middleware-host-header@3.840.0': + '@aws-sdk/middleware-host-header@3.953.0': dependencies: - '@aws-sdk/types': 3.840.0 - '@smithy/protocol-http': 5.1.2 - '@smithy/types': 4.3.1 + '@aws-sdk/types': 3.953.0 + '@smithy/protocol-http': 5.3.6 + '@smithy/types': 4.10.0 tslib: 2.8.1 - '@aws-sdk/middleware-logger@3.840.0': + '@aws-sdk/middleware-logger@3.953.0': dependencies: - '@aws-sdk/types': 3.840.0 - '@smithy/types': 4.3.1 + '@aws-sdk/types': 3.953.0 + '@smithy/types': 4.10.0 tslib: 2.8.1 - '@aws-sdk/middleware-recursion-detection@3.840.0': + '@aws-sdk/middleware-recursion-detection@3.953.0': dependencies: - '@aws-sdk/types': 3.840.0 - '@smithy/protocol-http': 5.1.2 - '@smithy/types': 4.3.1 + '@aws-sdk/types': 3.953.0 + '@aws/lambda-invoke-store': 0.2.2 + '@smithy/protocol-http': 5.3.6 + '@smithy/types': 4.10.0 tslib: 2.8.1 - '@aws-sdk/middleware-user-agent@3.848.0': + '@aws-sdk/middleware-user-agent@3.954.0': dependencies: - '@aws-sdk/core': 3.846.0 - '@aws-sdk/types': 3.840.0 - '@aws-sdk/util-endpoints': 3.848.0 - '@smithy/core': 3.7.2 - '@smithy/protocol-http': 5.1.2 - '@smithy/types': 4.3.1 + '@aws-sdk/core': 3.954.0 + '@aws-sdk/types': 3.953.0 + '@aws-sdk/util-endpoints': 3.953.0 + '@smithy/core': 3.19.0 + '@smithy/protocol-http': 5.3.6 + '@smithy/types': 4.10.0 tslib: 2.8.1 - '@aws-sdk/nested-clients@3.848.0': + '@aws-sdk/nested-clients@3.954.0': dependencies: '@aws-crypto/sha256-browser': 5.2.0 '@aws-crypto/sha256-js': 5.2.0 - '@aws-sdk/core': 3.846.0 - '@aws-sdk/middleware-host-header': 3.840.0 - '@aws-sdk/middleware-logger': 3.840.0 - '@aws-sdk/middleware-recursion-detection': 3.840.0 - '@aws-sdk/middleware-user-agent': 3.848.0 - '@aws-sdk/region-config-resolver': 3.840.0 - '@aws-sdk/types': 3.840.0 - '@aws-sdk/util-endpoints': 3.848.0 - '@aws-sdk/util-user-agent-browser': 3.840.0 - '@aws-sdk/util-user-agent-node': 3.848.0 - '@smithy/config-resolver': 4.1.4 - '@smithy/core': 3.7.2 - '@smithy/fetch-http-handler': 5.1.0 - '@smithy/hash-node': 4.0.4 - '@smithy/invalid-dependency': 4.0.4 - '@smithy/middleware-content-length': 4.0.4 - '@smithy/middleware-endpoint': 4.1.17 - '@smithy/middleware-retry': 4.1.18 - '@smithy/middleware-serde': 4.0.8 - '@smithy/middleware-stack': 4.0.4 - '@smithy/node-config-provider': 4.1.3 - '@smithy/node-http-handler': 4.1.0 - '@smithy/protocol-http': 5.1.2 - '@smithy/smithy-client': 4.4.9 - '@smithy/types': 4.3.1 - '@smithy/url-parser': 4.0.4 - '@smithy/util-base64': 4.0.0 - '@smithy/util-body-length-browser': 4.0.0 - '@smithy/util-body-length-node': 4.0.0 - '@smithy/util-defaults-mode-browser': 4.0.25 - '@smithy/util-defaults-mode-node': 4.0.25 - '@smithy/util-endpoints': 3.0.6 - '@smithy/util-middleware': 4.0.4 - '@smithy/util-retry': 4.0.6 - '@smithy/util-utf8': 4.0.0 + '@aws-sdk/core': 3.954.0 + '@aws-sdk/middleware-host-header': 3.953.0 + '@aws-sdk/middleware-logger': 3.953.0 + '@aws-sdk/middleware-recursion-detection': 3.953.0 + '@aws-sdk/middleware-user-agent': 3.954.0 + '@aws-sdk/region-config-resolver': 3.953.0 + '@aws-sdk/types': 3.953.0 + '@aws-sdk/util-endpoints': 3.953.0 + '@aws-sdk/util-user-agent-browser': 3.953.0 + '@aws-sdk/util-user-agent-node': 3.954.0 + '@smithy/config-resolver': 4.4.4 + '@smithy/core': 3.19.0 + '@smithy/fetch-http-handler': 5.3.7 + '@smithy/hash-node': 4.2.6 + '@smithy/invalid-dependency': 4.2.6 + '@smithy/middleware-content-length': 4.2.6 + '@smithy/middleware-endpoint': 4.4.0 + '@smithy/middleware-retry': 4.4.16 + '@smithy/middleware-serde': 4.2.7 + '@smithy/middleware-stack': 4.2.6 + '@smithy/node-config-provider': 4.3.6 + '@smithy/node-http-handler': 4.4.6 + '@smithy/protocol-http': 5.3.6 + '@smithy/smithy-client': 4.10.1 + '@smithy/types': 4.10.0 + '@smithy/url-parser': 4.2.6 + '@smithy/util-base64': 4.3.0 + '@smithy/util-body-length-browser': 4.2.0 + '@smithy/util-body-length-node': 4.2.1 + '@smithy/util-defaults-mode-browser': 4.3.15 + '@smithy/util-defaults-mode-node': 4.2.18 + '@smithy/util-endpoints': 3.2.6 + '@smithy/util-middleware': 4.2.6 + '@smithy/util-retry': 4.2.6 + '@smithy/util-utf8': 4.2.0 tslib: 2.8.1 transitivePeerDependencies: - aws-crt - '@aws-sdk/region-config-resolver@3.840.0': + '@aws-sdk/region-config-resolver@3.953.0': dependencies: - '@aws-sdk/types': 3.840.0 - '@smithy/node-config-provider': 4.1.3 - '@smithy/types': 4.3.1 - '@smithy/util-config-provider': 4.0.0 - '@smithy/util-middleware': 4.0.4 + '@aws-sdk/types': 3.953.0 + '@smithy/config-resolver': 4.4.4 + '@smithy/node-config-provider': 4.3.6 + '@smithy/types': 4.10.0 tslib: 2.8.1 - '@aws-sdk/token-providers@3.848.0': + '@aws-sdk/token-providers@3.954.0': dependencies: - '@aws-sdk/core': 3.846.0 - '@aws-sdk/nested-clients': 3.848.0 - '@aws-sdk/types': 3.840.0 - '@smithy/property-provider': 4.0.4 - '@smithy/shared-ini-file-loader': 4.0.4 - '@smithy/types': 4.3.1 + '@aws-sdk/core': 3.954.0 + '@aws-sdk/nested-clients': 3.954.0 + '@aws-sdk/types': 3.953.0 + '@smithy/property-provider': 4.2.6 + '@smithy/shared-ini-file-loader': 4.4.1 + '@smithy/types': 4.10.0 tslib: 2.8.1 transitivePeerDependencies: - aws-crt - '@aws-sdk/types@3.840.0': + '@aws-sdk/types@3.953.0': dependencies: - '@smithy/types': 4.3.1 + '@smithy/types': 4.10.0 tslib: 2.8.1 - '@aws-sdk/util-endpoints@3.848.0': + '@aws-sdk/util-endpoints@3.953.0': dependencies: - '@aws-sdk/types': 3.840.0 - '@smithy/types': 4.3.1 - '@smithy/url-parser': 4.0.4 - '@smithy/util-endpoints': 3.0.6 + '@aws-sdk/types': 3.953.0 + '@smithy/types': 4.10.0 + '@smithy/url-parser': 4.2.6 + '@smithy/util-endpoints': 3.2.6 tslib: 2.8.1 - '@aws-sdk/util-locate-window@3.804.0': + '@aws-sdk/util-locate-window@3.953.0': dependencies: tslib: 2.8.1 - '@aws-sdk/util-user-agent-browser@3.840.0': + '@aws-sdk/util-user-agent-browser@3.953.0': dependencies: - '@aws-sdk/types': 3.840.0 - '@smithy/types': 4.3.1 - bowser: 2.11.0 + '@aws-sdk/types': 3.953.0 + '@smithy/types': 4.10.0 + bowser: 2.13.1 tslib: 2.8.1 - '@aws-sdk/util-user-agent-node@3.848.0': + '@aws-sdk/util-user-agent-node@3.954.0': dependencies: - '@aws-sdk/middleware-user-agent': 3.848.0 - '@aws-sdk/types': 3.840.0 - '@smithy/node-config-provider': 4.1.3 - '@smithy/types': 4.3.1 + '@aws-sdk/middleware-user-agent': 3.954.0 + '@aws-sdk/types': 3.953.0 + '@smithy/node-config-provider': 4.3.6 + '@smithy/types': 4.10.0 tslib: 2.8.1 '@aws-sdk/util-utf8-browser@3.259.0': dependencies: tslib: 2.8.1 - '@aws-sdk/xml-builder@3.821.0': + '@aws-sdk/xml-builder@3.953.0': dependencies: - '@smithy/types': 4.3.1 + '@smithy/types': 4.10.0 + fast-xml-parser: 5.2.5 tslib: 2.8.1 + '@aws/lambda-invoke-store@0.2.2': {} + '@babel/code-frame@7.27.1': dependencies: - '@babel/helper-validator-identifier': 7.27.1 + '@babel/helper-validator-identifier': 7.28.5 js-tokens: 4.0.0 picocolors: 1.1.1 - '@babel/compat-data@7.28.0': {} + '@babel/compat-data@7.28.5': {} - '@babel/core@7.28.0': + '@babel/core@7.28.5': dependencies: - '@ampproject/remapping': 2.3.0 '@babel/code-frame': 7.27.1 - '@babel/generator': 7.28.0 + '@babel/generator': 7.28.5 '@babel/helper-compilation-targets': 7.27.2 - '@babel/helper-module-transforms': 7.27.3(@babel/core@7.28.0) - '@babel/helpers': 7.28.2 - '@babel/parser': 7.28.0 + '@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.5) + '@babel/helpers': 7.28.4 + '@babel/parser': 7.28.5 '@babel/template': 7.27.2 - '@babel/traverse': 7.28.0 - '@babel/types': 7.28.2 + '@babel/traverse': 7.28.5 + '@babel/types': 7.28.5 + '@jridgewell/remapping': 2.3.5 convert-source-map: 2.0.0 - debug: 4.4.1(supports-color@8.1.1) + debug: 4.4.3(supports-color@8.1.1) gensync: 1.0.0-beta.2 json5: 2.2.3 semver: 6.3.1 transitivePeerDependencies: - supports-color - '@babel/generator@7.28.0': + '@babel/generator@7.28.5': dependencies: - '@babel/parser': 7.28.0 - '@babel/types': 7.28.2 - '@jridgewell/gen-mapping': 0.3.12 - '@jridgewell/trace-mapping': 0.3.29 + '@babel/parser': 7.28.5 + '@babel/types': 7.28.5 + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 jsesc: 3.1.0 '@babel/helper-compilation-targets@7.27.2': dependencies: - '@babel/compat-data': 7.28.0 + '@babel/compat-data': 7.28.5 '@babel/helper-validator-option': 7.27.1 - browserslist: 4.25.1 + browserslist: 4.28.1 lru-cache: 5.1.1 semver: 6.3.1 @@ -5239,17 +5667,17 @@ snapshots: '@babel/helper-module-imports@7.27.1': dependencies: - '@babel/traverse': 7.28.0 - '@babel/types': 7.28.2 + '@babel/traverse': 7.28.5 + '@babel/types': 7.28.5 transitivePeerDependencies: - supports-color - '@babel/helper-module-transforms@7.27.3(@babel/core@7.28.0)': + '@babel/helper-module-transforms@7.28.3(@babel/core@7.28.5)': dependencies: - '@babel/core': 7.28.0 + '@babel/core': 7.28.5 '@babel/helper-module-imports': 7.27.1 - '@babel/helper-validator-identifier': 7.27.1 - '@babel/traverse': 7.28.0 + '@babel/helper-validator-identifier': 7.28.5 + '@babel/traverse': 7.28.5 transitivePeerDependencies: - supports-color @@ -5257,78 +5685,104 @@ snapshots: '@babel/helper-string-parser@7.27.1': {} - '@babel/helper-validator-identifier@7.27.1': {} + '@babel/helper-validator-identifier@7.28.5': {} '@babel/helper-validator-option@7.27.1': {} - '@babel/helpers@7.28.2': + '@babel/helpers@7.28.4': dependencies: '@babel/template': 7.27.2 - '@babel/types': 7.28.2 + '@babel/types': 7.28.5 - '@babel/parser@7.28.0': + '@babel/parser@7.28.5': dependencies: - '@babel/types': 7.28.2 + '@babel/types': 7.28.5 - '@babel/plugin-transform-react-jsx-self@7.27.1(@babel/core@7.28.0)': + '@babel/plugin-transform-react-jsx-self@7.27.1(@babel/core@7.28.5)': dependencies: - '@babel/core': 7.28.0 + '@babel/core': 7.28.5 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-react-jsx-source@7.27.1(@babel/core@7.28.0)': + '@babel/plugin-transform-react-jsx-source@7.27.1(@babel/core@7.28.5)': dependencies: - '@babel/core': 7.28.0 + '@babel/core': 7.28.5 '@babel/helper-plugin-utils': 7.27.1 - '@babel/runtime@7.28.2': {} + '@babel/runtime@7.28.4': {} '@babel/template@7.27.2': dependencies: '@babel/code-frame': 7.27.1 - '@babel/parser': 7.28.0 - '@babel/types': 7.28.2 + '@babel/parser': 7.28.5 + '@babel/types': 7.28.5 - '@babel/traverse@7.28.0': + '@babel/traverse@7.28.5': dependencies: '@babel/code-frame': 7.27.1 - '@babel/generator': 7.28.0 + '@babel/generator': 7.28.5 '@babel/helper-globals': 7.28.0 - '@babel/parser': 7.28.0 + '@babel/parser': 7.28.5 '@babel/template': 7.27.2 - '@babel/types': 7.28.2 - debug: 4.4.1(supports-color@8.1.1) + '@babel/types': 7.28.5 + debug: 4.4.3(supports-color@8.1.1) transitivePeerDependencies: - supports-color - '@babel/types@7.28.2': + '@babel/types@7.28.5': dependencies: '@babel/helper-string-parser': 7.27.1 - '@babel/helper-validator-identifier': 7.27.1 + '@babel/helper-validator-identifier': 7.28.5 - '@base-org/account@1.0.2(@types/react@18.3.23)(bufferutil@4.0.9)(immer@10.0.2)(react@18.3.1)(typescript@5.8.3)(use-sync-external-store@1.4.0(react@18.3.1))(utf-8-validate@5.0.10)(wagmi@2.16.0(@tanstack/query-core@5.83.0)(@tanstack/react-query@5.83.0(react@18.3.1))(@types/react@18.3.23)(bufferutil@4.0.9)(immer@10.0.2)(react@18.3.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(viem@2.37.5(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4))(zod@3.22.4))(zod@3.22.4)': + '@base-org/account@2.4.0(@types/react@18.3.27)(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(immer@10.0.2)(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)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@4.2.1)': dependencies: + '@coinbase/cdp-sdk': 1.40.1(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.18.0(bufferutil@4.0.9)(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.8.3)(zod@3.22.4) + ox: 0.6.9(typescript@5.9.3)(zod@4.2.1) preact: 10.24.2 - viem: 2.37.5(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) - zustand: 5.0.3(@types/react@18.3.23)(immer@10.0.2)(react@18.3.1)(use-sync-external-store@1.4.0(react@18.3.1)) - optionalDependencies: - wagmi: 2.16.0(@tanstack/query-core@5.83.0)(@tanstack/react-query@5.83.0(react@18.3.1))(@types/react@18.3.23)(bufferutil@4.0.9)(immer@10.0.2)(react@18.3.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(viem@2.37.5(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4))(zod@3.22.4) + viem: 2.43.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) + zustand: 5.0.3(@types/react@18.3.27)(immer@10.0.2)(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 + - ws - zod '@bytecodealliance/preview2-shim@0.17.0': {} + '@coinbase/cdp-sdk@1.40.1(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))': + dependencies: + '@solana-program/system': 0.8.1(@solana/kit@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))) + '@solana-program/token': 0.6.0(@solana/kit@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))) + '@solana/kit': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@solana/web3.js': 1.98.4(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10) + abitype: 1.0.6(typescript@5.9.3)(zod@3.25.76) + axios: 1.13.2(debug@4.4.3) + axios-retry: 4.5.0(axios@1.13.2) + jose: 6.1.3 + md5: 2.3.0 + uncrypto: 0.1.3 + viem: 2.43.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + zod: 3.25.76 + transitivePeerDependencies: + - bufferutil + - debug + - encoding + - fastestsmallesttextencoderdecoder + - typescript + - utf-8-validate + - ws + '@coinbase/wallet-sdk@3.9.3': dependencies: bn.js: 5.2.2 @@ -5338,21 +5792,21 @@ snapshots: eth-json-rpc-filters: 6.0.1 eventemitter3: 5.0.1 keccak: 3.0.4 - preact: 10.26.9 + preact: 10.28.0 sha.js: 2.4.12 transitivePeerDependencies: - supports-color - '@coinbase/wallet-sdk@4.3.6(@types/react@18.3.23)(bufferutil@4.0.9)(immer@10.0.2)(react@18.3.1)(typescript@5.8.3)(use-sync-external-store@1.4.0(react@18.3.1))(utf-8-validate@5.0.10)(zod@3.22.4)': + '@coinbase/wallet-sdk@4.3.6(@types/react@18.3.27)(bufferutil@4.0.9)(immer@10.0.2)(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.2.1)': dependencies: '@noble/hashes': 1.4.0 clsx: 1.2.1 eventemitter3: 5.0.1 idb-keyval: 6.2.1 - ox: 0.6.9(typescript@5.8.3)(zod@3.22.4) + ox: 0.6.9(typescript@5.9.3)(zod@4.2.1) preact: 10.24.2 - viem: 2.37.5(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) - zustand: 5.0.3(@types/react@18.3.23)(immer@10.0.2)(react@18.3.1)(use-sync-external-store@1.4.0(react@18.3.1)) + viem: 2.43.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) + zustand: 5.0.3(@types/react@18.3.27)(immer@10.0.2)(react@18.3.1)(use-sync-external-store@1.4.0(react@18.3.1)) transitivePeerDependencies: - '@types/react' - bufferutil @@ -5367,7 +5821,7 @@ snapshots: dependencies: '@jridgewell/trace-mapping': 0.3.9 - '@ecies/ciphers@0.2.4(@noble/ciphers@1.3.0)': + '@ecies/ciphers@0.2.5(@noble/ciphers@1.3.0)': dependencies: '@noble/ciphers': 1.3.0 @@ -5734,39 +6188,43 @@ snapshots: '@fastify/busboy@2.1.1': {} + '@gemini-wallet/core@0.3.2(viem@2.43.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1))': + dependencies: + '@metamask/rpc-errors': 7.0.2 + eventemitter3: 5.0.1 + viem: 2.43.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) + transitivePeerDependencies: + - supports-color + '@isaacs/balanced-match@4.0.1': {} '@isaacs/brace-expansion@5.0.0': dependencies: '@isaacs/balanced-match': 4.0.1 - '@isaacs/cliui@8.0.2': + '@jridgewell/gen-mapping@0.3.13': dependencies: - string-width: 5.1.2 - string-width-cjs: string-width@4.2.3 - strip-ansi: 7.1.0 - strip-ansi-cjs: strip-ansi@6.0.1 - wrap-ansi: 8.1.0 - wrap-ansi-cjs: wrap-ansi@7.0.0 + '@jridgewell/sourcemap-codec': 1.5.5 + '@jridgewell/trace-mapping': 0.3.31 - '@jridgewell/gen-mapping@0.3.12': + '@jridgewell/remapping@2.3.5': dependencies: - '@jridgewell/sourcemap-codec': 1.5.4 - '@jridgewell/trace-mapping': 0.3.29 + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 '@jridgewell/resolve-uri@3.1.2': {} - '@jridgewell/sourcemap-codec@1.5.4': {} + '@jridgewell/sourcemap-codec@1.5.5': {} - '@jridgewell/trace-mapping@0.3.29': + '@jridgewell/trace-mapping@0.3.31': dependencies: '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.5.4 + '@jridgewell/sourcemap-codec': 1.5.5 '@jridgewell/trace-mapping@0.3.9': dependencies: '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.5.4 + '@jridgewell/sourcemap-codec': 1.5.5 '@lit-labs/ssr-dom-shim@1.4.0': {} @@ -5814,7 +6272,7 @@ snapshots: '@metamask/onboarding@1.0.1': dependencies: - bowser: 2.11.0 + bowser: 2.13.1 '@metamask/providers@16.1.0': dependencies: @@ -5840,17 +6298,29 @@ snapshots: transitivePeerDependencies: - supports-color + '@metamask/rpc-errors@7.0.2': + dependencies: + '@metamask/utils': 11.9.0 + fast-safe-stringify: 2.1.1 + transitivePeerDependencies: + - supports-color + '@metamask/safe-event-emitter@2.0.0': {} '@metamask/safe-event-emitter@3.1.2': {} - '@metamask/sdk-communication-layer@0.32.0(cross-fetch@4.1.0)(eciesjs@0.4.15)(eventemitter2@6.4.9)(readable-stream@3.6.2)(socket.io-client@4.8.1(bufferutil@4.0.9)(utf-8-validate@5.0.10))': + '@metamask/sdk-analytics@0.0.5': dependencies: + openapi-fetch: 0.13.8 + + '@metamask/sdk-communication-layer@0.33.1(cross-fetch@4.1.0)(eciesjs@0.4.16)(eventemitter2@6.4.9)(readable-stream@3.6.2)(socket.io-client@4.8.1(bufferutil@4.0.9)(utf-8-validate@5.0.10))': + dependencies: + '@metamask/sdk-analytics': 0.0.5 bufferutil: 4.0.9 cross-fetch: 4.1.0 date-fns: 2.30.0 - debug: 4.4.1(supports-color@8.1.1) - eciesjs: 0.4.15 + debug: 4.3.4 + eciesjs: 0.4.16 eventemitter2: 6.4.9 readable-stream: 3.6.2 socket.io-client: 4.8.1(bufferutil@4.0.9)(utf-8-validate@5.0.10) @@ -5859,22 +6329,23 @@ snapshots: transitivePeerDependencies: - supports-color - '@metamask/sdk-install-modal-web@0.32.0': + '@metamask/sdk-install-modal-web@0.32.1': dependencies: '@paulmillr/qr': 0.2.1 - '@metamask/sdk@0.32.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)': + '@metamask/sdk@0.33.1(bufferutil@4.0.9)(utf-8-validate@5.0.10)': dependencies: - '@babel/runtime': 7.28.2 + '@babel/runtime': 7.28.4 '@metamask/onboarding': 1.0.1 '@metamask/providers': 16.1.0 - '@metamask/sdk-communication-layer': 0.32.0(cross-fetch@4.1.0)(eciesjs@0.4.15)(eventemitter2@6.4.9)(readable-stream@3.6.2)(socket.io-client@4.8.1(bufferutil@4.0.9)(utf-8-validate@5.0.10)) - '@metamask/sdk-install-modal-web': 0.32.0 + '@metamask/sdk-analytics': 0.0.5 + '@metamask/sdk-communication-layer': 0.33.1(cross-fetch@4.1.0)(eciesjs@0.4.16)(eventemitter2@6.4.9)(readable-stream@3.6.2)(socket.io-client@4.8.1(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@metamask/sdk-install-modal-web': 0.32.1 '@paulmillr/qr': 0.2.1 - bowser: 2.11.0 + bowser: 2.13.1 cross-fetch: 4.1.0 - debug: 4.4.1(supports-color@8.1.1) - eciesjs: 0.4.15 + debug: 4.3.4 + eciesjs: 0.4.16 eth-rpc-errors: 4.0.3 eventemitter2: 6.4.9 obj-multiplex: 1.0.0 @@ -5892,12 +6363,28 @@ snapshots: '@metamask/superstruct@3.2.1': {} + '@metamask/utils@11.9.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.21 + debug: 4.4.3(supports-color@8.1.1) + lodash: 4.17.21 + pony-cause: 2.1.11 + semver: 7.7.3 + uuid: 9.0.1 + transitivePeerDependencies: + - supports-color + '@metamask/utils@5.0.2': dependencies: '@ethereumjs/tx': 4.2.0 '@types/debug': 4.1.12 - debug: 4.4.1(supports-color@8.1.1) - semver: 7.7.2 + debug: 4.4.3(supports-color@8.1.1) + semver: 7.7.3 superstruct: 1.0.4 transitivePeerDependencies: - supports-color @@ -5909,9 +6396,9 @@ snapshots: '@noble/hashes': 1.8.0 '@scure/base': 1.2.6 '@types/debug': 4.1.12 - debug: 4.4.1(supports-color@8.1.1) + debug: 4.3.4 pony-cause: 2.1.11 - semver: 7.7.2 + semver: 7.7.3 uuid: 9.0.1 transitivePeerDependencies: - supports-color @@ -5923,9 +6410,9 @@ snapshots: '@noble/hashes': 1.8.0 '@scure/base': 1.2.6 '@types/debug': 4.1.12 - debug: 4.4.1(supports-color@8.1.1) + debug: 4.3.4 pony-cause: 2.1.11 - semver: 7.7.2 + semver: 7.7.3 uuid: 9.0.1 transitivePeerDependencies: - supports-color @@ -5958,7 +6445,7 @@ snapshots: dependencies: '@noble/hashes': 1.8.0 - '@noble/curves@1.9.4': + '@noble/curves@1.9.7': dependencies: '@noble/hashes': 1.8.0 @@ -5992,67 +6479,67 @@ snapshots: '@nodelib/fs.scandir': 2.1.5 fastq: 1.19.1 - '@nomicfoundation/edr-darwin-arm64@0.11.3': {} + '@nomicfoundation/edr-darwin-arm64@0.12.0-next.17': {} - '@nomicfoundation/edr-darwin-x64@0.11.3': {} + '@nomicfoundation/edr-darwin-x64@0.12.0-next.17': {} - '@nomicfoundation/edr-linux-arm64-gnu@0.11.3': {} + '@nomicfoundation/edr-linux-arm64-gnu@0.12.0-next.17': {} - '@nomicfoundation/edr-linux-arm64-musl@0.11.3': {} + '@nomicfoundation/edr-linux-arm64-musl@0.12.0-next.17': {} - '@nomicfoundation/edr-linux-x64-gnu@0.11.3': {} + '@nomicfoundation/edr-linux-x64-gnu@0.12.0-next.17': {} - '@nomicfoundation/edr-linux-x64-musl@0.11.3': {} + '@nomicfoundation/edr-linux-x64-musl@0.12.0-next.17': {} - '@nomicfoundation/edr-win32-x64-msvc@0.11.3': {} + '@nomicfoundation/edr-win32-x64-msvc@0.12.0-next.17': {} - '@nomicfoundation/edr@0.11.3': + '@nomicfoundation/edr@0.12.0-next.17': dependencies: - '@nomicfoundation/edr-darwin-arm64': 0.11.3 - '@nomicfoundation/edr-darwin-x64': 0.11.3 - '@nomicfoundation/edr-linux-arm64-gnu': 0.11.3 - '@nomicfoundation/edr-linux-arm64-musl': 0.11.3 - '@nomicfoundation/edr-linux-x64-gnu': 0.11.3 - '@nomicfoundation/edr-linux-x64-musl': 0.11.3 - '@nomicfoundation/edr-win32-x64-msvc': 0.11.3 + '@nomicfoundation/edr-darwin-arm64': 0.12.0-next.17 + '@nomicfoundation/edr-darwin-x64': 0.12.0-next.17 + '@nomicfoundation/edr-linux-arm64-gnu': 0.12.0-next.17 + '@nomicfoundation/edr-linux-arm64-musl': 0.12.0-next.17 + '@nomicfoundation/edr-linux-x64-gnu': 0.12.0-next.17 + '@nomicfoundation/edr-linux-x64-musl': 0.12.0-next.17 + '@nomicfoundation/edr-win32-x64-msvc': 0.12.0-next.17 - '@nomicfoundation/hardhat-chai-matchers@2.1.0(@nomicfoundation/hardhat-ethers@3.1.0(ethers@6.15.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(hardhat@2.26.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.8.3))(typescript@5.8.3)(utf-8-validate@5.0.10)))(chai@4.5.0)(ethers@6.15.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(hardhat@2.26.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.8.3))(typescript@5.8.3)(utf-8-validate@5.0.10))': + '@nomicfoundation/hardhat-chai-matchers@2.1.0(@nomicfoundation/hardhat-ethers@3.1.3(ethers@6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10)))(chai@4.5.0)(ethers@6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10))': dependencies: - '@nomicfoundation/hardhat-ethers': 3.1.0(ethers@6.15.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(hardhat@2.26.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.8.3))(typescript@5.8.3)(utf-8-validate@5.0.10)) + '@nomicfoundation/hardhat-ethers': 3.1.3(ethers@6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10)) '@types/chai-as-promised': 7.1.8 chai: 4.5.0 chai-as-promised: 7.1.2(chai@4.5.0) deep-eql: 4.1.4 - ethers: 6.15.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) - hardhat: 2.26.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.8.3))(typescript@5.8.3)(utf-8-validate@5.0.10) + ethers: 6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + hardhat: 2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10) ordinal: 1.0.3 - '@nomicfoundation/hardhat-ethers@3.1.0(ethers@6.15.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(hardhat@2.26.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.8.3))(typescript@5.8.3)(utf-8-validate@5.0.10))': + '@nomicfoundation/hardhat-ethers@3.1.3(ethers@6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10))': dependencies: - debug: 4.4.1(supports-color@8.1.1) - ethers: 6.15.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) - hardhat: 2.26.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.8.3))(typescript@5.8.3)(utf-8-validate@5.0.10) + debug: 4.4.3(supports-color@8.1.1) + ethers: 6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + hardhat: 2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10) lodash.isequal: 4.5.0 transitivePeerDependencies: - supports-color - '@nomicfoundation/hardhat-ignition-ethers@0.15.14(@nomicfoundation/hardhat-ethers@3.1.0(ethers@6.15.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(hardhat@2.26.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.8.3))(typescript@5.8.3)(utf-8-validate@5.0.10)))(@nomicfoundation/hardhat-ignition@0.15.13(@nomicfoundation/hardhat-verify@2.1.0(hardhat@2.26.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.8.3))(typescript@5.8.3)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(hardhat@2.26.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.8.3))(typescript@5.8.3)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10))(@nomicfoundation/ignition-core@0.15.13(bufferutil@4.0.9)(utf-8-validate@5.0.10))(ethers@6.15.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(hardhat@2.26.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.8.3))(typescript@5.8.3)(utf-8-validate@5.0.10))': + '@nomicfoundation/hardhat-ignition-ethers@0.15.17(@nomicfoundation/hardhat-ethers@3.1.3(ethers@6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10)))(@nomicfoundation/hardhat-ignition@0.15.16(@nomicfoundation/hardhat-verify@2.1.3(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10))(@nomicfoundation/ignition-core@0.15.15(bufferutil@4.0.9)(utf-8-validate@5.0.10))(ethers@6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10))': dependencies: - '@nomicfoundation/hardhat-ethers': 3.1.0(ethers@6.15.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(hardhat@2.26.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.8.3))(typescript@5.8.3)(utf-8-validate@5.0.10)) - '@nomicfoundation/hardhat-ignition': 0.15.13(@nomicfoundation/hardhat-verify@2.1.0(hardhat@2.26.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.8.3))(typescript@5.8.3)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(hardhat@2.26.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.8.3))(typescript@5.8.3)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) - '@nomicfoundation/ignition-core': 0.15.13(bufferutil@4.0.9)(utf-8-validate@5.0.10) - ethers: 6.15.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) - hardhat: 2.26.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.8.3))(typescript@5.8.3)(utf-8-validate@5.0.10) + '@nomicfoundation/hardhat-ethers': 3.1.3(ethers@6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10)) + '@nomicfoundation/hardhat-ignition': 0.15.16(@nomicfoundation/hardhat-verify@2.1.3(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) + '@nomicfoundation/ignition-core': 0.15.15(bufferutil@4.0.9)(utf-8-validate@5.0.10) + ethers: 6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + hardhat: 2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10) - '@nomicfoundation/hardhat-ignition@0.15.13(@nomicfoundation/hardhat-verify@2.1.0(hardhat@2.26.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.8.3))(typescript@5.8.3)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(hardhat@2.26.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.8.3))(typescript@5.8.3)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10)': + '@nomicfoundation/hardhat-ignition@0.15.16(@nomicfoundation/hardhat-verify@2.1.3(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10)': dependencies: - '@nomicfoundation/hardhat-verify': 2.1.0(hardhat@2.26.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.8.3))(typescript@5.8.3)(utf-8-validate@5.0.10)) - '@nomicfoundation/ignition-core': 0.15.13(bufferutil@4.0.9)(utf-8-validate@5.0.10) - '@nomicfoundation/ignition-ui': 0.15.12 + '@nomicfoundation/hardhat-verify': 2.1.3(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10)) + '@nomicfoundation/ignition-core': 0.15.15(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@nomicfoundation/ignition-ui': 0.15.13 chalk: 4.1.2 - debug: 4.4.1(supports-color@8.1.1) + debug: 4.4.3(supports-color@8.1.1) fs-extra: 10.1.0 - hardhat: 2.26.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.8.3))(typescript@5.8.3)(utf-8-validate@5.0.10) + hardhat: 2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10) json5: 2.2.3 prompts: 2.4.2 transitivePeerDependencies: @@ -6060,39 +6547,39 @@ snapshots: - supports-color - utf-8-validate - '@nomicfoundation/hardhat-network-helpers@1.1.0(hardhat@2.26.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.8.3))(typescript@5.8.3)(utf-8-validate@5.0.10))': + '@nomicfoundation/hardhat-network-helpers@1.1.2(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10))': dependencies: ethereumjs-util: 7.1.5 - hardhat: 2.26.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.8.3))(typescript@5.8.3)(utf-8-validate@5.0.10) + hardhat: 2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10) - '@nomicfoundation/hardhat-toolbox@5.0.0(0e4b137f5db723198014a5b4a31800ae)': + '@nomicfoundation/hardhat-toolbox@5.0.0(718d8c1f3463e528ebfebd4ac5f4e994)': dependencies: - '@nomicfoundation/hardhat-chai-matchers': 2.1.0(@nomicfoundation/hardhat-ethers@3.1.0(ethers@6.15.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(hardhat@2.26.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.8.3))(typescript@5.8.3)(utf-8-validate@5.0.10)))(chai@4.5.0)(ethers@6.15.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(hardhat@2.26.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.8.3))(typescript@5.8.3)(utf-8-validate@5.0.10)) - '@nomicfoundation/hardhat-ethers': 3.1.0(ethers@6.15.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(hardhat@2.26.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.8.3))(typescript@5.8.3)(utf-8-validate@5.0.10)) - '@nomicfoundation/hardhat-ignition-ethers': 0.15.14(@nomicfoundation/hardhat-ethers@3.1.0(ethers@6.15.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(hardhat@2.26.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.8.3))(typescript@5.8.3)(utf-8-validate@5.0.10)))(@nomicfoundation/hardhat-ignition@0.15.13(@nomicfoundation/hardhat-verify@2.1.0(hardhat@2.26.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.8.3))(typescript@5.8.3)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(hardhat@2.26.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.8.3))(typescript@5.8.3)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10))(@nomicfoundation/ignition-core@0.15.13(bufferutil@4.0.9)(utf-8-validate@5.0.10))(ethers@6.15.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(hardhat@2.26.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.8.3))(typescript@5.8.3)(utf-8-validate@5.0.10)) - '@nomicfoundation/hardhat-network-helpers': 1.1.0(hardhat@2.26.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.8.3))(typescript@5.8.3)(utf-8-validate@5.0.10)) - '@nomicfoundation/hardhat-verify': 2.1.0(hardhat@2.26.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.8.3))(typescript@5.8.3)(utf-8-validate@5.0.10)) - '@typechain/ethers-v6': 0.5.1(ethers@6.15.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(typechain@8.3.2(typescript@5.8.3))(typescript@5.8.3) - '@typechain/hardhat': 9.1.0(@typechain/ethers-v6@0.5.1(ethers@6.15.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(typechain@8.3.2(typescript@5.8.3))(typescript@5.8.3))(ethers@6.15.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(hardhat@2.26.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.8.3))(typescript@5.8.3)(utf-8-validate@5.0.10))(typechain@8.3.2(typescript@5.8.3)) + '@nomicfoundation/hardhat-chai-matchers': 2.1.0(@nomicfoundation/hardhat-ethers@3.1.3(ethers@6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10)))(chai@4.5.0)(ethers@6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10)) + '@nomicfoundation/hardhat-ethers': 3.1.3(ethers@6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10)) + '@nomicfoundation/hardhat-ignition-ethers': 0.15.17(@nomicfoundation/hardhat-ethers@3.1.3(ethers@6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10)))(@nomicfoundation/hardhat-ignition@0.15.16(@nomicfoundation/hardhat-verify@2.1.3(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10))(@nomicfoundation/ignition-core@0.15.15(bufferutil@4.0.9)(utf-8-validate@5.0.10))(ethers@6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10)) + '@nomicfoundation/hardhat-network-helpers': 1.1.2(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10)) + '@nomicfoundation/hardhat-verify': 2.1.3(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10)) + '@typechain/ethers-v6': 0.5.1(ethers@6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(typechain@8.3.2(typescript@5.9.3))(typescript@5.9.3) + '@typechain/hardhat': 9.1.0(@typechain/ethers-v6@0.5.1(ethers@6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(typechain@8.3.2(typescript@5.9.3))(typescript@5.9.3))(ethers@6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10))(typechain@8.3.2(typescript@5.9.3)) '@types/chai': 4.3.20 '@types/mocha': 10.0.10 '@types/node': 22.7.5 chai: 4.5.0 - ethers: 6.15.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) - hardhat: 2.26.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.8.3))(typescript@5.8.3)(utf-8-validate@5.0.10) - hardhat-gas-reporter: 1.0.10(bufferutil@4.0.9)(hardhat@2.26.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.8.3))(typescript@5.8.3)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) - solidity-coverage: 0.8.16(hardhat@2.26.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.8.3))(typescript@5.8.3)(utf-8-validate@5.0.10)) - ts-node: 10.9.2(@types/node@22.7.5)(typescript@5.8.3) - typechain: 8.3.2(typescript@5.8.3) - typescript: 5.8.3 + ethers: 6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + hardhat: 2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10) + hardhat-gas-reporter: 1.0.10(bufferutil@4.0.9)(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) + solidity-coverage: 0.8.17(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10)) + ts-node: 10.9.2(@types/node@22.7.5)(typescript@5.9.3) + typechain: 8.3.2(typescript@5.9.3) + typescript: 5.9.3 - '@nomicfoundation/hardhat-verify@2.1.0(hardhat@2.26.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.8.3))(typescript@5.8.3)(utf-8-validate@5.0.10))': + '@nomicfoundation/hardhat-verify@2.1.3(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10))': dependencies: '@ethersproject/abi': 5.8.0 '@ethersproject/address': 5.8.0 cbor: 8.1.0 - debug: 4.4.1(supports-color@8.1.1) - hardhat: 2.26.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.8.3))(typescript@5.8.3)(utf-8-validate@5.0.10) + debug: 4.4.3(supports-color@8.1.1) + hardhat: 2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10) lodash.clonedeep: 4.5.0 picocolors: 1.1.1 semver: 6.3.1 @@ -6101,13 +6588,13 @@ snapshots: transitivePeerDependencies: - supports-color - '@nomicfoundation/ignition-core@0.15.13(bufferutil@4.0.9)(utf-8-validate@5.0.10)': + '@nomicfoundation/ignition-core@0.15.15(bufferutil@4.0.9)(utf-8-validate@5.0.10)': dependencies: '@ethersproject/address': 5.6.1 '@nomicfoundation/solidity-analyzer': 0.1.2 cbor: 9.0.2 - debug: 4.4.1(supports-color@8.1.1) - ethers: 6.15.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + debug: 4.4.3(supports-color@8.1.1) + ethers: 6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) fs-extra: 10.1.0 immer: 10.0.2 lodash: 4.17.21 @@ -6117,7 +6604,7 @@ snapshots: - supports-color - utf-8-validate - '@nomicfoundation/ignition-ui@0.15.12': {} + '@nomicfoundation/ignition-ui@0.15.13': {} '@nomicfoundation/slang@0.18.3': dependencies: @@ -6166,67 +6653,67 @@ snapshots: '@openzeppelin/defender-sdk-base-client@2.7.0': dependencies: - '@aws-sdk/client-lambda': 3.851.0 - amazon-cognito-identity-js: 6.3.15 + '@aws-sdk/client-lambda': 3.954.0 + amazon-cognito-identity-js: 6.3.16 async-retry: 1.3.3 transitivePeerDependencies: - aws-crt - encoding - '@openzeppelin/defender-sdk-deploy-client@2.7.0(debug@4.4.1)': + '@openzeppelin/defender-sdk-deploy-client@2.7.0(debug@4.4.3)': dependencies: '@openzeppelin/defender-sdk-base-client': 2.7.0 - axios: 1.11.0(debug@4.4.1) + axios: 1.13.2(debug@4.4.3) lodash: 4.17.21 transitivePeerDependencies: - aws-crt - debug - encoding - '@openzeppelin/defender-sdk-network-client@2.7.0(debug@4.4.1)': + '@openzeppelin/defender-sdk-network-client@2.7.0(debug@4.4.3)': dependencies: '@openzeppelin/defender-sdk-base-client': 2.7.0 - axios: 1.11.0(debug@4.4.1) + axios: 1.13.2(debug@4.4.3) lodash: 4.17.21 transitivePeerDependencies: - aws-crt - debug - encoding - '@openzeppelin/hardhat-upgrades@3.9.1(@nomicfoundation/hardhat-ethers@3.1.0(ethers@6.15.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(hardhat@2.26.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.8.3))(typescript@5.8.3)(utf-8-validate@5.0.10)))(@nomicfoundation/hardhat-verify@2.1.0(hardhat@2.26.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.8.3))(typescript@5.8.3)(utf-8-validate@5.0.10)))(ethers@6.15.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(hardhat@2.26.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.8.3))(typescript@5.8.3)(utf-8-validate@5.0.10))': + '@openzeppelin/hardhat-upgrades@3.9.1(@nomicfoundation/hardhat-ethers@3.1.3(ethers@6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10)))(@nomicfoundation/hardhat-verify@2.1.3(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10)))(ethers@6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10))': dependencies: - '@nomicfoundation/hardhat-ethers': 3.1.0(ethers@6.15.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(hardhat@2.26.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.8.3))(typescript@5.8.3)(utf-8-validate@5.0.10)) + '@nomicfoundation/hardhat-ethers': 3.1.3(ethers@6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10)) '@openzeppelin/defender-sdk-base-client': 2.7.0 - '@openzeppelin/defender-sdk-deploy-client': 2.7.0(debug@4.4.1) - '@openzeppelin/defender-sdk-network-client': 2.7.0(debug@4.4.1) - '@openzeppelin/upgrades-core': 1.44.1 + '@openzeppelin/defender-sdk-deploy-client': 2.7.0(debug@4.4.3) + '@openzeppelin/defender-sdk-network-client': 2.7.0(debug@4.4.3) + '@openzeppelin/upgrades-core': 1.44.2 chalk: 4.1.2 - debug: 4.4.1(supports-color@8.1.1) + debug: 4.4.3(supports-color@8.1.1) ethereumjs-util: 7.1.5 - ethers: 6.15.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) - hardhat: 2.26.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.8.3))(typescript@5.8.3)(utf-8-validate@5.0.10) + ethers: 6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + hardhat: 2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10) proper-lockfile: 4.1.2 - undici: 6.21.3 + undici: 6.22.0 optionalDependencies: - '@nomicfoundation/hardhat-verify': 2.1.0(hardhat@2.26.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.8.3))(typescript@5.8.3)(utf-8-validate@5.0.10)) + '@nomicfoundation/hardhat-verify': 2.1.3(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10)) transitivePeerDependencies: - aws-crt - encoding - supports-color - '@openzeppelin/upgrades-core@1.44.1': + '@openzeppelin/upgrades-core@1.44.2': dependencies: '@nomicfoundation/slang': 0.18.3 bignumber.js: 9.3.1 - cbor: 10.0.9 + cbor: 10.0.11 chalk: 4.1.2 compare-versions: 6.1.1 - debug: 4.4.1(supports-color@8.1.1) + debug: 4.4.3(supports-color@8.1.1) ethereumjs-util: 7.1.5 minimatch: 9.0.5 minimist: 1.2.8 proper-lockfile: 4.1.2 - solidity-ast: 0.4.60 + solidity-ast: 0.4.61 transitivePeerDependencies: - supports-color @@ -6239,46 +6726,54 @@ snapshots: tslib: 2.8.1 optional: true - '@pkgjs/parseargs@0.11.0': - optional: true - - '@rainbow-me/rainbowkit@2.2.8(@tanstack/react-query@5.83.0(react@18.3.1))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.8.3)(viem@2.37.5(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4))(wagmi@2.16.0(@tanstack/query-core@5.83.0)(@tanstack/react-query@5.83.0(react@18.3.1))(@types/react@18.3.23)(bufferutil@4.0.9)(immer@10.0.2)(react@18.3.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(viem@2.37.5(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4))(zod@3.22.4))': + '@rainbow-me/rainbowkit@2.2.10(@tanstack/react-query@5.90.12(react@18.3.1))(@types/react@18.3.27)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3)(viem@2.43.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1))(wagmi@2.19.5(@tanstack/query-core@5.90.12)(@tanstack/react-query@5.90.12(react@18.3.1))(@types/react@18.3.27)(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(immer@10.0.2)(react@18.3.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.43.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1))(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@4.2.1))': dependencies: - '@tanstack/react-query': 5.83.0(react@18.3.1) + '@tanstack/react-query': 5.90.12(react@18.3.1) '@vanilla-extract/css': 1.17.3 '@vanilla-extract/dynamic': 2.1.4 '@vanilla-extract/sprinkles': 1.6.4(@vanilla-extract/css@1.17.3) clsx: 2.1.1 - cuer: 0.0.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.8.3) + cuer: 0.0.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - react-remove-scroll: 2.6.2(@types/react@18.3.23)(react@18.3.1) - ua-parser-js: 1.0.40 - viem: 2.37.5(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) - wagmi: 2.16.0(@tanstack/query-core@5.83.0)(@tanstack/react-query@5.83.0(react@18.3.1))(@types/react@18.3.23)(bufferutil@4.0.9)(immer@10.0.2)(react@18.3.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(viem@2.37.5(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4))(zod@3.22.4) + react-remove-scroll: 2.6.2(@types/react@18.3.27)(react@18.3.1) + ua-parser-js: 1.0.41 + viem: 2.43.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) + wagmi: 2.19.5(@tanstack/query-core@5.90.12)(@tanstack/react-query@5.90.12(react@18.3.1))(@types/react@18.3.27)(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(immer@10.0.2)(react@18.3.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.43.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1))(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@4.2.1) transitivePeerDependencies: - '@types/react' - babel-plugin-macros - typescript - '@reown/appkit-common@1.7.8(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4)': + '@reown/appkit-common@1.7.8(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.22.4)': + dependencies: + big.js: 6.2.2 + dayjs: 1.11.13 + viem: 2.43.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.22.4) + transitivePeerDependencies: + - bufferutil + - typescript + - utf-8-validate + - zod + + '@reown/appkit-common@1.7.8(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1)': dependencies: big.js: 6.2.2 dayjs: 1.11.13 - viem: 2.37.5(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) + viem: 2.43.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) transitivePeerDependencies: - bufferutil - typescript - utf-8-validate - zod - '@reown/appkit-controllers@1.7.8(@types/react@18.3.23)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4)': + '@reown/appkit-controllers@1.7.8(@types/react@18.3.27)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1)': dependencies: - '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) - '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10) - '@walletconnect/universal-provider': 2.21.0(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) - valtio: 1.13.2(@types/react@18.3.23)(react@18.3.1) - viem: 2.37.5(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) + '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) + '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10) + '@walletconnect/universal-provider': 2.21.0(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) + valtio: 1.13.2(@types/react@18.3.27)(react@18.3.1) + viem: 2.43.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -6294,6 +6789,7 @@ snapshots: - '@types/react' - '@upstash/redis' - '@vercel/blob' + - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -6306,14 +6802,14 @@ snapshots: - utf-8-validate - zod - '@reown/appkit-pay@1.7.8(@types/react@18.3.23)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4)': + '@reown/appkit-pay@1.7.8(@types/react@18.3.27)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1)': dependencies: - '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) - '@reown/appkit-controllers': 1.7.8(@types/react@18.3.23)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) - '@reown/appkit-ui': 1.7.8(@types/react@18.3.23)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) - '@reown/appkit-utils': 1.7.8(@types/react@18.3.23)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@18.3.23)(react@18.3.1))(zod@3.22.4) + '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) + '@reown/appkit-controllers': 1.7.8(@types/react@18.3.27)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) + '@reown/appkit-ui': 1.7.8(@types/react@18.3.27)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) + '@reown/appkit-utils': 1.7.8(@types/react@18.3.27)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@18.3.27)(react@18.3.1))(zod@4.2.1) lit: 3.3.0 - valtio: 1.13.2(@types/react@18.3.23)(react@18.3.1) + valtio: 1.13.2(@types/react@18.3.27)(react@18.3.1) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -6329,6 +6825,7 @@ snapshots: - '@types/react' - '@upstash/redis' - '@vercel/blob' + - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -6345,13 +6842,13 @@ snapshots: dependencies: buffer: 6.0.3 - '@reown/appkit-scaffold-ui@1.7.8(@types/react@18.3.23)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@18.3.23)(react@18.3.1))(zod@3.22.4)': + '@reown/appkit-scaffold-ui@1.7.8(@types/react@18.3.27)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@18.3.27)(react@18.3.1))(zod@4.2.1)': dependencies: - '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) - '@reown/appkit-controllers': 1.7.8(@types/react@18.3.23)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) - '@reown/appkit-ui': 1.7.8(@types/react@18.3.23)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) - '@reown/appkit-utils': 1.7.8(@types/react@18.3.23)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@18.3.23)(react@18.3.1))(zod@3.22.4) - '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10) + '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) + '@reown/appkit-controllers': 1.7.8(@types/react@18.3.27)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) + '@reown/appkit-ui': 1.7.8(@types/react@18.3.27)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) + '@reown/appkit-utils': 1.7.8(@types/react@18.3.27)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@18.3.27)(react@18.3.1))(zod@4.2.1) + '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10) lit: 3.3.0 transitivePeerDependencies: - '@azure/app-configuration' @@ -6368,6 +6865,7 @@ snapshots: - '@types/react' - '@upstash/redis' - '@vercel/blob' + - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -6381,11 +6879,11 @@ snapshots: - valtio - zod - '@reown/appkit-ui@1.7.8(@types/react@18.3.23)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4)': + '@reown/appkit-ui@1.7.8(@types/react@18.3.27)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1)': dependencies: - '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) - '@reown/appkit-controllers': 1.7.8(@types/react@18.3.23)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) - '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10) + '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) + '@reown/appkit-controllers': 1.7.8(@types/react@18.3.27)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) + '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10) lit: 3.3.0 qrcode: 1.5.3 transitivePeerDependencies: @@ -6403,6 +6901,7 @@ snapshots: - '@types/react' - '@upstash/redis' - '@vercel/blob' + - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -6415,16 +6914,16 @@ snapshots: - utf-8-validate - zod - '@reown/appkit-utils@1.7.8(@types/react@18.3.23)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@18.3.23)(react@18.3.1))(zod@3.22.4)': + '@reown/appkit-utils@1.7.8(@types/react@18.3.27)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@18.3.27)(react@18.3.1))(zod@4.2.1)': dependencies: - '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) - '@reown/appkit-controllers': 1.7.8(@types/react@18.3.23)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) + '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) + '@reown/appkit-controllers': 1.7.8(@types/react@18.3.27)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) '@reown/appkit-polyfills': 1.7.8 - '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10) + '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10) '@walletconnect/logger': 2.1.2 - '@walletconnect/universal-provider': 2.21.0(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) - valtio: 1.13.2(@types/react@18.3.23)(react@18.3.1) - viem: 2.37.5(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) + '@walletconnect/universal-provider': 2.21.0(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) + valtio: 1.13.2(@types/react@18.3.27)(react@18.3.1) + viem: 2.43.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -6440,6 +6939,7 @@ snapshots: - '@types/react' - '@upstash/redis' - '@vercel/blob' + - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -6452,9 +6952,9 @@ snapshots: - utf-8-validate - zod - '@reown/appkit-wallet@1.7.8(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)': + '@reown/appkit-wallet@1.7.8(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)': dependencies: - '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) + '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.22.4) '@reown/appkit-polyfills': 1.7.8 '@walletconnect/logger': 2.1.2 zod: 3.22.4 @@ -6463,21 +6963,21 @@ snapshots: - typescript - utf-8-validate - '@reown/appkit@1.7.8(@types/react@18.3.23)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4)': + '@reown/appkit@1.7.8(@types/react@18.3.27)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1)': dependencies: - '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) - '@reown/appkit-controllers': 1.7.8(@types/react@18.3.23)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) - '@reown/appkit-pay': 1.7.8(@types/react@18.3.23)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) + '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) + '@reown/appkit-controllers': 1.7.8(@types/react@18.3.27)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) + '@reown/appkit-pay': 1.7.8(@types/react@18.3.27)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) '@reown/appkit-polyfills': 1.7.8 - '@reown/appkit-scaffold-ui': 1.7.8(@types/react@18.3.23)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@18.3.23)(react@18.3.1))(zod@3.22.4) - '@reown/appkit-ui': 1.7.8(@types/react@18.3.23)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) - '@reown/appkit-utils': 1.7.8(@types/react@18.3.23)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@18.3.23)(react@18.3.1))(zod@3.22.4) - '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10) + '@reown/appkit-scaffold-ui': 1.7.8(@types/react@18.3.27)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@18.3.27)(react@18.3.1))(zod@4.2.1) + '@reown/appkit-ui': 1.7.8(@types/react@18.3.27)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) + '@reown/appkit-utils': 1.7.8(@types/react@18.3.27)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@18.3.27)(react@18.3.1))(zod@4.2.1) + '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10) '@walletconnect/types': 2.21.0 - '@walletconnect/universal-provider': 2.21.0(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) + '@walletconnect/universal-provider': 2.21.0(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) bs58: 6.0.0 - valtio: 1.13.2(@types/react@18.3.23)(react@18.3.1) - viem: 2.37.5(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) + valtio: 1.13.2(@types/react@18.3.27)(react@18.3.1) + viem: 2.43.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -6493,6 +6993,7 @@ snapshots: - '@types/react' - '@upstash/redis' - '@vercel/blob' + - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -6507,72 +7008,78 @@ snapshots: '@rolldown/pluginutils@1.0.0-beta.27': {} - '@rollup/rollup-android-arm-eabi@4.45.1': + '@rollup/rollup-android-arm-eabi@4.53.5': optional: true - '@rollup/rollup-android-arm64@4.45.1': + '@rollup/rollup-android-arm64@4.53.5': optional: true - '@rollup/rollup-darwin-arm64@4.45.1': + '@rollup/rollup-darwin-arm64@4.53.5': optional: true - '@rollup/rollup-darwin-x64@4.45.1': + '@rollup/rollup-darwin-x64@4.53.5': optional: true - '@rollup/rollup-freebsd-arm64@4.45.1': + '@rollup/rollup-freebsd-arm64@4.53.5': optional: true - '@rollup/rollup-freebsd-x64@4.45.1': + '@rollup/rollup-freebsd-x64@4.53.5': optional: true - '@rollup/rollup-linux-arm-gnueabihf@4.45.1': + '@rollup/rollup-linux-arm-gnueabihf@4.53.5': optional: true - '@rollup/rollup-linux-arm-musleabihf@4.45.1': + '@rollup/rollup-linux-arm-musleabihf@4.53.5': optional: true - '@rollup/rollup-linux-arm64-gnu@4.45.1': + '@rollup/rollup-linux-arm64-gnu@4.53.5': optional: true - '@rollup/rollup-linux-arm64-musl@4.45.1': + '@rollup/rollup-linux-arm64-musl@4.53.5': optional: true - '@rollup/rollup-linux-loongarch64-gnu@4.45.1': + '@rollup/rollup-linux-loong64-gnu@4.53.5': optional: true - '@rollup/rollup-linux-powerpc64le-gnu@4.45.1': + '@rollup/rollup-linux-ppc64-gnu@4.53.5': optional: true - '@rollup/rollup-linux-riscv64-gnu@4.45.1': + '@rollup/rollup-linux-riscv64-gnu@4.53.5': optional: true - '@rollup/rollup-linux-riscv64-musl@4.45.1': + '@rollup/rollup-linux-riscv64-musl@4.53.5': optional: true - '@rollup/rollup-linux-s390x-gnu@4.45.1': + '@rollup/rollup-linux-s390x-gnu@4.53.5': optional: true - '@rollup/rollup-linux-x64-gnu@4.45.1': + '@rollup/rollup-linux-x64-gnu@4.53.5': optional: true - '@rollup/rollup-linux-x64-musl@4.45.1': + '@rollup/rollup-linux-x64-musl@4.53.5': optional: true - '@rollup/rollup-win32-arm64-msvc@4.45.1': + '@rollup/rollup-openharmony-arm64@4.53.5': optional: true - '@rollup/rollup-win32-ia32-msvc@4.45.1': + '@rollup/rollup-win32-arm64-msvc@4.53.5': optional: true - '@rollup/rollup-win32-x64-msvc@4.45.1': + '@rollup/rollup-win32-ia32-msvc@4.53.5': optional: true - '@safe-global/api-kit@4.0.1(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4)': + '@rollup/rollup-win32-x64-gnu@4.53.5': + optional: true + + '@rollup/rollup-win32-x64-msvc@4.53.5': + optional: true + + '@safe-global/api-kit@4.0.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1)': dependencies: - '@safe-global/protocol-kit': 6.1.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) - '@safe-global/types-kit': 3.0.0(typescript@5.8.3)(zod@3.22.4) + '@safe-global/protocol-kit': 6.1.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) + '@safe-global/types-kit': 3.0.0(typescript@5.9.3)(zod@4.2.1) node-fetch: 2.7.0 - viem: 2.37.5(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) + viem: 2.43.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) transitivePeerDependencies: - bufferutil - encoding @@ -6580,16 +7087,16 @@ snapshots: - utf-8-validate - zod - '@safe-global/protocol-kit@6.1.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4)': + '@safe-global/protocol-kit@6.1.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1)': dependencies: '@safe-global/safe-deployments': 1.37.49 '@safe-global/safe-modules-deployments': 2.2.21 - '@safe-global/types-kit': 3.0.0(typescript@5.8.3)(zod@3.22.4) - abitype: 1.1.0(typescript@5.8.3)(zod@3.22.4) - semver: 7.7.2 - viem: 2.37.5(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) + '@safe-global/types-kit': 3.0.0(typescript@5.9.3)(zod@4.2.1) + abitype: 1.2.3(typescript@5.9.3)(zod@4.2.1) + semver: 7.7.3 + viem: 2.43.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) optionalDependencies: - '@noble/curves': 1.9.4 + '@noble/curves': 1.9.7 '@peculiar/asn1-schema': 2.6.0 transitivePeerDependencies: - bufferutil @@ -6597,9 +7104,9 @@ snapshots: - utf-8-validate - zod - '@safe-global/safe-apps-provider@0.18.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4)': + '@safe-global/safe-apps-provider@0.18.6(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1)': dependencies: - '@safe-global/safe-apps-sdk': 9.1.0(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) + '@safe-global/safe-apps-sdk': 9.1.0(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) events: 3.3.0 transitivePeerDependencies: - bufferutil @@ -6607,10 +7114,10 @@ snapshots: - utf-8-validate - zod - '@safe-global/safe-apps-sdk@9.1.0(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4)': + '@safe-global/safe-apps-sdk@9.1.0(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1)': dependencies: '@safe-global/safe-gateway-typescript-sdk': 3.23.1 - viem: 2.37.5(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) + viem: 2.43.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) transitivePeerDependencies: - bufferutil - typescript @@ -6619,15 +7126,15 @@ snapshots: '@safe-global/safe-deployments@1.37.49': dependencies: - semver: 7.7.2 + semver: 7.7.3 '@safe-global/safe-gateway-typescript-sdk@3.23.1': {} '@safe-global/safe-modules-deployments@2.2.21': {} - '@safe-global/types-kit@3.0.0(typescript@5.8.3)(zod@3.22.4)': + '@safe-global/types-kit@3.0.0(typescript@5.9.3)(zod@4.2.1)': dependencies: - abitype: 1.1.0(typescript@5.8.3)(zod@3.22.4) + abitype: 1.2.3(typescript@5.9.3)(zod@4.2.1) transitivePeerDependencies: - typescript - zod @@ -6650,13 +7157,13 @@ snapshots: '@scure/bip32@1.6.2': dependencies: - '@noble/curves': 1.8.2 - '@noble/hashes': 1.7.2 + '@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.4 + '@noble/curves': 1.9.1 '@noble/hashes': 1.8.0 '@scure/base': 1.2.6 @@ -6672,7 +7179,7 @@ snapshots: '@scure/bip39@1.5.4': dependencies: - '@noble/hashes': 1.7.2 + '@noble/hashes': 1.7.1 '@scure/base': 1.2.6 '@scure/bip39@1.6.0': @@ -6729,224 +7236,226 @@ snapshots: '@sentry/types': 5.30.0 tslib: 1.14.1 - '@smithy/abort-controller@4.0.4': + '@smithy/abort-controller@4.2.6': dependencies: - '@smithy/types': 4.3.1 + '@smithy/types': 4.10.0 tslib: 2.8.1 - '@smithy/config-resolver@4.1.4': + '@smithy/config-resolver@4.4.4': dependencies: - '@smithy/node-config-provider': 4.1.3 - '@smithy/types': 4.3.1 - '@smithy/util-config-provider': 4.0.0 - '@smithy/util-middleware': 4.0.4 + '@smithy/node-config-provider': 4.3.6 + '@smithy/types': 4.10.0 + '@smithy/util-config-provider': 4.2.0 + '@smithy/util-endpoints': 3.2.6 + '@smithy/util-middleware': 4.2.6 tslib: 2.8.1 - '@smithy/core@3.7.2': - dependencies: - '@smithy/middleware-serde': 4.0.8 - '@smithy/protocol-http': 5.1.2 - '@smithy/types': 4.3.1 - '@smithy/util-base64': 4.0.0 - '@smithy/util-body-length-browser': 4.0.0 - '@smithy/util-middleware': 4.0.4 - '@smithy/util-stream': 4.2.3 - '@smithy/util-utf8': 4.0.0 + '@smithy/core@3.19.0': + dependencies: + '@smithy/middleware-serde': 4.2.7 + '@smithy/protocol-http': 5.3.6 + '@smithy/types': 4.10.0 + '@smithy/util-base64': 4.3.0 + '@smithy/util-body-length-browser': 4.2.0 + '@smithy/util-middleware': 4.2.6 + '@smithy/util-stream': 4.5.7 + '@smithy/util-utf8': 4.2.0 + '@smithy/uuid': 1.1.0 tslib: 2.8.1 - '@smithy/credential-provider-imds@4.0.6': + '@smithy/credential-provider-imds@4.2.6': dependencies: - '@smithy/node-config-provider': 4.1.3 - '@smithy/property-provider': 4.0.4 - '@smithy/types': 4.3.1 - '@smithy/url-parser': 4.0.4 + '@smithy/node-config-provider': 4.3.6 + '@smithy/property-provider': 4.2.6 + '@smithy/types': 4.10.0 + '@smithy/url-parser': 4.2.6 tslib: 2.8.1 - '@smithy/eventstream-codec@4.0.4': + '@smithy/eventstream-codec@4.2.6': dependencies: '@aws-crypto/crc32': 5.2.0 - '@smithy/types': 4.3.1 - '@smithy/util-hex-encoding': 4.0.0 + '@smithy/types': 4.10.0 + '@smithy/util-hex-encoding': 4.2.0 tslib: 2.8.1 - '@smithy/eventstream-serde-browser@4.0.4': + '@smithy/eventstream-serde-browser@4.2.6': dependencies: - '@smithy/eventstream-serde-universal': 4.0.4 - '@smithy/types': 4.3.1 + '@smithy/eventstream-serde-universal': 4.2.6 + '@smithy/types': 4.10.0 tslib: 2.8.1 - '@smithy/eventstream-serde-config-resolver@4.1.2': + '@smithy/eventstream-serde-config-resolver@4.3.6': dependencies: - '@smithy/types': 4.3.1 + '@smithy/types': 4.10.0 tslib: 2.8.1 - '@smithy/eventstream-serde-node@4.0.4': + '@smithy/eventstream-serde-node@4.2.6': dependencies: - '@smithy/eventstream-serde-universal': 4.0.4 - '@smithy/types': 4.3.1 + '@smithy/eventstream-serde-universal': 4.2.6 + '@smithy/types': 4.10.0 tslib: 2.8.1 - '@smithy/eventstream-serde-universal@4.0.4': + '@smithy/eventstream-serde-universal@4.2.6': dependencies: - '@smithy/eventstream-codec': 4.0.4 - '@smithy/types': 4.3.1 + '@smithy/eventstream-codec': 4.2.6 + '@smithy/types': 4.10.0 tslib: 2.8.1 - '@smithy/fetch-http-handler@5.1.0': + '@smithy/fetch-http-handler@5.3.7': dependencies: - '@smithy/protocol-http': 5.1.2 - '@smithy/querystring-builder': 4.0.4 - '@smithy/types': 4.3.1 - '@smithy/util-base64': 4.0.0 + '@smithy/protocol-http': 5.3.6 + '@smithy/querystring-builder': 4.2.6 + '@smithy/types': 4.10.0 + '@smithy/util-base64': 4.3.0 tslib: 2.8.1 - '@smithy/hash-node@4.0.4': + '@smithy/hash-node@4.2.6': dependencies: - '@smithy/types': 4.3.1 - '@smithy/util-buffer-from': 4.0.0 - '@smithy/util-utf8': 4.0.0 + '@smithy/types': 4.10.0 + '@smithy/util-buffer-from': 4.2.0 + '@smithy/util-utf8': 4.2.0 tslib: 2.8.1 - '@smithy/invalid-dependency@4.0.4': + '@smithy/invalid-dependency@4.2.6': dependencies: - '@smithy/types': 4.3.1 + '@smithy/types': 4.10.0 tslib: 2.8.1 '@smithy/is-array-buffer@2.2.0': dependencies: tslib: 2.8.1 - '@smithy/is-array-buffer@4.0.0': + '@smithy/is-array-buffer@4.2.0': dependencies: tslib: 2.8.1 - '@smithy/middleware-content-length@4.0.4': + '@smithy/middleware-content-length@4.2.6': dependencies: - '@smithy/protocol-http': 5.1.2 - '@smithy/types': 4.3.1 + '@smithy/protocol-http': 5.3.6 + '@smithy/types': 4.10.0 tslib: 2.8.1 - '@smithy/middleware-endpoint@4.1.17': + '@smithy/middleware-endpoint@4.4.0': dependencies: - '@smithy/core': 3.7.2 - '@smithy/middleware-serde': 4.0.8 - '@smithy/node-config-provider': 4.1.3 - '@smithy/shared-ini-file-loader': 4.0.4 - '@smithy/types': 4.3.1 - '@smithy/url-parser': 4.0.4 - '@smithy/util-middleware': 4.0.4 + '@smithy/core': 3.19.0 + '@smithy/middleware-serde': 4.2.7 + '@smithy/node-config-provider': 4.3.6 + '@smithy/shared-ini-file-loader': 4.4.1 + '@smithy/types': 4.10.0 + '@smithy/url-parser': 4.2.6 + '@smithy/util-middleware': 4.2.6 tslib: 2.8.1 - '@smithy/middleware-retry@4.1.18': + '@smithy/middleware-retry@4.4.16': dependencies: - '@smithy/node-config-provider': 4.1.3 - '@smithy/protocol-http': 5.1.2 - '@smithy/service-error-classification': 4.0.6 - '@smithy/smithy-client': 4.4.9 - '@smithy/types': 4.3.1 - '@smithy/util-middleware': 4.0.4 - '@smithy/util-retry': 4.0.6 + '@smithy/node-config-provider': 4.3.6 + '@smithy/protocol-http': 5.3.6 + '@smithy/service-error-classification': 4.2.6 + '@smithy/smithy-client': 4.10.1 + '@smithy/types': 4.10.0 + '@smithy/util-middleware': 4.2.6 + '@smithy/util-retry': 4.2.6 + '@smithy/uuid': 1.1.0 tslib: 2.8.1 - uuid: 9.0.1 - '@smithy/middleware-serde@4.0.8': + '@smithy/middleware-serde@4.2.7': dependencies: - '@smithy/protocol-http': 5.1.2 - '@smithy/types': 4.3.1 + '@smithy/protocol-http': 5.3.6 + '@smithy/types': 4.10.0 tslib: 2.8.1 - '@smithy/middleware-stack@4.0.4': + '@smithy/middleware-stack@4.2.6': dependencies: - '@smithy/types': 4.3.1 + '@smithy/types': 4.10.0 tslib: 2.8.1 - '@smithy/node-config-provider@4.1.3': + '@smithy/node-config-provider@4.3.6': dependencies: - '@smithy/property-provider': 4.0.4 - '@smithy/shared-ini-file-loader': 4.0.4 - '@smithy/types': 4.3.1 + '@smithy/property-provider': 4.2.6 + '@smithy/shared-ini-file-loader': 4.4.1 + '@smithy/types': 4.10.0 tslib: 2.8.1 - '@smithy/node-http-handler@4.1.0': + '@smithy/node-http-handler@4.4.6': dependencies: - '@smithy/abort-controller': 4.0.4 - '@smithy/protocol-http': 5.1.2 - '@smithy/querystring-builder': 4.0.4 - '@smithy/types': 4.3.1 + '@smithy/abort-controller': 4.2.6 + '@smithy/protocol-http': 5.3.6 + '@smithy/querystring-builder': 4.2.6 + '@smithy/types': 4.10.0 tslib: 2.8.1 - '@smithy/property-provider@4.0.4': + '@smithy/property-provider@4.2.6': dependencies: - '@smithy/types': 4.3.1 + '@smithy/types': 4.10.0 tslib: 2.8.1 - '@smithy/protocol-http@5.1.2': + '@smithy/protocol-http@5.3.6': dependencies: - '@smithy/types': 4.3.1 + '@smithy/types': 4.10.0 tslib: 2.8.1 - '@smithy/querystring-builder@4.0.4': + '@smithy/querystring-builder@4.2.6': dependencies: - '@smithy/types': 4.3.1 - '@smithy/util-uri-escape': 4.0.0 + '@smithy/types': 4.10.0 + '@smithy/util-uri-escape': 4.2.0 tslib: 2.8.1 - '@smithy/querystring-parser@4.0.4': + '@smithy/querystring-parser@4.2.6': dependencies: - '@smithy/types': 4.3.1 + '@smithy/types': 4.10.0 tslib: 2.8.1 - '@smithy/service-error-classification@4.0.6': + '@smithy/service-error-classification@4.2.6': dependencies: - '@smithy/types': 4.3.1 + '@smithy/types': 4.10.0 - '@smithy/shared-ini-file-loader@4.0.4': + '@smithy/shared-ini-file-loader@4.4.1': dependencies: - '@smithy/types': 4.3.1 + '@smithy/types': 4.10.0 tslib: 2.8.1 - '@smithy/signature-v4@5.1.2': + '@smithy/signature-v4@5.3.6': dependencies: - '@smithy/is-array-buffer': 4.0.0 - '@smithy/protocol-http': 5.1.2 - '@smithy/types': 4.3.1 - '@smithy/util-hex-encoding': 4.0.0 - '@smithy/util-middleware': 4.0.4 - '@smithy/util-uri-escape': 4.0.0 - '@smithy/util-utf8': 4.0.0 + '@smithy/is-array-buffer': 4.2.0 + '@smithy/protocol-http': 5.3.6 + '@smithy/types': 4.10.0 + '@smithy/util-hex-encoding': 4.2.0 + '@smithy/util-middleware': 4.2.6 + '@smithy/util-uri-escape': 4.2.0 + '@smithy/util-utf8': 4.2.0 tslib: 2.8.1 - '@smithy/smithy-client@4.4.9': + '@smithy/smithy-client@4.10.1': dependencies: - '@smithy/core': 3.7.2 - '@smithy/middleware-endpoint': 4.1.17 - '@smithy/middleware-stack': 4.0.4 - '@smithy/protocol-http': 5.1.2 - '@smithy/types': 4.3.1 - '@smithy/util-stream': 4.2.3 + '@smithy/core': 3.19.0 + '@smithy/middleware-endpoint': 4.4.0 + '@smithy/middleware-stack': 4.2.6 + '@smithy/protocol-http': 5.3.6 + '@smithy/types': 4.10.0 + '@smithy/util-stream': 4.5.7 tslib: 2.8.1 - '@smithy/types@4.3.1': + '@smithy/types@4.10.0': dependencies: tslib: 2.8.1 - '@smithy/url-parser@4.0.4': + '@smithy/url-parser@4.2.6': dependencies: - '@smithy/querystring-parser': 4.0.4 - '@smithy/types': 4.3.1 + '@smithy/querystring-parser': 4.2.6 + '@smithy/types': 4.10.0 tslib: 2.8.1 - '@smithy/util-base64@4.0.0': + '@smithy/util-base64@4.3.0': dependencies: - '@smithy/util-buffer-from': 4.0.0 - '@smithy/util-utf8': 4.0.0 + '@smithy/util-buffer-from': 4.2.0 + '@smithy/util-utf8': 4.2.0 tslib: 2.8.1 - '@smithy/util-body-length-browser@4.0.0': + '@smithy/util-body-length-browser@4.2.0': dependencies: tslib: 2.8.1 - '@smithy/util-body-length-node@4.0.0': + '@smithy/util-body-length-node@4.2.1': dependencies: tslib: 2.8.1 @@ -6955,66 +7464,65 @@ snapshots: '@smithy/is-array-buffer': 2.2.0 tslib: 2.8.1 - '@smithy/util-buffer-from@4.0.0': + '@smithy/util-buffer-from@4.2.0': dependencies: - '@smithy/is-array-buffer': 4.0.0 + '@smithy/is-array-buffer': 4.2.0 tslib: 2.8.1 - '@smithy/util-config-provider@4.0.0': + '@smithy/util-config-provider@4.2.0': dependencies: tslib: 2.8.1 - '@smithy/util-defaults-mode-browser@4.0.25': + '@smithy/util-defaults-mode-browser@4.3.15': dependencies: - '@smithy/property-provider': 4.0.4 - '@smithy/smithy-client': 4.4.9 - '@smithy/types': 4.3.1 - bowser: 2.11.0 + '@smithy/property-provider': 4.2.6 + '@smithy/smithy-client': 4.10.1 + '@smithy/types': 4.10.0 tslib: 2.8.1 - '@smithy/util-defaults-mode-node@4.0.25': + '@smithy/util-defaults-mode-node@4.2.18': dependencies: - '@smithy/config-resolver': 4.1.4 - '@smithy/credential-provider-imds': 4.0.6 - '@smithy/node-config-provider': 4.1.3 - '@smithy/property-provider': 4.0.4 - '@smithy/smithy-client': 4.4.9 - '@smithy/types': 4.3.1 + '@smithy/config-resolver': 4.4.4 + '@smithy/credential-provider-imds': 4.2.6 + '@smithy/node-config-provider': 4.3.6 + '@smithy/property-provider': 4.2.6 + '@smithy/smithy-client': 4.10.1 + '@smithy/types': 4.10.0 tslib: 2.8.1 - '@smithy/util-endpoints@3.0.6': + '@smithy/util-endpoints@3.2.6': dependencies: - '@smithy/node-config-provider': 4.1.3 - '@smithy/types': 4.3.1 + '@smithy/node-config-provider': 4.3.6 + '@smithy/types': 4.10.0 tslib: 2.8.1 - '@smithy/util-hex-encoding@4.0.0': + '@smithy/util-hex-encoding@4.2.0': dependencies: tslib: 2.8.1 - '@smithy/util-middleware@4.0.4': + '@smithy/util-middleware@4.2.6': dependencies: - '@smithy/types': 4.3.1 + '@smithy/types': 4.10.0 tslib: 2.8.1 - '@smithy/util-retry@4.0.6': + '@smithy/util-retry@4.2.6': dependencies: - '@smithy/service-error-classification': 4.0.6 - '@smithy/types': 4.3.1 + '@smithy/service-error-classification': 4.2.6 + '@smithy/types': 4.10.0 tslib: 2.8.1 - '@smithy/util-stream@4.2.3': + '@smithy/util-stream@4.5.7': dependencies: - '@smithy/fetch-http-handler': 5.1.0 - '@smithy/node-http-handler': 4.1.0 - '@smithy/types': 4.3.1 - '@smithy/util-base64': 4.0.0 - '@smithy/util-buffer-from': 4.0.0 - '@smithy/util-hex-encoding': 4.0.0 - '@smithy/util-utf8': 4.0.0 + '@smithy/fetch-http-handler': 5.3.7 + '@smithy/node-http-handler': 4.4.6 + '@smithy/types': 4.10.0 + '@smithy/util-base64': 4.3.0 + '@smithy/util-buffer-from': 4.2.0 + '@smithy/util-hex-encoding': 4.2.0 + '@smithy/util-utf8': 4.2.0 tslib: 2.8.1 - '@smithy/util-uri-escape@4.0.0': + '@smithy/util-uri-escape@4.2.0': dependencies: tslib: 2.8.1 @@ -7023,33 +7531,457 @@ snapshots: '@smithy/util-buffer-from': 2.2.0 tslib: 2.8.1 - '@smithy/util-utf8@4.0.0': + '@smithy/util-utf8@4.2.0': dependencies: - '@smithy/util-buffer-from': 4.0.0 + '@smithy/util-buffer-from': 4.2.0 tslib: 2.8.1 - '@smithy/util-waiter@4.0.6': + '@smithy/util-waiter@4.2.6': + dependencies: + '@smithy/abort-controller': 4.2.6 + '@smithy/types': 4.10.0 + tslib: 2.8.1 + + '@smithy/uuid@1.1.0': dependencies: - '@smithy/abort-controller': 4.0.4 - '@smithy/types': 4.3.1 tslib: 2.8.1 '@socket.io/component-emitter@3.1.2': {} + '@solana-program/system@0.8.1(@solana/kit@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)))': + dependencies: + '@solana/kit': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + + '@solana-program/token@0.6.0(@solana/kit@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)))': + dependencies: + '@solana/kit': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + + '@solana/accounts@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)': + dependencies: + '@solana/addresses': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/codecs-core': 3.0.3(typescript@5.9.3) + '@solana/codecs-strings': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/errors': 3.0.3(typescript@5.9.3) + '@solana/rpc-spec': 3.0.3(typescript@5.9.3) + '@solana/rpc-types': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/addresses@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)': + dependencies: + '@solana/assertions': 3.0.3(typescript@5.9.3) + '@solana/codecs-core': 3.0.3(typescript@5.9.3) + '@solana/codecs-strings': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/errors': 3.0.3(typescript@5.9.3) + '@solana/nominal-types': 3.0.3(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/assertions@3.0.3(typescript@5.9.3)': + dependencies: + '@solana/errors': 3.0.3(typescript@5.9.3) + typescript: 5.9.3 + + '@solana/buffer-layout@4.0.1': + dependencies: + buffer: 6.0.3 + + '@solana/codecs-core@2.3.0(typescript@5.9.3)': + dependencies: + '@solana/errors': 2.3.0(typescript@5.9.3) + typescript: 5.9.3 + + '@solana/codecs-core@3.0.3(typescript@5.9.3)': + dependencies: + '@solana/errors': 3.0.3(typescript@5.9.3) + typescript: 5.9.3 + + '@solana/codecs-data-structures@3.0.3(typescript@5.9.3)': + dependencies: + '@solana/codecs-core': 3.0.3(typescript@5.9.3) + '@solana/codecs-numbers': 3.0.3(typescript@5.9.3) + '@solana/errors': 3.0.3(typescript@5.9.3) + typescript: 5.9.3 + + '@solana/codecs-numbers@2.3.0(typescript@5.9.3)': + dependencies: + '@solana/codecs-core': 2.3.0(typescript@5.9.3) + '@solana/errors': 2.3.0(typescript@5.9.3) + typescript: 5.9.3 + + '@solana/codecs-numbers@3.0.3(typescript@5.9.3)': + dependencies: + '@solana/codecs-core': 3.0.3(typescript@5.9.3) + '@solana/errors': 3.0.3(typescript@5.9.3) + typescript: 5.9.3 + + '@solana/codecs-strings@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)': + dependencies: + '@solana/codecs-core': 3.0.3(typescript@5.9.3) + '@solana/codecs-numbers': 3.0.3(typescript@5.9.3) + '@solana/errors': 3.0.3(typescript@5.9.3) + fastestsmallesttextencoderdecoder: 1.0.22 + typescript: 5.9.3 + + '@solana/codecs@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)': + dependencies: + '@solana/codecs-core': 3.0.3(typescript@5.9.3) + '@solana/codecs-data-structures': 3.0.3(typescript@5.9.3) + '@solana/codecs-numbers': 3.0.3(typescript@5.9.3) + '@solana/codecs-strings': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/options': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/errors@2.3.0(typescript@5.9.3)': + dependencies: + chalk: 5.6.2 + commander: 14.0.2 + typescript: 5.9.3 + + '@solana/errors@3.0.3(typescript@5.9.3)': + dependencies: + chalk: 5.6.2 + commander: 14.0.0 + typescript: 5.9.3 + + '@solana/fast-stable-stringify@3.0.3(typescript@5.9.3)': + dependencies: + typescript: 5.9.3 + + '@solana/functional@3.0.3(typescript@5.9.3)': + dependencies: + typescript: 5.9.3 + + '@solana/instruction-plans@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)': + dependencies: + '@solana/errors': 3.0.3(typescript@5.9.3) + '@solana/instructions': 3.0.3(typescript@5.9.3) + '@solana/promises': 3.0.3(typescript@5.9.3) + '@solana/transaction-messages': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/transactions': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/instructions@3.0.3(typescript@5.9.3)': + dependencies: + '@solana/codecs-core': 3.0.3(typescript@5.9.3) + '@solana/errors': 3.0.3(typescript@5.9.3) + typescript: 5.9.3 + + '@solana/keys@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)': + dependencies: + '@solana/assertions': 3.0.3(typescript@5.9.3) + '@solana/codecs-core': 3.0.3(typescript@5.9.3) + '@solana/codecs-strings': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/errors': 3.0.3(typescript@5.9.3) + '@solana/nominal-types': 3.0.3(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/kit@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))': + dependencies: + '@solana/accounts': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/addresses': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/codecs': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/errors': 3.0.3(typescript@5.9.3) + '@solana/functional': 3.0.3(typescript@5.9.3) + '@solana/instruction-plans': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/instructions': 3.0.3(typescript@5.9.3) + '@solana/keys': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/programs': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/rpc': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/rpc-parsed-types': 3.0.3(typescript@5.9.3) + '@solana/rpc-spec-types': 3.0.3(typescript@5.9.3) + '@solana/rpc-subscriptions': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@solana/rpc-types': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/signers': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/sysvars': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/transaction-confirmation': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@solana/transaction-messages': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/transactions': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + - ws + + '@solana/nominal-types@3.0.3(typescript@5.9.3)': + dependencies: + typescript: 5.9.3 + + '@solana/options@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)': + dependencies: + '@solana/codecs-core': 3.0.3(typescript@5.9.3) + '@solana/codecs-data-structures': 3.0.3(typescript@5.9.3) + '@solana/codecs-numbers': 3.0.3(typescript@5.9.3) + '@solana/codecs-strings': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/errors': 3.0.3(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/programs@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)': + dependencies: + '@solana/addresses': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/errors': 3.0.3(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/promises@3.0.3(typescript@5.9.3)': + dependencies: + typescript: 5.9.3 + + '@solana/rpc-api@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)': + dependencies: + '@solana/addresses': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/codecs-core': 3.0.3(typescript@5.9.3) + '@solana/codecs-strings': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/errors': 3.0.3(typescript@5.9.3) + '@solana/keys': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/rpc-parsed-types': 3.0.3(typescript@5.9.3) + '@solana/rpc-spec': 3.0.3(typescript@5.9.3) + '@solana/rpc-transformers': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/rpc-types': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/transaction-messages': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/transactions': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/rpc-parsed-types@3.0.3(typescript@5.9.3)': + dependencies: + typescript: 5.9.3 + + '@solana/rpc-spec-types@3.0.3(typescript@5.9.3)': + dependencies: + typescript: 5.9.3 + + '@solana/rpc-spec@3.0.3(typescript@5.9.3)': + dependencies: + '@solana/errors': 3.0.3(typescript@5.9.3) + '@solana/rpc-spec-types': 3.0.3(typescript@5.9.3) + typescript: 5.9.3 + + '@solana/rpc-subscriptions-api@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)': + dependencies: + '@solana/addresses': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/keys': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/rpc-subscriptions-spec': 3.0.3(typescript@5.9.3) + '@solana/rpc-transformers': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/rpc-types': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/transaction-messages': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/transactions': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/rpc-subscriptions-channel-websocket@3.0.3(typescript@5.9.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))': + dependencies: + '@solana/errors': 3.0.3(typescript@5.9.3) + '@solana/functional': 3.0.3(typescript@5.9.3) + '@solana/rpc-subscriptions-spec': 3.0.3(typescript@5.9.3) + '@solana/subscribable': 3.0.3(typescript@5.9.3) + typescript: 5.9.3 + ws: 8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + + '@solana/rpc-subscriptions-spec@3.0.3(typescript@5.9.3)': + dependencies: + '@solana/errors': 3.0.3(typescript@5.9.3) + '@solana/promises': 3.0.3(typescript@5.9.3) + '@solana/rpc-spec-types': 3.0.3(typescript@5.9.3) + '@solana/subscribable': 3.0.3(typescript@5.9.3) + typescript: 5.9.3 + + '@solana/rpc-subscriptions@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))': + dependencies: + '@solana/errors': 3.0.3(typescript@5.9.3) + '@solana/fast-stable-stringify': 3.0.3(typescript@5.9.3) + '@solana/functional': 3.0.3(typescript@5.9.3) + '@solana/promises': 3.0.3(typescript@5.9.3) + '@solana/rpc-spec-types': 3.0.3(typescript@5.9.3) + '@solana/rpc-subscriptions-api': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/rpc-subscriptions-channel-websocket': 3.0.3(typescript@5.9.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@solana/rpc-subscriptions-spec': 3.0.3(typescript@5.9.3) + '@solana/rpc-transformers': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/rpc-types': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/subscribable': 3.0.3(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + - ws + + '@solana/rpc-transformers@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)': + dependencies: + '@solana/errors': 3.0.3(typescript@5.9.3) + '@solana/functional': 3.0.3(typescript@5.9.3) + '@solana/nominal-types': 3.0.3(typescript@5.9.3) + '@solana/rpc-spec-types': 3.0.3(typescript@5.9.3) + '@solana/rpc-types': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/rpc-transport-http@3.0.3(typescript@5.9.3)': + dependencies: + '@solana/errors': 3.0.3(typescript@5.9.3) + '@solana/rpc-spec': 3.0.3(typescript@5.9.3) + '@solana/rpc-spec-types': 3.0.3(typescript@5.9.3) + typescript: 5.9.3 + undici-types: 7.16.0 + + '@solana/rpc-types@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)': + dependencies: + '@solana/addresses': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/codecs-core': 3.0.3(typescript@5.9.3) + '@solana/codecs-numbers': 3.0.3(typescript@5.9.3) + '@solana/codecs-strings': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/errors': 3.0.3(typescript@5.9.3) + '@solana/nominal-types': 3.0.3(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/rpc@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)': + dependencies: + '@solana/errors': 3.0.3(typescript@5.9.3) + '@solana/fast-stable-stringify': 3.0.3(typescript@5.9.3) + '@solana/functional': 3.0.3(typescript@5.9.3) + '@solana/rpc-api': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/rpc-spec': 3.0.3(typescript@5.9.3) + '@solana/rpc-spec-types': 3.0.3(typescript@5.9.3) + '@solana/rpc-transformers': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/rpc-transport-http': 3.0.3(typescript@5.9.3) + '@solana/rpc-types': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/signers@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)': + dependencies: + '@solana/addresses': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/codecs-core': 3.0.3(typescript@5.9.3) + '@solana/errors': 3.0.3(typescript@5.9.3) + '@solana/instructions': 3.0.3(typescript@5.9.3) + '@solana/keys': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/nominal-types': 3.0.3(typescript@5.9.3) + '@solana/transaction-messages': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/transactions': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/subscribable@3.0.3(typescript@5.9.3)': + dependencies: + '@solana/errors': 3.0.3(typescript@5.9.3) + typescript: 5.9.3 + + '@solana/sysvars@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)': + dependencies: + '@solana/accounts': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/codecs': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/errors': 3.0.3(typescript@5.9.3) + '@solana/rpc-types': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/transaction-confirmation@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))': + dependencies: + '@solana/addresses': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/codecs-strings': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/errors': 3.0.3(typescript@5.9.3) + '@solana/keys': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/promises': 3.0.3(typescript@5.9.3) + '@solana/rpc': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/rpc-subscriptions': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@solana/rpc-types': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/transaction-messages': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/transactions': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + - ws + + '@solana/transaction-messages@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)': + dependencies: + '@solana/addresses': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/codecs-core': 3.0.3(typescript@5.9.3) + '@solana/codecs-data-structures': 3.0.3(typescript@5.9.3) + '@solana/codecs-numbers': 3.0.3(typescript@5.9.3) + '@solana/errors': 3.0.3(typescript@5.9.3) + '@solana/functional': 3.0.3(typescript@5.9.3) + '@solana/instructions': 3.0.3(typescript@5.9.3) + '@solana/nominal-types': 3.0.3(typescript@5.9.3) + '@solana/rpc-types': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/transactions@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)': + dependencies: + '@solana/addresses': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/codecs-core': 3.0.3(typescript@5.9.3) + '@solana/codecs-data-structures': 3.0.3(typescript@5.9.3) + '@solana/codecs-numbers': 3.0.3(typescript@5.9.3) + '@solana/codecs-strings': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/errors': 3.0.3(typescript@5.9.3) + '@solana/functional': 3.0.3(typescript@5.9.3) + '@solana/instructions': 3.0.3(typescript@5.9.3) + '@solana/keys': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/nominal-types': 3.0.3(typescript@5.9.3) + '@solana/rpc-types': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/transaction-messages': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/web3.js@1.98.4(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)': + dependencies: + '@babel/runtime': 7.28.4 + '@noble/curves': 1.9.7 + '@noble/hashes': 1.8.0 + '@solana/buffer-layout': 4.0.1 + '@solana/codecs-numbers': 2.3.0(typescript@5.9.3) + agentkeepalive: 4.6.0 + bn.js: 5.2.2 + borsh: 0.7.0 + bs58: 4.0.1 + buffer: 6.0.3 + fast-stable-stringify: 1.0.0 + jayson: 4.2.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + node-fetch: 2.7.0 + rpc-websockets: 9.3.2 + superstruct: 2.0.2 + transitivePeerDependencies: + - bufferutil + - encoding + - typescript + - utf-8-validate + '@solidity-parser/parser@0.14.5': dependencies: antlr4ts: 0.5.0-alpha.4 '@solidity-parser/parser@0.20.2': {} - '@tanstack/query-core@5.83.0': {} + '@swc/helpers@0.5.17': + dependencies: + tslib: 2.8.1 + + '@tanstack/query-core@5.90.12': {} - '@tanstack/react-query@5.83.0(react@18.3.1)': + '@tanstack/react-query@5.90.12(react@18.3.1)': dependencies: - '@tanstack/query-core': 5.83.0 + '@tanstack/query-core': 5.90.12 react: 18.3.1 - '@tsconfig/node10@1.0.11': {} + '@tsconfig/node10@1.0.12': {} '@tsconfig/node12@1.0.11': {} @@ -7057,46 +7989,46 @@ snapshots: '@tsconfig/node16@1.0.4': {} - '@typechain/ethers-v6@0.5.1(ethers@6.15.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(typechain@8.3.2(typescript@5.8.3))(typescript@5.8.3)': + '@typechain/ethers-v6@0.5.1(ethers@6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(typechain@8.3.2(typescript@5.9.3))(typescript@5.9.3)': dependencies: - ethers: 6.15.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + ethers: 6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) lodash: 4.17.21 - ts-essentials: 7.0.3(typescript@5.8.3) - typechain: 8.3.2(typescript@5.8.3) - typescript: 5.8.3 + ts-essentials: 7.0.3(typescript@5.9.3) + typechain: 8.3.2(typescript@5.9.3) + typescript: 5.9.3 - '@typechain/hardhat@9.1.0(@typechain/ethers-v6@0.5.1(ethers@6.15.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(typechain@8.3.2(typescript@5.8.3))(typescript@5.8.3))(ethers@6.15.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(hardhat@2.26.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.8.3))(typescript@5.8.3)(utf-8-validate@5.0.10))(typechain@8.3.2(typescript@5.8.3))': + '@typechain/hardhat@9.1.0(@typechain/ethers-v6@0.5.1(ethers@6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(typechain@8.3.2(typescript@5.9.3))(typescript@5.9.3))(ethers@6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10))(typechain@8.3.2(typescript@5.9.3))': dependencies: - '@typechain/ethers-v6': 0.5.1(ethers@6.15.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(typechain@8.3.2(typescript@5.8.3))(typescript@5.8.3) - ethers: 6.15.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@typechain/ethers-v6': 0.5.1(ethers@6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(typechain@8.3.2(typescript@5.9.3))(typescript@5.9.3) + ethers: 6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) fs-extra: 9.1.0 - hardhat: 2.26.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.8.3))(typescript@5.8.3)(utf-8-validate@5.0.10) - typechain: 8.3.2(typescript@5.8.3) + hardhat: 2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10) + typechain: 8.3.2(typescript@5.9.3) '@types/babel__core@7.20.5': dependencies: - '@babel/parser': 7.28.0 - '@babel/types': 7.28.2 + '@babel/parser': 7.28.5 + '@babel/types': 7.28.5 '@types/babel__generator': 7.27.0 '@types/babel__template': 7.4.4 - '@types/babel__traverse': 7.20.7 + '@types/babel__traverse': 7.28.0 '@types/babel__generator@7.27.0': dependencies: - '@babel/types': 7.28.2 + '@babel/types': 7.28.5 '@types/babel__template@7.4.4': dependencies: - '@babel/parser': 7.28.0 - '@babel/types': 7.28.2 + '@babel/parser': 7.28.5 + '@babel/types': 7.28.5 - '@types/babel__traverse@7.20.7': + '@types/babel__traverse@7.28.0': dependencies: - '@babel/types': 7.28.2 + '@babel/types': 7.28.5 '@types/bn.js@5.2.0': dependencies: - '@types/node': 20.19.9 + '@types/node': 20.19.27 '@types/chai-as-promised@7.1.8': dependencies: @@ -7104,13 +8036,18 @@ snapshots: '@types/chai@4.3.20': {} - '@types/chai@5.2.2': + '@types/chai@5.2.3': dependencies: '@types/deep-eql': 4.0.2 + assertion-error: 2.0.1 '@types/concat-stream@1.6.1': dependencies: - '@types/node': 20.19.9 + '@types/node': 20.19.27 + + '@types/connect@3.4.38': + dependencies: + '@types/node': 20.19.27 '@types/debug@4.1.12': dependencies: @@ -7122,16 +8059,18 @@ snapshots: '@types/form-data@0.0.33': dependencies: - '@types/node': 20.19.9 + '@types/node': 20.19.27 '@types/glob@7.2.0': dependencies: '@types/minimatch': 6.0.0 - '@types/node': 20.19.9 + '@types/node': 20.19.27 + + '@types/lodash@4.17.21': {} '@types/minimatch@6.0.0': dependencies: - minimatch: 10.0.3 + minimatch: 10.1.1 '@types/mocha@10.0.10': {} @@ -7139,7 +8078,9 @@ snapshots: '@types/node@10.17.60': {} - '@types/node@20.19.9': + '@types/node@12.20.55': {} + + '@types/node@20.19.27': dependencies: undici-types: 6.21.0 @@ -7151,7 +8092,7 @@ snapshots: '@types/pbkdf2@3.1.2': dependencies: - '@types/node': 20.19.9 + '@types/node': 20.19.27 '@types/prettier@2.7.3': {} @@ -7159,21 +8100,31 @@ snapshots: '@types/qs@6.14.0': {} - '@types/react-dom@18.3.7(@types/react@18.3.23)': + '@types/react-dom@18.3.7(@types/react@18.3.27)': dependencies: - '@types/react': 18.3.23 + '@types/react': 18.3.27 - '@types/react@18.3.23': + '@types/react@18.3.27': dependencies: '@types/prop-types': 15.7.15 - csstype: 3.1.3 + csstype: 3.2.3 - '@types/secp256k1@4.0.6': + '@types/secp256k1@4.0.7': dependencies: - '@types/node': 20.19.9 + '@types/node': 20.19.27 '@types/trusted-types@2.0.7': {} + '@types/uuid@8.3.4': {} + + '@types/ws@7.4.7': + dependencies: + '@types/node': 20.19.27 + + '@types/ws@8.18.1': + dependencies: + '@types/node': 20.19.27 + '@uniswap/lib@4.0.1-alpha': {} '@uniswap/v2-core@1.0.1': {} @@ -7194,8 +8145,8 @@ snapshots: '@vanilla-extract/private': 1.0.9 css-what: 6.2.2 cssesc: 3.0.0 - csstype: 3.1.3 - dedent: 1.6.0 + csstype: 3.2.3 + dedent: 1.7.1 deep-object-diff: 1.1.9 deepmerge: 4.3.1 lru-cache: 10.4.3 @@ -7215,33 +8166,33 @@ snapshots: dependencies: '@vanilla-extract/css': 1.17.3 - '@vitejs/plugin-react@4.7.0(vite@5.4.19(@types/node@22.7.5))': + '@vitejs/plugin-react@4.7.0(vite@5.4.21(@types/node@22.7.5))': dependencies: - '@babel/core': 7.28.0 - '@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.28.0) - '@babel/plugin-transform-react-jsx-source': 7.27.1(@babel/core@7.28.0) + '@babel/core': 7.28.5 + '@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-react-jsx-source': 7.27.1(@babel/core@7.28.5) '@rolldown/pluginutils': 1.0.0-beta.27 '@types/babel__core': 7.20.5 react-refresh: 0.17.0 - vite: 5.4.19(@types/node@22.7.5) + vite: 5.4.21(@types/node@22.7.5) transitivePeerDependencies: - supports-color '@vitest/expect@3.2.4': dependencies: - '@types/chai': 5.2.2 + '@types/chai': 5.2.3 '@vitest/spy': 3.2.4 '@vitest/utils': 3.2.4 - chai: 5.2.1 + chai: 5.3.3 tinyrainbow: 2.0.0 - '@vitest/mocker@3.2.4(vite@5.4.19(@types/node@20.19.9))': + '@vitest/mocker@3.2.4(vite@5.4.21(@types/node@20.19.27))': dependencies: '@vitest/spy': 3.2.4 estree-walker: 3.0.3 - magic-string: 0.30.17 + magic-string: 0.30.21 optionalDependencies: - vite: 5.4.19(@types/node@20.19.9) + vite: 5.4.21(@types/node@20.19.27) '@vitest/pretty-format@3.2.4': dependencies: @@ -7251,37 +8202,39 @@ snapshots: dependencies: '@vitest/utils': 3.2.4 pathe: 2.0.3 - strip-literal: 3.0.0 + strip-literal: 3.1.0 '@vitest/snapshot@3.2.4': dependencies: '@vitest/pretty-format': 3.2.4 - magic-string: 0.30.17 + magic-string: 0.30.21 pathe: 2.0.3 '@vitest/spy@3.2.4': dependencies: - tinyspy: 4.0.3 + tinyspy: 4.0.4 '@vitest/utils@3.2.4': dependencies: '@vitest/pretty-format': 3.2.4 - loupe: 3.2.0 + loupe: 3.2.1 tinyrainbow: 2.0.0 - '@wagmi/connectors@5.9.0(@types/react@18.3.23)(@wagmi/core@2.18.0(@tanstack/query-core@5.83.0)(@types/react@18.3.23)(immer@10.0.2)(react@18.3.1)(typescript@5.8.3)(use-sync-external-store@1.4.0(react@18.3.1))(viem@2.37.5(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4)))(bufferutil@4.0.9)(immer@10.0.2)(react@18.3.1)(typescript@5.8.3)(use-sync-external-store@1.4.0(react@18.3.1))(utf-8-validate@5.0.10)(viem@2.37.5(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4))(wagmi@2.16.0(@tanstack/query-core@5.83.0)(@tanstack/react-query@5.83.0(react@18.3.1))(@types/react@18.3.23)(bufferutil@4.0.9)(immer@10.0.2)(react@18.3.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(viem@2.37.5(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4))(zod@3.22.4))(zod@3.22.4)': + '@wagmi/connectors@6.2.0(3e683225d0eaab4e1b5a92e5a7d66afa)': dependencies: - '@base-org/account': 1.0.2(@types/react@18.3.23)(bufferutil@4.0.9)(immer@10.0.2)(react@18.3.1)(typescript@5.8.3)(use-sync-external-store@1.4.0(react@18.3.1))(utf-8-validate@5.0.10)(wagmi@2.16.0(@tanstack/query-core@5.83.0)(@tanstack/react-query@5.83.0(react@18.3.1))(@types/react@18.3.23)(bufferutil@4.0.9)(immer@10.0.2)(react@18.3.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(viem@2.37.5(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4))(zod@3.22.4))(zod@3.22.4) - '@coinbase/wallet-sdk': 4.3.6(@types/react@18.3.23)(bufferutil@4.0.9)(immer@10.0.2)(react@18.3.1)(typescript@5.8.3)(use-sync-external-store@1.4.0(react@18.3.1))(utf-8-validate@5.0.10)(zod@3.22.4) - '@metamask/sdk': 0.32.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) - '@safe-global/safe-apps-provider': 0.18.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) - '@safe-global/safe-apps-sdk': 9.1.0(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) - '@wagmi/core': 2.18.0(@tanstack/query-core@5.83.0)(@types/react@18.3.23)(immer@10.0.2)(react@18.3.1)(typescript@5.8.3)(use-sync-external-store@1.4.0(react@18.3.1))(viem@2.37.5(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4)) - '@walletconnect/ethereum-provider': 2.21.1(@types/react@18.3.23)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) + '@base-org/account': 2.4.0(@types/react@18.3.27)(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(immer@10.0.2)(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)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@4.2.1) + '@coinbase/wallet-sdk': 4.3.6(@types/react@18.3.27)(bufferutil@4.0.9)(immer@10.0.2)(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.2.1) + '@gemini-wallet/core': 0.3.2(viem@2.43.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1)) + '@metamask/sdk': 0.33.1(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@safe-global/safe-apps-provider': 0.18.6(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) + '@safe-global/safe-apps-sdk': 9.1.0(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) + '@wagmi/core': 2.22.1(@tanstack/query-core@5.90.12)(@types/react@18.3.27)(immer@10.0.2)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@18.3.1))(viem@2.43.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1)) + '@walletconnect/ethereum-provider': 2.21.1(@types/react@18.3.27)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) cbw-sdk: '@coinbase/wallet-sdk@3.9.3' - viem: 2.37.5(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) + porto: 0.2.35(@tanstack/react-query@5.90.12(react@18.3.1))(@types/react@18.3.27)(@wagmi/core@2.22.1(@tanstack/query-core@5.90.12)(@types/react@18.3.27)(immer@10.0.2)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@18.3.1))(viem@2.43.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1)))(immer@10.0.2)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@18.3.1))(viem@2.43.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1))(wagmi@2.19.5(@tanstack/query-core@5.90.12)(@tanstack/react-query@5.90.12(react@18.3.1))(@types/react@18.3.27)(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(immer@10.0.2)(react@18.3.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.43.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1))(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@4.2.1)) + viem: 2.43.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) optionalDependencies: - typescript: 5.8.3 + typescript: 5.9.3 transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -7294,40 +8247,49 @@ snapshots: - '@netlify/blobs' - '@planetscale/database' - '@react-native-async-storage/async-storage' + - '@tanstack/react-query' - '@types/react' - '@upstash/redis' - '@vercel/blob' + - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil - db0 + - 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 + - ws - zod - '@wagmi/core@2.18.0(@tanstack/query-core@5.83.0)(@types/react@18.3.23)(immer@10.0.2)(react@18.3.1)(typescript@5.8.3)(use-sync-external-store@1.4.0(react@18.3.1))(viem@2.37.5(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4))': + '@wagmi/core@2.22.1(@tanstack/query-core@5.90.12)(@types/react@18.3.27)(immer@10.0.2)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@18.3.1))(viem@2.43.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1))': dependencies: eventemitter3: 5.0.1 - mipd: 0.0.7(typescript@5.8.3) - viem: 2.37.5(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) - zustand: 5.0.0(@types/react@18.3.23)(immer@10.0.2)(react@18.3.1)(use-sync-external-store@1.4.0(react@18.3.1)) + mipd: 0.0.7(typescript@5.9.3) + viem: 2.43.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) + zustand: 5.0.0(@types/react@18.3.27)(immer@10.0.2)(react@18.3.1)(use-sync-external-store@1.4.0(react@18.3.1)) optionalDependencies: - '@tanstack/query-core': 5.83.0 - typescript: 5.8.3 + '@tanstack/query-core': 5.90.12 + typescript: 5.9.3 transitivePeerDependencies: - '@types/react' - immer - react - use-sync-external-store - '@walletconnect/core@2.21.0(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4)': + '@walletconnect/core@2.21.0(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1)': dependencies: '@walletconnect/heartbeat': 1.2.2 '@walletconnect/jsonrpc-provider': 1.0.14 @@ -7341,7 +8303,7 @@ snapshots: '@walletconnect/safe-json': 1.0.2 '@walletconnect/time': 1.0.2 '@walletconnect/types': 2.21.0 - '@walletconnect/utils': 2.21.0(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) + '@walletconnect/utils': 2.21.0(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) '@walletconnect/window-getters': 1.0.1 es-toolkit: 1.33.0 events: 3.3.0 @@ -7360,6 +8322,7 @@ snapshots: - '@react-native-async-storage/async-storage' - '@upstash/redis' - '@vercel/blob' + - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -7370,7 +8333,7 @@ snapshots: - utf-8-validate - zod - '@walletconnect/core@2.21.1(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4)': + '@walletconnect/core@2.21.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1)': dependencies: '@walletconnect/heartbeat': 1.2.2 '@walletconnect/jsonrpc-provider': 1.0.14 @@ -7384,7 +8347,7 @@ snapshots: '@walletconnect/safe-json': 1.0.2 '@walletconnect/time': 1.0.2 '@walletconnect/types': 2.21.1 - '@walletconnect/utils': 2.21.1(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) + '@walletconnect/utils': 2.21.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) '@walletconnect/window-getters': 1.0.1 es-toolkit: 1.33.0 events: 3.3.0 @@ -7403,6 +8366,7 @@ snapshots: - '@react-native-async-storage/async-storage' - '@upstash/redis' - '@vercel/blob' + - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -7417,18 +8381,18 @@ snapshots: dependencies: tslib: 1.14.1 - '@walletconnect/ethereum-provider@2.21.1(@types/react@18.3.23)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4)': + '@walletconnect/ethereum-provider@2.21.1(@types/react@18.3.27)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1)': dependencies: - '@reown/appkit': 1.7.8(@types/react@18.3.23)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) + '@reown/appkit': 1.7.8(@types/react@18.3.27)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.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/sign-client': 2.21.1(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) + '@walletconnect/sign-client': 2.21.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) '@walletconnect/types': 2.21.1 - '@walletconnect/universal-provider': 2.21.1(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) - '@walletconnect/utils': 2.21.1(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) + '@walletconnect/universal-provider': 2.21.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) + '@walletconnect/utils': 2.21.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) events: 3.3.0 transitivePeerDependencies: - '@azure/app-configuration' @@ -7445,6 +8409,7 @@ snapshots: - '@types/react' - '@upstash/redis' - '@vercel/blob' + - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -7508,7 +8473,7 @@ snapshots: dependencies: '@walletconnect/safe-json': 1.0.2 idb-keyval: 6.2.2 - unstorage: 1.16.1(idb-keyval@6.2.2) + unstorage: 1.17.3(idb-keyval@6.2.2) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -7522,6 +8487,7 @@ snapshots: - '@planetscale/database' - '@upstash/redis' - '@vercel/blob' + - '@vercel/functions' - '@vercel/kv' - aws4fetch - db0 @@ -7549,16 +8515,16 @@ snapshots: dependencies: tslib: 1.14.1 - '@walletconnect/sign-client@2.21.0(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4)': + '@walletconnect/sign-client@2.21.0(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1)': dependencies: - '@walletconnect/core': 2.21.0(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) + '@walletconnect/core': 2.21.0(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) '@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.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) + '@walletconnect/utils': 2.21.0(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) events: 3.3.0 transitivePeerDependencies: - '@azure/app-configuration' @@ -7574,6 +8540,7 @@ snapshots: - '@react-native-async-storage/async-storage' - '@upstash/redis' - '@vercel/blob' + - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -7584,16 +8551,16 @@ snapshots: - utf-8-validate - zod - '@walletconnect/sign-client@2.21.1(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4)': + '@walletconnect/sign-client@2.21.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1)': dependencies: - '@walletconnect/core': 2.21.1(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) + '@walletconnect/core': 2.21.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) '@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.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) + '@walletconnect/utils': 2.21.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) events: 3.3.0 transitivePeerDependencies: - '@azure/app-configuration' @@ -7609,6 +8576,7 @@ snapshots: - '@react-native-async-storage/async-storage' - '@upstash/redis' - '@vercel/blob' + - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -7645,6 +8613,7 @@ snapshots: - '@react-native-async-storage/async-storage' - '@upstash/redis' - '@vercel/blob' + - '@vercel/functions' - '@vercel/kv' - aws4fetch - db0 @@ -7673,13 +8642,14 @@ snapshots: - '@react-native-async-storage/async-storage' - '@upstash/redis' - '@vercel/blob' + - '@vercel/functions' - '@vercel/kv' - aws4fetch - db0 - ioredis - uploadthing - '@walletconnect/universal-provider@2.21.0(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4)': + '@walletconnect/universal-provider@2.21.0(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1)': dependencies: '@walletconnect/events': 1.0.1 '@walletconnect/jsonrpc-http-connection': 1.0.8 @@ -7688,9 +8658,9 @@ snapshots: '@walletconnect/jsonrpc-utils': 1.0.8 '@walletconnect/keyvaluestorage': 1.1.1 '@walletconnect/logger': 2.1.2 - '@walletconnect/sign-client': 2.21.0(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) + '@walletconnect/sign-client': 2.21.0(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) '@walletconnect/types': 2.21.0 - '@walletconnect/utils': 2.21.0(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) + '@walletconnect/utils': 2.21.0(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) es-toolkit: 1.33.0 events: 3.3.0 transitivePeerDependencies: @@ -7707,6 +8677,7 @@ snapshots: - '@react-native-async-storage/async-storage' - '@upstash/redis' - '@vercel/blob' + - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -7718,7 +8689,7 @@ snapshots: - utf-8-validate - zod - '@walletconnect/universal-provider@2.21.1(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4)': + '@walletconnect/universal-provider@2.21.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1)': dependencies: '@walletconnect/events': 1.0.1 '@walletconnect/jsonrpc-http-connection': 1.0.8 @@ -7727,9 +8698,9 @@ snapshots: '@walletconnect/jsonrpc-utils': 1.0.8 '@walletconnect/keyvaluestorage': 1.1.1 '@walletconnect/logger': 2.1.2 - '@walletconnect/sign-client': 2.21.1(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) + '@walletconnect/sign-client': 2.21.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) '@walletconnect/types': 2.21.1 - '@walletconnect/utils': 2.21.1(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) + '@walletconnect/utils': 2.21.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) es-toolkit: 1.33.0 events: 3.3.0 transitivePeerDependencies: @@ -7746,6 +8717,7 @@ snapshots: - '@react-native-async-storage/async-storage' - '@upstash/redis' - '@vercel/blob' + - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -7757,7 +8729,7 @@ snapshots: - utf-8-validate - zod - '@walletconnect/utils@2.21.0(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4)': + '@walletconnect/utils@2.21.0(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1)': dependencies: '@noble/ciphers': 1.2.1 '@noble/curves': 1.8.1 @@ -7775,7 +8747,7 @@ snapshots: detect-browser: 5.3.0 query-string: 7.1.3 uint8arrays: 3.1.0 - viem: 2.23.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) + viem: 2.23.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -7790,6 +8762,7 @@ snapshots: - '@react-native-async-storage/async-storage' - '@upstash/redis' - '@vercel/blob' + - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -7800,7 +8773,7 @@ snapshots: - utf-8-validate - zod - '@walletconnect/utils@2.21.1(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4)': + '@walletconnect/utils@2.21.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1)': dependencies: '@noble/ciphers': 1.2.1 '@noble/curves': 1.8.1 @@ -7818,7 +8791,7 @@ snapshots: detect-browser: 5.3.0 query-string: 7.1.3 uint8arrays: 3.1.0 - viem: 2.23.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) + viem: 2.23.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -7833,6 +8806,7 @@ snapshots: - '@react-native-async-storage/async-storage' - '@upstash/redis' - '@vercel/blob' + - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -7854,16 +8828,31 @@ snapshots: abbrev@1.0.9: {} - abitype@1.0.8(typescript@5.8.3)(zod@3.22.4): + abitype@1.0.6(typescript@5.9.3)(zod@3.25.76): optionalDependencies: - typescript: 5.8.3 - zod: 3.22.4 + typescript: 5.9.3 + zod: 3.25.76 - abitype@1.1.0(typescript@5.8.3)(zod@3.22.4): + abitype@1.0.8(typescript@5.9.3)(zod@4.2.1): optionalDependencies: - typescript: 5.8.3 + typescript: 5.9.3 + zod: 4.2.1 + + 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.2.1): + optionalDependencies: + typescript: 5.9.3 + zod: 4.2.1 + acorn-walk@8.3.4: dependencies: acorn: 8.15.0 @@ -7878,10 +8867,14 @@ snapshots: agent-base@6.0.2: dependencies: - debug: 4.4.1(supports-color@8.1.1) + debug: 4.4.3(supports-color@8.1.1) transitivePeerDependencies: - supports-color + agentkeepalive@4.6.0: + dependencies: + humanize-ms: 1.2.1 + aggregate-error@3.1.0: dependencies: clean-stack: 2.2.0 @@ -7890,11 +8883,11 @@ snapshots: ajv@8.17.1: dependencies: fast-deep-equal: 3.1.3 - fast-uri: 3.0.6 + fast-uri: 3.1.0 json-schema-traverse: 1.0.0 require-from-string: 2.0.2 - amazon-cognito-identity-js@6.3.15: + amazon-cognito-identity-js@6.3.16: dependencies: '@aws-crypto/sha256-js': 1.2.2 buffer: 4.9.2 @@ -7921,8 +8914,6 @@ snapshots: ansi-regex@5.0.1: {} - ansi-regex@6.1.0: {} - ansi-styles@3.2.1: dependencies: color-convert: 1.9.3 @@ -7931,8 +8922,6 @@ snapshots: dependencies: color-convert: 2.0.1 - ansi-styles@6.2.1: {} - antlr4ts@0.5.0-alpha.4: {} any-promise@1.3.0: {} @@ -7991,12 +8980,11 @@ snapshots: atomic-sleep@1.0.0: {} - autoprefixer@10.4.21(postcss@8.5.6): + autoprefixer@10.4.23(postcss@8.5.6): dependencies: - browserslist: 4.25.1 - caniuse-lite: 1.0.30001727 - fraction.js: 4.3.7 - normalize-range: 0.1.2 + browserslist: 4.28.1 + caniuse-lite: 1.0.30001760 + fraction.js: 5.3.4 picocolors: 1.1.1 postcss: 8.5.6 postcss-value-parser: 4.2.0 @@ -8005,10 +8993,15 @@ snapshots: dependencies: possible-typed-array-names: 1.1.0 - axios@1.11.0(debug@4.4.1): + axios-retry@4.5.0(axios@1.13.2): + dependencies: + axios: 1.13.2(debug@4.4.3) + is-retry-allowed: 2.2.0 + + axios@1.13.2(debug@4.4.3): dependencies: - follow-redirects: 1.15.9(debug@4.4.1) - form-data: 4.0.4 + follow-redirects: 1.15.11(debug@4.4.3) + form-data: 4.0.5 proxy-from-env: 1.1.0 transitivePeerDependencies: - debug @@ -8025,6 +9018,8 @@ snapshots: base64-sol@1.0.1: {} + baseline-browser-mapping@2.9.10: {} + bech32@1.1.4: {} big.js@6.2.2: {} @@ -8041,7 +9036,13 @@ snapshots: bn.js@5.2.2: {} - bowser@2.11.0: {} + borsh@0.7.0: + dependencies: + bn.js: 5.2.2 + bs58: 4.0.1 + text-encoding-utf-8: 1.0.2 + + bowser@2.13.1: {} boxen@5.1.2: dependencies: @@ -8074,18 +9075,19 @@ snapshots: browserify-aes@1.2.0: dependencies: buffer-xor: 1.0.3 - cipher-base: 1.0.6 + cipher-base: 1.0.7 create-hash: 1.2.0 evp_bytestokey: 1.0.3 inherits: 2.0.4 safe-buffer: 5.2.1 - browserslist@4.25.1: + browserslist@4.28.1: dependencies: - caniuse-lite: 1.0.30001727 - electron-to-chromium: 1.5.191 - node-releases: 2.0.19 - update-browserslist-db: 1.1.3(browserslist@4.25.1) + baseline-browser-mapping: 2.9.10 + caniuse-lite: 1.0.30001760 + electron-to-chromium: 1.5.267 + node-releases: 2.0.27 + update-browserslist-db: 1.2.3(browserslist@4.28.1) bs58@4.0.1: dependencies: @@ -8147,11 +9149,11 @@ snapshots: camelcase@6.3.0: {} - caniuse-lite@1.0.30001727: {} + caniuse-lite@1.0.30001760: {} caseless@0.12.0: {} - cbor@10.0.9: + cbor@10.0.11: dependencies: nofilter: 3.1.0 @@ -8178,12 +9180,12 @@ snapshots: pathval: 1.1.1 type-detect: 4.1.0 - chai@5.2.1: + chai@5.3.3: dependencies: assertion-error: 2.0.1 check-error: 2.1.1 deep-eql: 5.0.2 - loupe: 3.2.0 + loupe: 3.2.1 pathval: 2.0.1 chalk@2.4.2: @@ -8197,6 +9199,8 @@ snapshots: ansi-styles: 4.3.0 supports-color: 7.2.0 + chalk@5.6.2: {} + charenc@0.0.2: {} check-error@1.0.3: @@ -8223,10 +9227,11 @@ snapshots: ci-info@2.0.0: {} - cipher-base@1.0.6: + cipher-base@1.0.7: dependencies: inherits: 2.0.4 safe-buffer: 5.2.1 + to-buffer: 1.2.2 clean-stack@2.2.0: {} @@ -8289,6 +9294,12 @@ snapshots: table-layout: 1.0.2 typical: 5.2.0 + commander@14.0.0: {} + + commander@14.0.2: {} + + commander@2.20.3: {} + commander@4.1.1: {} commander@8.3.0: {} @@ -8314,27 +9325,20 @@ snapshots: crc-32@1.2.2: {} - create-hash@1.1.3: - dependencies: - cipher-base: 1.0.6 - inherits: 2.0.4 - ripemd160: 2.0.1 - sha.js: 2.4.12 - create-hash@1.2.0: dependencies: - cipher-base: 1.0.6 + cipher-base: 1.0.7 inherits: 2.0.4 md5.js: 1.3.5 - ripemd160: 2.0.2 + ripemd160: 2.0.3 sha.js: 2.4.12 create-hmac@1.1.7: dependencies: - cipher-base: 1.0.6 + cipher-base: 1.0.7 create-hash: 1.2.0 inherits: 2.0.4 - ripemd160: 2.0.2 + ripemd160: 2.0.3 safe-buffer: 5.2.1 sha.js: 2.4.12 @@ -8352,12 +9356,6 @@ snapshots: 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 @@ -8368,29 +9366,29 @@ snapshots: cssesc@3.0.0: {} - csstype@3.1.3: {} + csstype@3.2.3: {} - cuer@0.0.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.8.3): + cuer@0.0.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3): dependencies: - qr: 0.5.0 + qr: 0.5.3 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - typescript: 5.8.3 + typescript: 5.9.3 date-fns@2.30.0: dependencies: - '@babel/runtime': 7.28.2 + '@babel/runtime': 7.28.4 dayjs@1.11.13: {} death@1.1.0: {} - debug@4.3.7: + debug@4.3.4: dependencies: - ms: 2.1.3 + ms: 2.1.2 - debug@4.4.1(supports-color@8.1.1): + debug@4.4.3(supports-color@8.1.1): dependencies: ms: 2.1.3 optionalDependencies: @@ -8402,7 +9400,7 @@ snapshots: decode-uri-component@0.2.2: {} - dedent@1.6.0: {} + dedent@1.7.1: {} deep-eql@4.1.4: dependencies: @@ -8426,13 +9424,15 @@ snapshots: defu@6.1.4: {} + delay@5.0.0: {} + delayed-stream@1.0.0: {} depd@2.0.0: {} - derive-valtio@0.1.0(valtio@1.13.2(@types/react@18.3.23)(react@18.3.1)): + derive-valtio@0.1.0(valtio@1.13.2(@types/react@18.3.27)(react@18.3.1)): dependencies: - valtio: 1.13.2(@types/react@18.3.23)(react@18.3.1) + valtio: 1.13.2(@types/react@18.3.27)(react@18.3.1) destr@2.0.5: {} @@ -8440,7 +9440,7 @@ snapshots: detect-node-es@1.1.0: {} - dexie@4.0.11: {} + dexie@4.2.1: {} didyoumean@1.2.2: {} @@ -8475,16 +9475,14 @@ snapshots: readable-stream: 3.6.2 stream-shift: 1.0.3 - eastasianwidth@0.2.0: {} - - eciesjs@0.4.15: + eciesjs@0.4.16: dependencies: - '@ecies/ciphers': 0.2.4(@noble/ciphers@1.3.0) + '@ecies/ciphers': 0.2.5(@noble/ciphers@1.3.0) '@noble/ciphers': 1.3.0 - '@noble/curves': 1.9.4 + '@noble/curves': 1.9.7 '@noble/hashes': 1.8.0 - electron-to-chromium@1.5.191: {} + electron-to-chromium@1.5.267: {} elliptic@6.6.1: dependencies: @@ -8498,8 +9496,6 @@ snapshots: emoji-regex@8.0.0: {} - emoji-regex@9.2.2: {} - encode-utf8@1.0.3: {} end-of-stream@1.4.5: @@ -8509,7 +9505,7 @@ snapshots: engine.io-client@6.6.3(bufferutil@4.0.9)(utf-8-validate@5.0.10): dependencies: '@socket.io/component-emitter': 3.1.2 - debug: 4.3.7 + debug: 4.3.4 engine.io-parser: 5.2.3 ws: 8.17.1(bufferutil@4.0.9)(utf-8-validate@5.0.10) xmlhttprequest-ssl: 2.1.2 @@ -8546,6 +9542,12 @@ snapshots: es-toolkit@1.33.0: {} + es6-promise@4.2.8: {} + + es6-promisify@5.0.0: + dependencies: + es6-promise: 4.2.8 + esbuild@0.21.5: optionalDependencies: '@esbuild/aix-ppc64': 0.21.5 @@ -8612,7 +9614,7 @@ snapshots: eth-gas-reporter@0.2.27(bufferutil@4.0.9)(utf-8-validate@5.0.10): dependencies: '@solidity-parser/parser': 0.14.5 - axios: 1.11.0(debug@4.4.1) + axios: 1.13.2(debug@4.4.3) cli-table3: 0.5.1 colors: 1.4.0 ethereum-cryptography: 1.2.0 @@ -8653,7 +9655,7 @@ snapshots: ethereum-cryptography@0.1.3: dependencies: '@types/pbkdf2': 3.1.2 - '@types/secp256k1': 4.0.6 + '@types/secp256k1': 4.0.7 blakejs: 1.2.1 browserify-aes: 1.2.0 bs58check: 2.1.2 @@ -8661,7 +9663,7 @@ snapshots: create-hmac: 1.1.7 hash.js: 1.1.7 keccak: 3.0.4 - pbkdf2: 3.1.3 + pbkdf2: 3.1.5 randombytes: 2.1.0 safe-buffer: 5.2.1 scrypt-js: 3.0.1 @@ -8726,7 +9728,7 @@ snapshots: - bufferutil - utf-8-validate - ethers@6.15.0(bufferutil@4.0.9)(utf-8-validate@5.0.10): + ethers@6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10): dependencies: '@adraffy/ens-normalize': 1.10.1 '@noble/curves': 1.2.0 @@ -8755,13 +9757,15 @@ snapshots: md5.js: 1.3.5 safe-buffer: 5.2.1 - expect-type@1.2.2: {} + expect-type@1.3.0: {} extension-port-stream@3.0.0: dependencies: readable-stream: 3.6.2 webextension-polyfill: 0.10.0 + eyes@0.1.8: {} + fast-base64-decode@1.0.0: {} fast-deep-equal@3.1.3: {} @@ -8780,17 +9784,21 @@ snapshots: fast-safe-stringify@2.1.1: {} - fast-uri@3.0.6: {} + fast-stable-stringify@1.0.0: {} + + fast-uri@3.1.0: {} fast-xml-parser@5.2.5: dependencies: - strnum: 2.1.1 + strnum: 2.1.2 + + fastestsmallesttextencoderdecoder@1.0.22: {} fastq@1.19.1: dependencies: reusify: 1.1.0 - fdir@6.4.6(picomatch@4.0.3): + fdir@6.5.0(picomatch@4.0.3): optionalDependencies: picomatch: 4.0.3 @@ -8816,19 +9824,14 @@ snapshots: flat@5.0.2: {} - follow-redirects@1.15.9(debug@4.4.1): + follow-redirects@1.15.11(debug@4.4.3): optionalDependencies: - debug: 4.4.1(supports-color@8.1.1) + debug: 4.4.3(supports-color@8.1.1) for-each@0.3.5: dependencies: is-callable: 1.2.7 - foreground-child@3.3.1: - dependencies: - cross-spawn: 7.0.6 - signal-exit: 4.1.0 - form-data@2.5.5: dependencies: asynckit: 0.4.0 @@ -8838,7 +9841,7 @@ snapshots: mime-types: 2.1.35 safe-buffer: 5.2.1 - form-data@4.0.4: + form-data@4.0.5: dependencies: asynckit: 0.4.0 combined-stream: 1.0.8 @@ -8848,11 +9851,11 @@ snapshots: fp-ts@1.19.3: {} - fraction.js@4.3.7: {} + fraction.js@5.3.4: {} - framer-motion@12.23.9(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + framer-motion@12.23.26(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: - motion-dom: 12.23.9 + motion-dom: 12.23.23 motion-utils: 12.23.6 tslib: 2.8.1 optionalDependencies: @@ -8862,7 +9865,7 @@ snapshots: fs-extra@10.1.0: dependencies: graceful-fs: 4.2.11 - jsonfile: 6.1.0 + jsonfile: 6.2.0 universalify: 2.0.1 fs-extra@7.0.1: @@ -8881,7 +9884,7 @@ snapshots: dependencies: at-least-node: 1.0.0 graceful-fs: 4.2.11 - jsonfile: 6.1.0 + jsonfile: 6.2.0 universalify: 2.0.1 fs-readdir-recursive@1.1.0: {} @@ -8893,6 +9896,8 @@ snapshots: function-bind@1.1.2: {} + generator-function@2.0.1: {} + gensync@1.0.0-beta.2: {} get-caller-file@2.0.5: {} @@ -8934,15 +9939,6 @@ snapshots: dependencies: is-glob: 4.0.3 - glob@10.4.5: - dependencies: - foreground-child: 3.3.1 - jackspeak: 3.4.3 - minimatch: 9.0.5 - minipass: 7.1.2 - package-json-from-dist: 1.0.1 - path-scurry: 1.11.1 - glob@5.0.15: dependencies: inflight: 1.0.6 @@ -9002,14 +9998,14 @@ snapshots: graceful-fs@4.2.11: {} - h3@1.15.3: + h3@1.15.4: dependencies: cookie-es: 1.2.2 crossws: 0.3.5 defu: 6.1.4 destr: 2.0.5 iron-webcrypto: 1.2.1 - node-mock-http: 1.0.1 + node-mock-http: 1.0.4 radix3: 1.1.2 ufo: 1.6.1 uncrypto: 0.1.3 @@ -9023,15 +10019,15 @@ snapshots: optionalDependencies: uglify-js: 3.19.3 - hardhat-dependency-compiler@1.2.1(hardhat@2.26.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.8.3))(typescript@5.8.3)(utf-8-validate@5.0.10)): + hardhat-dependency-compiler@1.2.1(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10)): dependencies: - hardhat: 2.26.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.8.3))(typescript@5.8.3)(utf-8-validate@5.0.10) + hardhat: 2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10) - hardhat-gas-reporter@1.0.10(bufferutil@4.0.9)(hardhat@2.26.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.8.3))(typescript@5.8.3)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10): + hardhat-gas-reporter@1.0.10(bufferutil@4.0.9)(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10): dependencies: array-uniq: 1.0.3 eth-gas-reporter: 0.2.27(bufferutil@4.0.9)(utf-8-validate@5.0.10) - hardhat: 2.26.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.8.3))(typescript@5.8.3)(utf-8-validate@5.0.10) + hardhat: 2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10) sha1: 1.1.1 transitivePeerDependencies: - '@codechecks/client' @@ -9039,11 +10035,11 @@ snapshots: - debug - utf-8-validate - hardhat@2.26.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.8.3))(typescript@5.8.3)(utf-8-validate@5.0.10): + hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10): dependencies: '@ethereumjs/util': 9.1.0 '@ethersproject/abi': 5.8.0 - '@nomicfoundation/edr': 0.11.3 + '@nomicfoundation/edr': 0.12.0-next.17 '@nomicfoundation/solidity-analyzer': 0.1.2 '@sentry/node': 5.30.0 adm-zip: 0.4.16 @@ -9052,7 +10048,7 @@ snapshots: boxen: 5.1.2 chokidar: 4.0.3 ci-info: 2.0.0 - debug: 4.4.1(supports-color@8.1.1) + debug: 4.4.3(supports-color@8.1.1) enquirer: 2.4.1 env-paths: 2.2.1 ethereum-cryptography: 1.2.0 @@ -9069,20 +10065,20 @@ snapshots: mocha: 10.8.2 p-map: 4.0.0 picocolors: 1.1.1 - raw-body: 2.5.2 + raw-body: 2.5.3 resolve: 1.17.0 semver: 6.3.1 - solc: 0.8.26(debug@4.4.1) + solc: 0.8.26(debug@4.4.3) source-map-support: 0.5.21 stacktrace-parser: 0.1.11 - tinyglobby: 0.2.14 + tinyglobby: 0.2.15 tsort: 0.0.1 undici: 5.29.0 uuid: 8.3.2 ws: 7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10) optionalDependencies: - ts-node: 10.9.2(@types/node@22.7.5)(typescript@5.8.3) - typescript: 5.8.3 + ts-node: 10.9.2(@types/node@22.7.5)(typescript@5.9.3) + typescript: 5.9.3 transitivePeerDependencies: - bufferutil - supports-color @@ -9104,15 +10100,12 @@ snapshots: dependencies: has-symbols: 1.1.0 - hash-base@2.0.2: + hash-base@3.1.2: dependencies: inherits: 2.0.4 - - hash-base@3.1.0: - dependencies: - inherits: 2.0.4 - readable-stream: 3.6.2 + readable-stream: 2.3.8 safe-buffer: 5.2.1 + to-buffer: 1.2.2 hash.js@1.1.7: dependencies: @@ -9133,6 +10126,8 @@ snapshots: minimalistic-assert: 1.0.1 minimalistic-crypto-utils: 1.0.1 + hono@4.11.1: {} + http-basic@8.1.3: dependencies: caseless: 0.12.0 @@ -9140,12 +10135,12 @@ snapshots: http-response-object: 3.0.2 parse-cache-control: 1.0.1 - http-errors@2.0.0: + http-errors@2.0.1: dependencies: depd: 2.0.0 inherits: 2.0.4 setprototypeof: 1.2.0 - statuses: 2.0.1 + statuses: 2.0.2 toidentifier: 1.0.1 http-response-object@3.0.2: @@ -9155,10 +10150,14 @@ snapshots: https-proxy-agent@5.0.1: dependencies: agent-base: 6.0.2 - debug: 4.4.1(supports-color@8.1.1) + debug: 4.4.3(supports-color@8.1.1) transitivePeerDependencies: - supports-color + humanize-ms@1.2.1: + dependencies: + ms: 2.1.3 + iconv-lite@0.4.24: dependencies: safer-buffer: 2.1.2 @@ -9203,6 +10202,8 @@ snapshots: dependencies: binary-extensions: 2.3.0 + is-buffer@1.1.6: {} + is-callable@1.2.7: {} is-core-module@2.16.1: @@ -9215,9 +10216,10 @@ snapshots: is-fullwidth-code-point@3.0.0: {} - is-generator-function@1.1.0: + is-generator-function@1.1.2: dependencies: call-bound: 1.0.4 + generator-function: 2.0.1 get-proto: 1.0.1 has-tostringtag: 1.0.2 safe-regex-test: 1.1.0 @@ -9239,6 +10241,8 @@ snapshots: has-tostringtag: 1.0.2 hasown: 2.0.2 + is-retry-allowed@2.2.0: {} + is-stream@2.0.1: {} is-typed-array@1.1.15: @@ -9260,6 +10264,10 @@ snapshots: transitivePeerDependencies: - encoding + isomorphic-ws@4.0.1(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10)): + dependencies: + ws: 7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10) + isows@1.0.6(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)): dependencies: ws: 8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) @@ -9268,14 +10276,28 @@ snapshots: dependencies: ws: 8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10) - jackspeak@3.4.3: + jayson@4.2.0(bufferutil@4.0.9)(utf-8-validate@5.0.10): dependencies: - '@isaacs/cliui': 8.0.2 - optionalDependencies: - '@pkgjs/parseargs': 0.11.0 + '@types/connect': 3.4.38 + '@types/node': 12.20.55 + '@types/ws': 7.4.7 + commander: 2.20.3 + delay: 5.0.0 + es6-promisify: 5.0.0 + eyes: 0.1.8 + isomorphic-ws: 4.0.1(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + json-stringify-safe: 5.0.1 + stream-json: 1.9.1 + uuid: 8.3.2 + ws: 7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10) + transitivePeerDependencies: + - bufferutil + - utf-8-validate jiti@1.21.7: {} + jose@6.1.3: {} + js-cookie@2.2.1: {} js-sha3@0.8.0: {} @@ -9284,12 +10306,12 @@ snapshots: js-tokens@9.0.1: {} - js-yaml@3.14.1: + js-yaml@3.14.2: dependencies: argparse: 1.0.10 esprima: 4.0.1 - js-yaml@4.1.0: + js-yaml@4.1.1: dependencies: argparse: 2.0.1 @@ -9314,7 +10336,7 @@ snapshots: optionalDependencies: graceful-fs: 4.2.11 - jsonfile@6.1.0: + jsonfile@6.2.0: dependencies: universalify: 2.0.1 optionalDependencies: @@ -9390,7 +10412,7 @@ snapshots: dependencies: get-func-name: 2.0.2 - loupe@3.2.0: {} + loupe@3.2.1: {} lru-cache@10.4.3: {} @@ -9404,9 +10426,9 @@ snapshots: dependencies: react: 18.3.1 - magic-string@0.30.17: + magic-string@0.30.21: dependencies: - '@jridgewell/sourcemap-codec': 1.5.4 + '@jridgewell/sourcemap-codec': 1.5.5 make-error@1.3.6: {} @@ -9416,13 +10438,19 @@ snapshots: md5.js@1.3.5: dependencies: - hash-base: 3.1.0 + hash-base: 3.1.2 inherits: 2.0.4 safe-buffer: 5.2.1 + md5@2.3.0: + dependencies: + charenc: 0.0.2 + crypt: 0.0.2 + is-buffer: 1.1.6 + media-query-parser@2.0.2: dependencies: - '@babel/runtime': 7.28.2 + '@babel/runtime': 7.28.4 memorystream@0.3.1: {} @@ -9455,7 +10483,7 @@ snapshots: minimalistic-crypto-utils@1.0.1: {} - minimatch@10.0.3: + minimatch@10.1.1: dependencies: '@isaacs/brace-expansion': 5.0.0 @@ -9473,11 +10501,9 @@ snapshots: minimist@1.2.8: {} - minipass@7.1.2: {} - - mipd@0.0.7(typescript@5.8.3): + mipd@0.0.7(typescript@5.9.3): optionalDependencies: - typescript: 5.8.3 + typescript: 5.9.3 mkdirp@0.5.6: dependencies: @@ -9494,13 +10520,13 @@ snapshots: ansi-colors: 4.1.3 browser-stdout: 1.3.1 chokidar: 3.6.0 - debug: 4.4.1(supports-color@8.1.1) + debug: 4.4.3(supports-color@8.1.1) diff: 5.2.0 escape-string-regexp: 4.0.0 find-up: 5.0.0 glob: 8.1.0 he: 1.2.0 - js-yaml: 4.1.0 + js-yaml: 4.1.1 log-symbols: 4.1.0 minimatch: 5.1.6 ms: 2.1.3 @@ -9514,12 +10540,14 @@ snapshots: modern-ahocorasick@1.1.0: {} - motion-dom@12.23.9: + motion-dom@12.23.23: dependencies: motion-utils: 12.23.6 motion-utils@12.23.6: {} + ms@2.1.2: {} + ms@2.1.3: {} multiformats@9.9.0: {} @@ -9550,7 +10578,7 @@ snapshots: dependencies: lodash: 4.17.21 - node-fetch-native@1.6.6: {} + node-fetch-native@1.6.7: {} node-fetch@2.7.0: dependencies: @@ -9558,9 +10586,9 @@ snapshots: node-gyp-build@4.8.4: {} - node-mock-http@1.0.1: {} + node-mock-http@1.0.4: {} - node-releases@2.0.19: {} + node-releases@2.0.27: {} nofilter@3.1.0: {} @@ -9570,8 +10598,6 @@ snapshots: normalize-path@3.0.0: {} - normalize-range@0.1.2: {} - number-to-bn@1.7.0: dependencies: bn.js: 4.11.6 @@ -9591,10 +10617,10 @@ snapshots: obliterator@2.0.5: {} - ofetch@1.4.1: + ofetch@1.5.1: dependencies: destr: 2.0.5 - node-fetch-native: 1.6.6 + node-fetch-native: 1.6.7 ufo: 1.6.1 on-exit-leak-free@0.2.0: {} @@ -9603,6 +10629,12 @@ snapshots: dependencies: wrappy: 1.0.2 + openapi-fetch@0.13.8: + dependencies: + openapi-typescript-helpers: 0.0.15 + + openapi-typescript-helpers@0.0.15: {} + optionator@0.8.3: dependencies: deep-is: 0.1.4 @@ -9616,46 +10648,91 @@ snapshots: os-tmpdir@1.0.2: {} - ox@0.6.7(typescript@5.8.3)(zod@3.22.4): + ox@0.10.5(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.10.5(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.10.5(typescript@5.9.3)(zod@4.2.1): dependencies: - '@adraffy/ens-normalize': 1.11.0 - '@noble/curves': 1.9.4 + '@adraffy/ens-normalize': 1.11.1 + '@noble/ciphers': 1.3.0 + '@noble/curves': 1.9.1 '@noble/hashes': 1.8.0 '@scure/bip32': 1.7.0 '@scure/bip39': 1.6.0 - abitype: 1.1.0(typescript@5.8.3)(zod@3.22.4) + abitype: 1.2.3(typescript@5.9.3)(zod@4.2.1) eventemitter3: 5.0.1 optionalDependencies: - typescript: 5.8.3 + typescript: 5.9.3 transitivePeerDependencies: - zod - ox@0.6.9(typescript@5.8.3)(zod@3.22.4): + ox@0.6.7(typescript@5.9.3)(zod@4.2.1): dependencies: - '@adraffy/ens-normalize': 1.11.0 - '@noble/curves': 1.9.4 + '@adraffy/ens-normalize': 1.11.1 + '@noble/curves': 1.8.1 + '@noble/hashes': 1.8.0 + '@scure/bip32': 1.6.2 + '@scure/bip39': 1.5.4 + abitype: 1.0.8(typescript@5.9.3)(zod@4.2.1) + eventemitter3: 5.0.1 + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - zod + + ox@0.6.9(typescript@5.9.3)(zod@4.2.1): + dependencies: + '@adraffy/ens-normalize': 1.11.1 + '@noble/curves': 1.9.7 '@noble/hashes': 1.8.0 '@scure/bip32': 1.7.0 '@scure/bip39': 1.6.0 - abitype: 1.1.0(typescript@5.8.3)(zod@3.22.4) + abitype: 1.2.3(typescript@5.9.3)(zod@4.2.1) eventemitter3: 5.0.1 optionalDependencies: - typescript: 5.8.3 + typescript: 5.9.3 transitivePeerDependencies: - zod - ox@0.9.3(typescript@5.8.3)(zod@3.22.4): + ox@0.9.17(typescript@5.9.3)(zod@4.2.1): dependencies: - '@adraffy/ens-normalize': 1.11.0 + '@adraffy/ens-normalize': 1.11.1 '@noble/ciphers': 1.3.0 '@noble/curves': 1.9.1 '@noble/hashes': 1.8.0 '@scure/bip32': 1.7.0 '@scure/bip39': 1.6.0 - abitype: 1.1.0(typescript@5.8.3)(zod@3.22.4) + abitype: 1.2.3(typescript@5.9.3)(zod@4.2.1) eventemitter3: 5.0.1 optionalDependencies: - typescript: 5.8.3 + typescript: 5.9.3 transitivePeerDependencies: - zod @@ -9681,23 +10758,14 @@ snapshots: p-try@2.2.0: {} - package-json-from-dist@1.0.1: {} - parse-cache-control@1.0.1: {} path-exists@4.0.0: {} path-is-absolute@1.0.1: {} - path-key@3.1.1: {} - path-parse@1.0.7: {} - path-scurry@1.11.1: - dependencies: - lru-cache: 10.4.3 - minipass: 7.1.2 - path-type@4.0.0: {} pathe@2.0.3: {} @@ -9706,14 +10774,14 @@ snapshots: pathval@2.0.1: {} - pbkdf2@3.1.3: + pbkdf2@3.1.5: dependencies: - create-hash: 1.1.3 + create-hash: 1.2.0 create-hmac: 1.1.7 - ripemd160: 2.0.1 + ripemd160: 2.0.3 safe-buffer: 5.2.1 sha.js: 2.4.12 - to-buffer: 1.2.1 + to-buffer: 1.2.2 picocolors@1.1.1: {} @@ -9756,6 +10824,26 @@ snapshots: pony-cause@2.1.11: {} + porto@0.2.35(@tanstack/react-query@5.90.12(react@18.3.1))(@types/react@18.3.27)(@wagmi/core@2.22.1(@tanstack/query-core@5.90.12)(@types/react@18.3.27)(immer@10.0.2)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@18.3.1))(viem@2.43.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1)))(immer@10.0.2)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@18.3.1))(viem@2.43.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1))(wagmi@2.19.5(@tanstack/query-core@5.90.12)(@tanstack/react-query@5.90.12(react@18.3.1))(@types/react@18.3.27)(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(immer@10.0.2)(react@18.3.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.43.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1))(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@4.2.1)): + dependencies: + '@wagmi/core': 2.22.1(@tanstack/query-core@5.90.12)(@types/react@18.3.27)(immer@10.0.2)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@18.3.1))(viem@2.43.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1)) + hono: 4.11.1 + idb-keyval: 6.2.2 + mipd: 0.0.7(typescript@5.9.3) + ox: 0.9.17(typescript@5.9.3)(zod@4.2.1) + viem: 2.43.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) + zod: 4.2.1 + zustand: 5.0.9(@types/react@18.3.27)(immer@10.0.2)(react@18.3.1)(use-sync-external-store@1.4.0(react@18.3.1)) + optionalDependencies: + '@tanstack/react-query': 5.90.12(react@18.3.1) + react: 18.3.1 + typescript: 5.9.3 + wagmi: 2.19.5(@tanstack/query-core@5.90.12)(@tanstack/react-query@5.90.12(react@18.3.1))(@types/react@18.3.27)(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(immer@10.0.2)(react@18.3.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.43.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1))(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@4.2.1) + transitivePeerDependencies: + - '@types/react' + - immer + - use-sync-external-store + possible-typed-array-names@1.1.0: {} postcss-import@15.1.0(postcss@8.5.6): @@ -9763,20 +10851,19 @@ snapshots: postcss: 8.5.6 postcss-value-parser: 4.2.0 read-cache: 1.0.0 - resolve: 1.22.10 + resolve: 1.22.11 - postcss-js@4.0.1(postcss@8.5.6): + postcss-js@4.1.0(postcss@8.5.6): dependencies: camelcase-css: 2.0.1 postcss: 8.5.6 - postcss-load-config@4.0.2(postcss@8.5.6)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.8.3)): + postcss-load-config@6.0.1(jiti@1.21.7)(postcss@8.5.6): dependencies: lilconfig: 3.1.3 - yaml: 2.8.0 optionalDependencies: + jiti: 1.21.7 postcss: 8.5.6 - ts-node: 10.9.2(@types/node@22.7.5)(typescript@5.8.3) postcss-nested@6.2.0(postcss@8.5.6): dependencies: @@ -9798,7 +10885,7 @@ snapshots: preact@10.24.2: {} - preact@10.26.9: {} + preact@10.28.0: {} prelude-ls@1.1.2: {} @@ -9840,7 +10927,7 @@ snapshots: pvutils@1.1.5: optional: true - qr@0.5.0: {} + qr@0.5.3: {} qrcode@1.5.3: dependencies: @@ -9870,10 +10957,10 @@ snapshots: dependencies: safe-buffer: 5.2.1 - raw-body@2.5.2: + raw-body@2.5.3: dependencies: bytes: 3.1.2 - http-errors: 2.0.0 + http-errors: 2.0.1 iconv-lite: 0.4.24 unpipe: 1.0.0 @@ -9885,32 +10972,32 @@ snapshots: react-refresh@0.17.0: {} - react-remove-scroll-bar@2.3.8(@types/react@18.3.23)(react@18.3.1): + react-remove-scroll-bar@2.3.8(@types/react@18.3.27)(react@18.3.1): dependencies: react: 18.3.1 - react-style-singleton: 2.2.3(@types/react@18.3.23)(react@18.3.1) + react-style-singleton: 2.2.3(@types/react@18.3.27)(react@18.3.1) tslib: 2.8.1 optionalDependencies: - '@types/react': 18.3.23 + '@types/react': 18.3.27 - react-remove-scroll@2.6.2(@types/react@18.3.23)(react@18.3.1): + react-remove-scroll@2.6.2(@types/react@18.3.27)(react@18.3.1): dependencies: react: 18.3.1 - react-remove-scroll-bar: 2.3.8(@types/react@18.3.23)(react@18.3.1) - react-style-singleton: 2.2.3(@types/react@18.3.23)(react@18.3.1) + react-remove-scroll-bar: 2.3.8(@types/react@18.3.27)(react@18.3.1) + react-style-singleton: 2.2.3(@types/react@18.3.27)(react@18.3.1) tslib: 2.8.1 - use-callback-ref: 1.3.3(@types/react@18.3.23)(react@18.3.1) - use-sidecar: 1.1.3(@types/react@18.3.23)(react@18.3.1) + use-callback-ref: 1.3.3(@types/react@18.3.27)(react@18.3.1) + use-sidecar: 1.1.3(@types/react@18.3.27)(react@18.3.1) optionalDependencies: - '@types/react': 18.3.23 + '@types/react': 18.3.27 - react-style-singleton@2.2.3(@types/react@18.3.23)(react@18.3.1): + react-style-singleton@2.2.3(@types/react@18.3.27)(react@18.3.1): dependencies: get-nonce: 1.0.1 react: 18.3.1 tslib: 2.8.1 optionalDependencies: - '@types/react': 18.3.23 + '@types/react': 18.3.27 react@18.3.1: dependencies: @@ -9946,7 +11033,7 @@ snapshots: rechoir@0.6.2: dependencies: - resolve: 1.22.10 + resolve: 1.22.11 recursive-readdir@2.2.3: dependencies: @@ -9976,7 +11063,7 @@ snapshots: dependencies: path-parse: 1.0.7 - resolve@1.22.10: + resolve@1.22.11: dependencies: is-core-module: 2.16.1 path-parse: 1.0.7 @@ -9988,46 +11075,56 @@ snapshots: reusify@1.1.0: {} - ripemd160@2.0.1: - dependencies: - hash-base: 2.0.2 - inherits: 2.0.4 - - ripemd160@2.0.2: + ripemd160@2.0.3: dependencies: - hash-base: 3.1.0 + hash-base: 3.1.2 inherits: 2.0.4 rlp@2.2.7: dependencies: bn.js: 5.2.2 - rollup@4.45.1: + rollup@4.53.5: dependencies: '@types/estree': 1.0.8 optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.45.1 - '@rollup/rollup-android-arm64': 4.45.1 - '@rollup/rollup-darwin-arm64': 4.45.1 - '@rollup/rollup-darwin-x64': 4.45.1 - '@rollup/rollup-freebsd-arm64': 4.45.1 - '@rollup/rollup-freebsd-x64': 4.45.1 - '@rollup/rollup-linux-arm-gnueabihf': 4.45.1 - '@rollup/rollup-linux-arm-musleabihf': 4.45.1 - '@rollup/rollup-linux-arm64-gnu': 4.45.1 - '@rollup/rollup-linux-arm64-musl': 4.45.1 - '@rollup/rollup-linux-loongarch64-gnu': 4.45.1 - '@rollup/rollup-linux-powerpc64le-gnu': 4.45.1 - '@rollup/rollup-linux-riscv64-gnu': 4.45.1 - '@rollup/rollup-linux-riscv64-musl': 4.45.1 - '@rollup/rollup-linux-s390x-gnu': 4.45.1 - '@rollup/rollup-linux-x64-gnu': 4.45.1 - '@rollup/rollup-linux-x64-musl': 4.45.1 - '@rollup/rollup-win32-arm64-msvc': 4.45.1 - '@rollup/rollup-win32-ia32-msvc': 4.45.1 - '@rollup/rollup-win32-x64-msvc': 4.45.1 + '@rollup/rollup-android-arm-eabi': 4.53.5 + '@rollup/rollup-android-arm64': 4.53.5 + '@rollup/rollup-darwin-arm64': 4.53.5 + '@rollup/rollup-darwin-x64': 4.53.5 + '@rollup/rollup-freebsd-arm64': 4.53.5 + '@rollup/rollup-freebsd-x64': 4.53.5 + '@rollup/rollup-linux-arm-gnueabihf': 4.53.5 + '@rollup/rollup-linux-arm-musleabihf': 4.53.5 + '@rollup/rollup-linux-arm64-gnu': 4.53.5 + '@rollup/rollup-linux-arm64-musl': 4.53.5 + '@rollup/rollup-linux-loong64-gnu': 4.53.5 + '@rollup/rollup-linux-ppc64-gnu': 4.53.5 + '@rollup/rollup-linux-riscv64-gnu': 4.53.5 + '@rollup/rollup-linux-riscv64-musl': 4.53.5 + '@rollup/rollup-linux-s390x-gnu': 4.53.5 + '@rollup/rollup-linux-x64-gnu': 4.53.5 + '@rollup/rollup-linux-x64-musl': 4.53.5 + '@rollup/rollup-openharmony-arm64': 4.53.5 + '@rollup/rollup-win32-arm64-msvc': 4.53.5 + '@rollup/rollup-win32-ia32-msvc': 4.53.5 + '@rollup/rollup-win32-x64-gnu': 4.53.5 + '@rollup/rollup-win32-x64-msvc': 4.53.5 fsevents: 2.3.3 + rpc-websockets@9.3.2: + dependencies: + '@swc/helpers': 0.5.17 + '@types/uuid': 8.3.4 + '@types/ws': 8.18.1 + buffer: 6.0.3 + eventemitter3: 5.0.1 + uuid: 8.3.2 + ws: 8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10) + optionalDependencies: + bufferutil: 4.0.9 + utf-8-validate: 5.0.10 + run-parallel@1.2.0: dependencies: queue-microtask: 1.2.3 @@ -10054,7 +11151,7 @@ snapshots: esprima: 2.7.3 glob: 5.0.15 handlebars: 4.7.8 - js-yaml: 3.14.1 + js-yaml: 3.14.2 mkdirp: 0.5.6 nopt: 3.0.6 once: 1.4.0 @@ -10079,7 +11176,7 @@ snapshots: semver@6.3.1: {} - semver@7.7.2: {} + semver@7.7.3: {} serialize-javascript@6.0.2: dependencies: @@ -10104,19 +11201,13 @@ snapshots: dependencies: inherits: 2.0.4 safe-buffer: 5.2.1 - to-buffer: 1.2.1 + to-buffer: 1.2.2 sha1@1.1.1: dependencies: charenc: 0.0.2 crypt: 0.0.2 - shebang-command@2.0.0: - dependencies: - shebang-regex: 3.0.0 - - shebang-regex@3.0.0: {} - shelljs@0.8.5: dependencies: glob: 7.2.3 @@ -10155,8 +11246,6 @@ snapshots: signal-exit@3.0.7: {} - signal-exit@4.1.0: {} - sisteransi@1.0.5: {} slash@3.0.0: {} @@ -10170,7 +11259,7 @@ snapshots: socket.io-client@4.8.1(bufferutil@4.0.9)(utf-8-validate@5.0.10): dependencies: '@socket.io/component-emitter': 3.1.2 - debug: 4.3.7 + debug: 4.3.4 engine.io-client: 6.6.3(bufferutil@4.0.9)(utf-8-validate@5.0.10) socket.io-parser: 4.2.4 transitivePeerDependencies: @@ -10181,15 +11270,15 @@ snapshots: socket.io-parser@4.2.4: dependencies: '@socket.io/component-emitter': 3.1.2 - debug: 4.3.7 + debug: 4.3.4 transitivePeerDependencies: - supports-color - solc@0.8.26(debug@4.4.1): + solc@0.8.26(debug@4.4.3): dependencies: command-exists: 1.2.9 commander: 8.3.0 - follow-redirects: 1.15.9(debug@4.4.1) + follow-redirects: 1.15.11(debug@4.4.3) js-sha3: 0.8.0 memorystream: 0.3.1 semver: 5.7.2 @@ -10197,9 +11286,9 @@ snapshots: transitivePeerDependencies: - debug - solidity-ast@0.4.60: {} + solidity-ast@0.4.61: {} - solidity-coverage@0.8.16(hardhat@2.26.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.8.3))(typescript@5.8.3)(utf-8-validate@5.0.10)): + solidity-coverage@0.8.17(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10)): dependencies: '@ethersproject/abi': 5.8.0 '@solidity-parser/parser': 0.20.2 @@ -10210,7 +11299,7 @@ snapshots: ghost-testrpc: 0.0.2 global-modules: 2.0.0 globby: 10.0.2 - hardhat: 2.26.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.8.3))(typescript@5.8.3)(utf-8-validate@5.0.10) + hardhat: 2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10) jsonschema: 1.5.0 lodash: 4.17.21 mocha: 10.8.2 @@ -10218,7 +11307,7 @@ snapshots: pify: 4.0.1 recursive-readdir: 2.2.3 sc-istanbul: 0.4.6 - semver: 7.7.2 + semver: 7.7.3 shelljs: 0.8.5 web3-utils: 1.10.4 @@ -10256,9 +11345,15 @@ snapshots: dependencies: type-fest: 0.7.1 - statuses@2.0.1: {} + statuses@2.0.2: {} + + std-env@3.10.0: {} - std-env@3.9.0: {} + stream-chain@2.2.5: {} + + stream-json@1.9.1: + dependencies: + stream-chain: 2.2.5 stream-shift@1.0.3: {} @@ -10277,12 +11372,6 @@ snapshots: is-fullwidth-code-point: 3.0.0 strip-ansi: 6.0.1 - string-width@5.1.2: - dependencies: - eastasianwidth: 0.2.0 - emoji-regex: 9.2.2 - strip-ansi: 7.1.0 - string_decoder@1.1.1: dependencies: safe-buffer: 5.1.2 @@ -10299,34 +11388,32 @@ snapshots: dependencies: ansi-regex: 5.0.1 - strip-ansi@7.1.0: - dependencies: - ansi-regex: 6.1.0 - strip-hex-prefix@1.0.0: dependencies: is-hex-prefixed: 1.0.0 strip-json-comments@3.1.1: {} - strip-literal@3.0.0: + strip-literal@3.1.0: dependencies: js-tokens: 9.0.1 - strnum@2.1.1: {} + strnum@2.1.2: {} - sucrase@3.35.0: + sucrase@3.35.1: dependencies: - '@jridgewell/gen-mapping': 0.3.12 + '@jridgewell/gen-mapping': 0.3.13 commander: 4.1.1 - glob: 10.4.5 lines-and-columns: 1.2.4 mz: 2.7.0 pirates: 4.0.7 + tinyglobby: 0.2.15 ts-interface-checker: 0.1.13 superstruct@1.0.4: {} + superstruct@2.0.2: {} + supports-color@3.2.3: dependencies: has-flag: 1.0.0 @@ -10370,7 +11457,7 @@ snapshots: string-width: 4.2.3 strip-ansi: 6.0.1 - tailwindcss@3.4.17(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.8.3)): + tailwindcss@3.4.19: dependencies: '@alloc/quick-lru': 5.2.0 arg: 5.0.2 @@ -10388,14 +11475,17 @@ snapshots: picocolors: 1.1.1 postcss: 8.5.6 postcss-import: 15.1.0(postcss@8.5.6) - postcss-js: 4.0.1(postcss@8.5.6) - postcss-load-config: 4.0.2(postcss@8.5.6)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.8.3)) + postcss-js: 4.1.0(postcss@8.5.6) + postcss-load-config: 6.0.1(jiti@1.21.7)(postcss@8.5.6) postcss-nested: 6.2.0(postcss@8.5.6) postcss-selector-parser: 6.1.2 - resolve: 1.22.10 - sucrase: 3.35.0 + resolve: 1.22.11 + sucrase: 3.35.1 transitivePeerDependencies: - - ts-node + - tsx + - yaml + + text-encoding-utf-8@1.0.2: {} then-request@6.0.2: dependencies: @@ -10431,22 +11521,22 @@ snapshots: tinyexec@0.3.2: {} - tinyglobby@0.2.14: + tinyglobby@0.2.15: dependencies: - fdir: 6.4.6(picomatch@4.0.3) + fdir: 6.5.0(picomatch@4.0.3) picomatch: 4.0.3 tinypool@1.1.1: {} tinyrainbow@2.0.0: {} - tinyspy@4.0.3: {} + tinyspy@4.0.4: {} tmp@0.0.33: dependencies: os-tmpdir: 1.0.2 - to-buffer@1.2.1: + to-buffer@1.2.2: dependencies: isarray: 2.0.5 safe-buffer: 5.2.1 @@ -10467,16 +11557,16 @@ snapshots: command-line-usage: 6.1.3 string-format: 2.0.0 - ts-essentials@7.0.3(typescript@5.8.3): + ts-essentials@7.0.3(typescript@5.9.3): dependencies: - typescript: 5.8.3 + typescript: 5.9.3 ts-interface-checker@0.1.13: {} - ts-node@10.9.2(@types/node@22.7.5)(typescript@5.8.3): + ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3): dependencies: '@cspotcode/source-map-support': 0.8.1 - '@tsconfig/node10': 1.0.11 + '@tsconfig/node10': 1.0.12 '@tsconfig/node12': 1.0.11 '@tsconfig/node14': 1.0.3 '@tsconfig/node16': 1.0.4 @@ -10487,7 +11577,7 @@ snapshots: create-require: 1.1.1 diff: 4.0.2 make-error: 1.3.6 - typescript: 5.8.3 + typescript: 5.9.3 v8-compile-cache-lib: 3.0.1 yn: 3.1.1 @@ -10513,10 +11603,10 @@ snapshots: type-fest@0.7.1: {} - typechain@8.3.2(typescript@5.8.3): + typechain@8.3.2(typescript@5.9.3): dependencies: '@types/prettier': 2.7.3 - debug: 4.4.1(supports-color@8.1.1) + debug: 4.4.3(supports-color@8.1.1) fs-extra: 7.0.1 glob: 7.1.7 js-sha3: 0.8.0 @@ -10524,8 +11614,8 @@ snapshots: mkdirp: 1.0.4 prettier: 2.8.8 ts-command-line-args: 2.5.1 - ts-essentials: 7.0.3(typescript@5.8.3) - typescript: 5.8.3 + ts-essentials: 7.0.3(typescript@5.9.3) + typescript: 5.9.3 transitivePeerDependencies: - supports-color @@ -10537,13 +11627,13 @@ snapshots: typedarray@0.0.6: {} - typescript@5.8.3: {} + typescript@5.9.3: {} typical@4.0.0: {} typical@5.2.0: {} - ua-parser-js@1.0.40: {} + ua-parser-js@1.0.41: {} ufo@1.6.1: {} @@ -10560,11 +11650,13 @@ snapshots: undici-types@6.21.0: {} + undici-types@7.16.0: {} + undici@5.29.0: dependencies: '@fastify/busboy': 2.1.1 - undici@6.21.3: {} + undici@6.22.0: {} unfetch@4.2.0: {} @@ -10574,39 +11666,39 @@ snapshots: unpipe@1.0.0: {} - unstorage@1.16.1(idb-keyval@6.2.2): + unstorage@1.17.3(idb-keyval@6.2.2): dependencies: anymatch: 3.1.3 chokidar: 4.0.3 destr: 2.0.5 - h3: 1.15.3 + h3: 1.15.4 lru-cache: 10.4.3 - node-fetch-native: 1.6.6 - ofetch: 1.4.1 + node-fetch-native: 1.6.7 + ofetch: 1.5.1 ufo: 1.6.1 optionalDependencies: idb-keyval: 6.2.2 - update-browserslist-db@1.1.3(browserslist@4.25.1): + update-browserslist-db@1.2.3(browserslist@4.28.1): dependencies: - browserslist: 4.25.1 + browserslist: 4.28.1 escalade: 3.2.0 picocolors: 1.1.1 - use-callback-ref@1.3.3(@types/react@18.3.23)(react@18.3.1): + use-callback-ref@1.3.3(@types/react@18.3.27)(react@18.3.1): dependencies: react: 18.3.1 tslib: 2.8.1 optionalDependencies: - '@types/react': 18.3.23 + '@types/react': 18.3.27 - use-sidecar@1.1.3(@types/react@18.3.23)(react@18.3.1): + use-sidecar@1.1.3(@types/react@18.3.27)(react@18.3.1): dependencies: detect-node-es: 1.1.0 react: 18.3.1 tslib: 2.8.1 optionalDependencies: - '@types/react': 18.3.23 + '@types/react': 18.3.27 use-sync-external-store@1.2.0(react@18.3.1): dependencies: @@ -10628,7 +11720,7 @@ snapshots: dependencies: inherits: 2.0.4 is-arguments: 1.2.0 - is-generator-function: 1.1.0 + is-generator-function: 1.1.2 is-typed-array: 1.1.15 which-typed-array: 1.1.19 @@ -10638,56 +11730,90 @@ snapshots: v8-compile-cache-lib@3.0.1: {} - valtio@1.13.2(@types/react@18.3.23)(react@18.3.1): + valtio@1.13.2(@types/react@18.3.27)(react@18.3.1): dependencies: - derive-valtio: 0.1.0(valtio@1.13.2(@types/react@18.3.23)(react@18.3.1)) + derive-valtio: 0.1.0(valtio@1.13.2(@types/react@18.3.27)(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.23 + '@types/react': 18.3.27 react: 18.3.1 - viem@2.23.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4): + viem@2.23.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1): 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.8.3)(zod@3.22.4) + abitype: 1.0.8(typescript@5.9.3)(zod@4.2.1) isows: 1.0.6(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) - ox: 0.6.7(typescript@5.8.3)(zod@3.22.4) + ox: 0.6.7(typescript@5.9.3)(zod@4.2.1) ws: 8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) optionalDependencies: - typescript: 5.8.3 + typescript: 5.9.3 transitivePeerDependencies: - bufferutil - utf-8-validate - zod - viem@2.37.5(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4): + viem@2.43.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.22.4): dependencies: '@noble/curves': 1.9.1 '@noble/hashes': 1.8.0 '@scure/bip32': 1.7.0 '@scure/bip39': 1.6.0 - abitype: 1.1.0(typescript@5.8.3)(zod@3.22.4) + abitype: 1.2.3(typescript@5.9.3)(zod@3.22.4) isows: 1.0.7(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) - ox: 0.9.3(typescript@5.8.3)(zod@3.22.4) + ox: 0.10.5(typescript@5.9.3)(zod@3.22.4) ws: 8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10) optionalDependencies: - typescript: 5.8.3 + typescript: 5.9.3 transitivePeerDependencies: - bufferutil - utf-8-validate - zod - vite-node@3.2.4(@types/node@20.19.9): + viem@2.43.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76): + dependencies: + '@noble/curves': 1.9.1 + '@noble/hashes': 1.8.0 + '@scure/bip32': 1.7.0 + '@scure/bip39': 1.6.0 + abitype: 1.2.3(typescript@5.9.3)(zod@3.25.76) + isows: 1.0.7(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + ox: 0.10.5(typescript@5.9.3)(zod@3.25.76) + ws: 8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10) + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + - zod + + viem@2.43.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1): + 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.2.1) + isows: 1.0.7(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + ox: 0.10.5(typescript@5.9.3)(zod@4.2.1) + ws: 8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10) + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + - zod + + vite-node@3.2.4(@types/node@20.19.27): dependencies: cac: 6.7.14 - debug: 4.4.1(supports-color@8.1.1) + debug: 4.4.3(supports-color@8.1.1) es-module-lexer: 1.7.0 pathe: 2.0.3 - vite: 5.4.19(@types/node@20.19.9) + vite: 5.4.21(@types/node@20.19.27) transitivePeerDependencies: - '@types/node' - less @@ -10702,10 +11828,10 @@ snapshots: vite-node@3.2.4(@types/node@22.7.5): dependencies: cac: 6.7.14 - debug: 4.4.1(supports-color@8.1.1) + debug: 4.4.3(supports-color@8.1.1) es-module-lexer: 1.7.0 pathe: 2.0.3 - vite: 5.4.19(@types/node@22.7.5) + vite: 5.4.21(@types/node@22.7.5) transitivePeerDependencies: - '@types/node' - less @@ -10717,56 +11843,56 @@ snapshots: - supports-color - terser - vite-plugin-wasm@3.5.0(vite@5.4.19(@types/node@22.7.5)): + vite-plugin-wasm@3.5.0(vite@5.4.21(@types/node@22.7.5)): dependencies: - vite: 5.4.19(@types/node@22.7.5) + vite: 5.4.21(@types/node@22.7.5) - vite@5.4.19(@types/node@20.19.9): + vite@5.4.21(@types/node@20.19.27): dependencies: esbuild: 0.21.5 postcss: 8.5.6 - rollup: 4.45.1 + rollup: 4.53.5 optionalDependencies: - '@types/node': 20.19.9 + '@types/node': 20.19.27 fsevents: 2.3.3 - vite@5.4.19(@types/node@22.7.5): + vite@5.4.21(@types/node@22.7.5): dependencies: esbuild: 0.21.5 postcss: 8.5.6 - rollup: 4.45.1 + rollup: 4.53.5 optionalDependencies: '@types/node': 22.7.5 fsevents: 2.3.3 - vitest@3.2.4(@types/debug@4.1.12)(@types/node@20.19.9): + vitest@3.2.4(@types/debug@4.1.12)(@types/node@20.19.27): dependencies: - '@types/chai': 5.2.2 + '@types/chai': 5.2.3 '@vitest/expect': 3.2.4 - '@vitest/mocker': 3.2.4(vite@5.4.19(@types/node@20.19.9)) + '@vitest/mocker': 3.2.4(vite@5.4.21(@types/node@20.19.27)) '@vitest/pretty-format': 3.2.4 '@vitest/runner': 3.2.4 '@vitest/snapshot': 3.2.4 '@vitest/spy': 3.2.4 '@vitest/utils': 3.2.4 - chai: 5.2.1 - debug: 4.4.1(supports-color@8.1.1) - expect-type: 1.2.2 - magic-string: 0.30.17 + chai: 5.3.3 + debug: 4.4.3(supports-color@8.1.1) + expect-type: 1.3.0 + magic-string: 0.30.21 pathe: 2.0.3 picomatch: 4.0.3 - std-env: 3.9.0 + std-env: 3.10.0 tinybench: 2.9.0 tinyexec: 0.3.2 - tinyglobby: 0.2.14 + tinyglobby: 0.2.15 tinypool: 1.1.1 tinyrainbow: 2.0.0 - vite: 5.4.19(@types/node@20.19.9) - vite-node: 3.2.4(@types/node@20.19.9) + vite: 5.4.21(@types/node@20.19.27) + vite-node: 3.2.4(@types/node@20.19.27) why-is-node-running: 2.3.0 optionalDependencies: '@types/debug': 4.1.12 - '@types/node': 20.19.9 + '@types/node': 20.19.27 transitivePeerDependencies: - less - lightningcss @@ -10780,27 +11906,27 @@ snapshots: vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.7.5): dependencies: - '@types/chai': 5.2.2 + '@types/chai': 5.2.3 '@vitest/expect': 3.2.4 - '@vitest/mocker': 3.2.4(vite@5.4.19(@types/node@20.19.9)) + '@vitest/mocker': 3.2.4(vite@5.4.21(@types/node@20.19.27)) '@vitest/pretty-format': 3.2.4 '@vitest/runner': 3.2.4 '@vitest/snapshot': 3.2.4 '@vitest/spy': 3.2.4 '@vitest/utils': 3.2.4 - chai: 5.2.1 - debug: 4.4.1(supports-color@8.1.1) - expect-type: 1.2.2 - magic-string: 0.30.17 + chai: 5.3.3 + debug: 4.4.3(supports-color@8.1.1) + expect-type: 1.3.0 + magic-string: 0.30.21 pathe: 2.0.3 picomatch: 4.0.3 - std-env: 3.9.0 + std-env: 3.10.0 tinybench: 2.9.0 tinyexec: 0.3.2 - tinyglobby: 0.2.14 + tinyglobby: 0.2.15 tinypool: 1.1.1 tinyrainbow: 2.0.0 - vite: 5.4.19(@types/node@22.7.5) + vite: 5.4.21(@types/node@22.7.5) vite-node: 3.2.4(@types/node@22.7.5) why-is-node-running: 2.3.0 optionalDependencies: @@ -10817,16 +11943,16 @@ snapshots: - supports-color - terser - wagmi@2.16.0(@tanstack/query-core@5.83.0)(@tanstack/react-query@5.83.0(react@18.3.1))(@types/react@18.3.23)(bufferutil@4.0.9)(immer@10.0.2)(react@18.3.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(viem@2.37.5(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4))(zod@3.22.4): + wagmi@2.19.5(@tanstack/query-core@5.90.12)(@tanstack/react-query@5.90.12(react@18.3.1))(@types/react@18.3.27)(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(immer@10.0.2)(react@18.3.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.43.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1))(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@4.2.1): dependencies: - '@tanstack/react-query': 5.83.0(react@18.3.1) - '@wagmi/connectors': 5.9.0(@types/react@18.3.23)(@wagmi/core@2.18.0(@tanstack/query-core@5.83.0)(@types/react@18.3.23)(immer@10.0.2)(react@18.3.1)(typescript@5.8.3)(use-sync-external-store@1.4.0(react@18.3.1))(viem@2.37.5(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4)))(bufferutil@4.0.9)(immer@10.0.2)(react@18.3.1)(typescript@5.8.3)(use-sync-external-store@1.4.0(react@18.3.1))(utf-8-validate@5.0.10)(viem@2.37.5(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4))(wagmi@2.16.0(@tanstack/query-core@5.83.0)(@tanstack/react-query@5.83.0(react@18.3.1))(@types/react@18.3.23)(bufferutil@4.0.9)(immer@10.0.2)(react@18.3.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(viem@2.37.5(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4))(zod@3.22.4))(zod@3.22.4) - '@wagmi/core': 2.18.0(@tanstack/query-core@5.83.0)(@types/react@18.3.23)(immer@10.0.2)(react@18.3.1)(typescript@5.8.3)(use-sync-external-store@1.4.0(react@18.3.1))(viem@2.37.5(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4)) + '@tanstack/react-query': 5.90.12(react@18.3.1) + '@wagmi/connectors': 6.2.0(3e683225d0eaab4e1b5a92e5a7d66afa) + '@wagmi/core': 2.22.1(@tanstack/query-core@5.90.12)(@types/react@18.3.27)(immer@10.0.2)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@18.3.1))(viem@2.43.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1)) react: 18.3.1 use-sync-external-store: 1.4.0(react@18.3.1) - viem: 2.37.5(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) + viem: 2.43.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) optionalDependencies: - typescript: 5.8.3 + typescript: 5.9.3 transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -10843,16 +11969,24 @@ snapshots: - '@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 + - ws - zod web3-utils@1.10.4: @@ -10891,10 +12025,6 @@ snapshots: dependencies: isexe: 2.0.0 - which@2.0.2: - dependencies: - isexe: 2.0.0 - why-is-node-running@2.3.0: dependencies: siginfo: 2.0.0 @@ -10927,12 +12057,6 @@ snapshots: string-width: 4.2.3 strip-ansi: 6.0.1 - wrap-ansi@8.1.0: - dependencies: - ansi-styles: 6.2.1 - string-width: 5.1.2 - strip-ansi: 7.1.0 - wrappy@1.0.2: {} ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10): @@ -10965,8 +12089,6 @@ snapshots: yallist@3.1.1: {} - yaml@2.8.0: {} - yargs-parser@18.1.3: dependencies: camelcase: 5.3.1 @@ -11011,16 +12133,27 @@ snapshots: zod@3.22.4: {} - zustand@5.0.0(@types/react@18.3.23)(immer@10.0.2)(react@18.3.1)(use-sync-external-store@1.4.0(react@18.3.1)): + zod@3.25.76: {} + + zod@4.2.1: {} + + zustand@5.0.0(@types/react@18.3.27)(immer@10.0.2)(react@18.3.1)(use-sync-external-store@1.4.0(react@18.3.1)): + optionalDependencies: + '@types/react': 18.3.27 + immer: 10.0.2 + react: 18.3.1 + use-sync-external-store: 1.4.0(react@18.3.1) + + zustand@5.0.3(@types/react@18.3.27)(immer@10.0.2)(react@18.3.1)(use-sync-external-store@1.4.0(react@18.3.1)): optionalDependencies: - '@types/react': 18.3.23 + '@types/react': 18.3.27 immer: 10.0.2 react: 18.3.1 use-sync-external-store: 1.4.0(react@18.3.1) - zustand@5.0.3(@types/react@18.3.23)(immer@10.0.2)(react@18.3.1)(use-sync-external-store@1.4.0(react@18.3.1)): + zustand@5.0.9(@types/react@18.3.27)(immer@10.0.2)(react@18.3.1)(use-sync-external-store@1.4.0(react@18.3.1)): optionalDependencies: - '@types/react': 18.3.23 + '@types/react': 18.3.27 immer: 10.0.2 react: 18.3.1 use-sync-external-store: 1.4.0(react@18.3.1) From 0048ee9fae0344deec65cde24f158dc81842ad70 Mon Sep 17 00:00:00 2001 From: Marco Esposito Date: Wed, 24 Dec 2025 18:50:20 +0100 Subject: [PATCH 03/51] deterministic session signer derivation --- apps/demo/src/App.tsx | 2 + apps/demo/src/components/IdentityCreation.tsx | 107 ++++++++++++- .../src/components/SessionSetupPrompt.tsx | 5 +- apps/demo/src/hooks/useInitIdentity.ts | 142 +++++++++++++----- apps/demo/src/services/DbService.ts | 31 ---- apps/demo/src/types.ts | 48 ++++-- 6 files changed, 246 insertions(+), 89 deletions(-) diff --git a/apps/demo/src/App.tsx b/apps/demo/src/App.tsx index 7efded2..9fa3446 100644 --- a/apps/demo/src/App.tsx +++ b/apps/demo/src/App.tsx @@ -76,6 +76,7 @@ export default function App() { setIsSafeDeployed, setIsModuleEnabled, setNeedsSessionSetup, + signingStep, // Actions createIdentity, triggerReinit, @@ -297,6 +298,7 @@ export default function App() { loading={loading} onCreateIdentity={createIdentity} address={address || "Not connected"} + signingStep={signingStep} /> ) : showHandshakeForm ? ( void; onImportIdentity?: () => void; address: string; + /** Current signing step: 1 = first signature, 2 = second signature, undefined = not started */ + signingStep?: 1 | 2 | null; +} + +function Spinner() { + return ( + + + + + ); +} + +function StepIndicator({ step }: { step: 1 | 2 }) { + return ( + + {/* Spinner on top */} +
+ +
+ + {/* Step indicators */} +
+ {/* Step 1 */} +
+
+ {step > 1 ? ( + + + + ) : ( + '1' + )} +
+ + Derive keys + +
+ + {/* Connector */} +
+ {step >= 1 && ( + 1 ? '100%' : '50%' }} + transition={{ duration: 0.3 }} + className="absolute inset-y-0 left-0 bg-blue-600" + /> + )} +
+ + {/* Step 2 */} +
+
+ 2 +
+ + Create proof + +
+
+
+ ); } export function IdentityCreation({ @@ -10,10 +104,16 @@ export function IdentityCreation({ onCreateIdentity, onImportIdentity, address, + signingStep, }: IdentityCreationProps) { return (
+ {/* Step indicator - shows during signing */} + + {signingStep && } + +
{/* Connected as...*/}

@@ -24,18 +124,15 @@ export function IdentityCreation({

Create Your Identity

-

- Choose how to set up your encrypted messaging identity: -

+ ); +} + export function IdentityCreation({ loading, onCreateIdentity, onImportIdentity, address, signingStep, + needsModeSelection, + fastModeAvailable, + chainId, }: IdentityCreationProps) { + // NEW: Track selected mode locally before identity creation starts + const [selectedMode, setSelectedMode] = useState(null); + + const handleModeSelect = (mode: ExecutionMode) => { + setSelectedMode(mode); + }; + + const handleCreateIdentity = () => { + if (selectedMode) { + onCreateIdentity(selectedMode); + } + }; + return (
@@ -115,44 +190,135 @@ export function IdentityCreation({
- {/* Connected as...*/}

{address ? <>Hello, {address.slice(0, 6)}...{address.slice(-4)} : "Not connected"}

- Create Your Identity + {needsModeSelection && !selectedMode + ? "Choose Your Experience" + : "Create Your Identity"}

-
- + {/* NEW: Mode Selection (before identity creation) */} + {needsModeSelection && !selectedMode && !signingStep && ( +
+ handleModeSelect('fast')} + /> - -
+ handleModeSelect('classic')} + /> -
-

- You will be asked to sign two messages. - The first signature deterministically derives your identity keys. - The second signature creates an Identity Proof that binds the generated public keys - to your wallet address, the current chain, and this dapp origin. - Keys are stored locally and never leave your device. -

-
+ {}} + /> +
+ )} + + {/* Mode selected badge */} + {selectedMode && !signingStep && ( +
+ + {selectedMode === 'fast' ? 'โšก Fast Mode' : '๐Ÿ” Classic Mode'} + + +
+ )} + + {/* Create Identity button (after mode selection) */} + {selectedMode && ( +
+ + + {/* Mode-specific info */} +
+ {selectedMode === 'classic' ? ( +

+ You'll sign two messages to derive your identity keys. + Each future message will require wallet confirmation. +

+ ) : ( +

+ You'll sign two messages to derive your identity keys. + After a one-time setup, messages are sent without popups. +

+ )} +
+
+ )} + + {/* Back to mode selection if not started */} + {!needsModeSelection && !selectedMode && !signingStep && ( +
+ + + + +
+

+ You will be asked to sign two messages. + The first signature deterministically derives your identity keys. + The second signature creates an Identity Proof. +

+
+
+ )}
); diff --git a/apps/demo/src/hooks/useInitIdentity.ts b/apps/demo/src/hooks/useInitIdentity.ts index f9cf3fd..e4d414c 100644 --- a/apps/demo/src/hooks/useInitIdentity.ts +++ b/apps/demo/src/hooks/useInitIdentity.ts @@ -16,8 +16,17 @@ import { SafeSessionSigner, } from '@verbeth/sdk'; import { dbService } from '../services/DbService.js'; -import { getOrCreateSafeForOwner } from '../services/safeAccount.js'; -import { LOGCHAIN_SINGLETON_ADDR, SAFE_MODULE_ADDRESS, StoredIdentity } from '../types.js'; +import { + getOrCreateSafeForOwner, + predictVerbEthSafeAddress, + isHelperAvailable, +} from '../services/safeAccount.js'; +import { + LOGCHAIN_SINGLETON_ADDR, + SAFE_MODULE_ADDRESS, + StoredIdentity, + ExecutionMode, +} from '../types.js'; interface UseInitIdentityParams { walletClient: any; @@ -26,7 +35,6 @@ interface UseInitIdentityParams { readProvider: any; ready: boolean; addLog: (message: string) => void; - onIdentityCreated?: () => void; onReset?: () => void; } @@ -52,16 +60,24 @@ export function useInitIdentity({ const [needsIdentityCreation, setNeedsIdentityCreation] = useState(false); const [loading, setLoading] = useState(false); const [reinitTrigger, setReinitTrigger] = useState(0); - + const [sessionSignerAddr, setSessionSignerAddr] = useState(null); const [needsSessionSetup, setNeedsSessionSetup] = useState(false); const [isSafeDeployed, setIsSafeDeployed] = useState(false); const [isModuleEnabled, setIsModuleEnabled] = useState(false); const [signingStep, setSigningStep] = useState<1 | 2 | null>(null); + // NEW: Execution mode state + const [executionMode, setExecutionMode] = useState(null); + const [needsModeSelection, setNeedsModeSelection] = useState(false); + const [emitterAddress, setEmitterAddress] = useState(null); + const rpId = globalThis.location?.host ?? ''; const identityContext = useMemo(() => ({ chainId, rpId }), [chainId, rpId]); + // NEW: Check if fast mode is available on this chain + const fastModeAvailable = useMemo(() => isHelperAvailable(chainId), [chainId]); + const resetState = useCallback(() => { setCurrentAccount(null); setIdentityKeyPair(null); @@ -76,6 +92,10 @@ export function useInitIdentity({ setNeedsSessionSetup(false); setIsSafeDeployed(false); setIsModuleEnabled(false); + // NEW + setExecutionMode(null); + setNeedsModeSelection(false); + setEmitterAddress(null); onReset?.(); }, [onReset]); @@ -90,13 +110,18 @@ export function useInitIdentity({ if (storedIdentity && storedIdentity.sessionPrivateKey) { setIdentityKeyPair(storedIdentity.keyPair); setIdentityProof(storedIdentity.proof ?? null); + // NEW: Restore mode from storage + setExecutionMode(storedIdentity.executionMode ?? 'fast'); // default to fast for legacy + setEmitterAddress(storedIdentity.emitterAddress ?? null); setNeedsIdentityCreation(false); - addLog(`Identity keys restored from database`); + setNeedsModeSelection(false); + addLog(`Identity restored (${storedIdentity.executionMode ?? 'fast'} mode)`); } else if (storedIdentity && !storedIdentity.sessionPrivateKey) { - setNeedsIdentityCreation(true); - addLog(`Identity upgrade required (to derive session key)`); + setNeedsModeSelection(true); + addLog(`Identity upgrade required`); } else { - setNeedsIdentityCreation(true); + // NEW: Need mode selection before identity creation + setNeedsModeSelection(true); } }, [addLog]); @@ -113,17 +138,41 @@ export function useInitIdentity({ const net = await ethersProvider.getNetwork(); if (Number(net.chainId) !== chainId) { - addLog(`Wrong network: connected to chain ${Number(net.chainId)}, expected ${chainId}. Please switch network in your wallet.`); + addLog(`Wrong network: connected to chain ${Number(net.chainId)}, expected ${chainId}.`); return; } const storedIdentity = await dbService.getIdentity(address); - + if (!storedIdentity || !storedIdentity.sessionPrivateKey) { - addLog(`Awaiting identity creation...`); + addLog(`Awaiting mode selection & identity creation...`); + return; + } + + const currentMode = storedIdentity.executionMode ?? 'fast'; + setExecutionMode(currentMode); + setEmitterAddress(storedIdentity.emitterAddress ?? address); + + // ========================================================================= + // CLASSIC MODE: EOA executor, no Safe setup needed + // ========================================================================= + if (currentMode === 'classic') { + addLog(`Classic mode: using EOA executor`); + + const contractInstance = LogChainV1__factory.connect(LOGCHAIN_SINGLETON_ADDR, ethersSigner as any); + const executorInstance = ExecutorFactory.createEOA(contractInstance); + + setExecutor(executorInstance); + setContract(contractInstance); + setTxSigner(ethersSigner); + setSafeAddr(null); + setNeedsSessionSetup(false); return; } + // ========================================================================= + // FAST MODE: VerbEth Safe + session signer + // ========================================================================= const sessionPrivKey = storedIdentity.sessionPrivateKey; const sessionWallet = new Wallet(sessionPrivKey, readProvider); const sessionAddr = storedIdentity.sessionAddress ?? await sessionWallet.getAddress(); @@ -139,6 +188,8 @@ export function useInitIdentity({ sessionSigner: sessionAddr, target: LOGCHAIN_SINGLETON_ADDR, }, + // NEW: Never use API for fast mode + useApiLookup: false, }); setSafeAddr(safeAddress); @@ -148,24 +199,21 @@ export function useInitIdentity({ setNeedsSessionSetup(true); } - console.log(`\n========== SAFE & SESSION INFO ==========`); + console.log(`\n========== SAFE & SESSION INFO (Fast Mode) ==========`); console.log(`Connected EOA wallet: ${address}`); - console.log(`Associated Safe address: ${safeAddress}`); + console.log(`VerbEth Safe address: ${safeAddress}`); console.log(` Safe deployed: ${isDeployed}`); console.log(` Module enabled: ${moduleEnabled}`); console.log(` Chain ID: ${chainId}`); - console.log(` Session signer address: ${sessionAddr}`); + console.log(` Session signer: ${sessionAddr}`); - // Check session signer balance const balance = await readProvider.getBalance(sessionAddr); - const balanceEth = Number(balance) / 1e18; - console.log(`Session signer balance: ${balanceEth.toFixed(6)} ETH (${balance.toString()} wei)`); + console.log(` Session signer balance: ${Number(balance) / 1e18} ETH`); if (balance === 0n) { addLog(`Session signer needs funding: ${sessionAddr}`); } - // Create SafeSessionSigner for transaction signing const safeSessionSigner = new SafeSessionSigner({ provider: readProvider, safeAddress, @@ -175,20 +223,19 @@ export function useInitIdentity({ }); setTxSigner(safeSessionSigner); - // Check if session is properly configured on the module if (isDeployed) { const isValid = await safeSessionSigner.isSessionValid(); const isTargetAllowed = await safeSessionSigner.isTargetAllowed(); - console.log(`Session valid on module: ${isValid}`); - console.log(`LogChain target allowed: ${isTargetAllowed}`); + console.log(` Session valid: ${isValid}`); + console.log(` Target allowed: ${isTargetAllowed}`); setNeedsSessionSetup(!isValid || !isTargetAllowed); if (!isValid || !isTargetAllowed) { - addLog(`Session needs setup on module (valid: ${isValid}, target: ${isTargetAllowed})`); + addLog(`Session needs setup (valid: ${isValid}, target: ${isTargetAllowed})`); } } - console.log(`==========================================\n`); + console.log(`=====================================================\n`); const contractInstance = LogChainV1__factory.connect(LOGCHAIN_SINGLETON_ADDR, safeSessionSigner as any); const executorInstance = ExecutorFactory.createEOA(contractInstance); @@ -197,16 +244,26 @@ export function useInitIdentity({ setContract(contractInstance); }, [walletClient, address, currentAccount, chainId, readProvider, addLog, switchToAccount]); - const createIdentity = useCallback(async () => { + // =========================================================================== + // NEW: Mode-aware identity creation + // =========================================================================== + const createIdentity = useCallback(async (selectedMode: ExecutionMode) => { if (!identitySigner || !address || !walletClient) { - addLog('โœ— Missing signer/provider or address for identity creation'); + addLog('โœ— Missing signer/provider or address'); return; } + + if (selectedMode === 'custom') { + addLog('Custom mode coming soon'); + return; + } + setSigningStep(1); setLoading(true); + try { // ================================================================ - // Derive all keys from seed signature (1 signature) + // Step 1: Derive keys (same for all modes) // ================================================================ addLog('Deriving identity keys (signature 1/2)...'); @@ -215,31 +272,30 @@ export function useInitIdentity({ address ); - console.log(`โœ“ Verbeth keys derived:`); - console.log(` Session signer: ${derivedKeys.sessionAddress}`); + console.log(`โœ“ Keys derived, session signer: ${derivedKeys.sessionAddress}`); // ================================================================ - // PREDICT SAFE ADDRESS (no signature needed) + // Step 2: Determine emitter address based on mode // ================================================================ - const ethersProvider = new BrowserProvider(walletClient.transport); - const ethersSigner = await ethersProvider.getSigner(); - - const { safeAddress: predictedSafe } = await getOrCreateSafeForOwner({ - chainId, - ownerAddress: address as `0x${string}`, - providerEip1193: walletClient.transport, - ethersSigner, - deployIfMissing: false, - sessionConfig: { - sessionSigner: derivedKeys.sessionAddress, - target: LOGCHAIN_SINGLETON_ADDR, - }, - }); - - console.log(`โœ“ Predicted Safe: ${predictedSafe}`); + let emitter: string; + + if (selectedMode === 'classic') { + // Classic mode: EOA is the emitter + emitter = address; + console.log(`โœ“ Classic mode: emitter = EOA (${address})`); + } else { + // Fast mode: Predict VerbEth Safe address (deterministic, no API) + emitter = await predictVerbEthSafeAddress({ + chainId, + ownerAddress: address as `0x${string}`, + sessionSignerAddr: derivedKeys.sessionAddress, + providerEip1193: walletClient.transport, + }); + console.log(`โœ“ Fast mode: emitter = VerbEth Safe (${emitter})`); + } // ================================================================ - // Create binding proof with Safe address (1 signature) + // Step 3: Create binding proof with correct emitter // ================================================================ addLog('Creating binding proof (signature 2/2)...'); setSigningStep(2); @@ -248,16 +304,13 @@ export function useInitIdentity({ identitySigner, address, derivedKeys, - predictedSafe, + emitter, identityContext ); // ================================================================ - // STORE IDENTITY + // Step 4: Store identity with mode info // ================================================================ - setIdentityKeyPair(derivedKeys.keyPair); - setIdentityProof(proof); - const identityToStore: StoredIdentity = { address: address, keyPair: derivedKeys.keyPair, @@ -265,30 +318,41 @@ export function useInitIdentity({ proof: proof, sessionPrivateKey: derivedKeys.sessionPrivateKey, sessionAddress: derivedKeys.sessionAddress, + // NEW: Store mode and emitter + executionMode: selectedMode, + emitterAddress: emitter, }; await dbService.saveIdentity(identityToStore); - addLog(`โœ“ Identity created with derived session key`); - addLog(` Session signer: ${derivedKeys.sessionAddress}`); + + setIdentityKeyPair(derivedKeys.keyPair); + setIdentityProof(proof); + setExecutionMode(selectedMode); + setEmitterAddress(emitter); setNeedsIdentityCreation(false); + setNeedsModeSelection(false); setSigningStep(null); - onIdentityCreated?.(); - // Trigger re-initialization to complete Safe setup + addLog(`โœ“ Identity created (${selectedMode} mode)`); + addLog(` Emitter: ${emitter.slice(0, 10)}...`); + + onIdentityCreated?.(); setReinitTrigger((t) => t + 1); + } catch (signError: any) { if (signError.code === 4001) { addLog('User rejected signing request.'); } else { console.error('Identity creation error:', signError); - addLog(`โœ— Failed to derive identity: ${signError.message}`); + addLog(`โœ— Failed: ${signError.message}`); } } finally { setLoading(false); + setSigningStep(null); } }, [identitySigner, address, walletClient, chainId, identityContext, addLog, onIdentityCreated]); - // Handle initialization on ready/wallet/address/reinit changes + // Handle initialization useEffect(() => { const handleInit = async () => { try { @@ -301,7 +365,7 @@ export function useInitIdentity({ } } catch (error) { console.error('Failed to initialize:', error); - addLog(`โœ— Failed to initialize: ${error instanceof Error ? error.message : 'Unknown error'}`); + addLog(`โœ— Failed to initialize: ${error instanceof Error ? error.message : 'Unknown'}`); } }; handleInit(); @@ -321,7 +385,15 @@ export function useInitIdentity({ identityLoading: loading, identityContext, signingStep, - // Session state (owned here, used by useSessionSetup) + + // NEW: Mode state + executionMode, + needsModeSelection, + emitterAddress, + fastModeAvailable, + setExecutionMode, + + // Session state sessionSignerAddr, needsSessionSetup, isSafeDeployed, @@ -330,6 +402,7 @@ export function useInitIdentity({ setNeedsSessionSetup, setIsSafeDeployed, setIsModuleEnabled, + // Actions createIdentity, resetState, diff --git a/apps/demo/src/hooks/useMessageListener.ts b/apps/demo/src/hooks/useMessageListener.ts index 0239059..a4a7eed 100644 --- a/apps/demo/src/hooks/useMessageListener.ts +++ b/apps/demo/src/hooks/useMessageListener.ts @@ -1,7 +1,8 @@ // apps/demo/src/hooks/useMessageListener.ts import { useState, useEffect, useRef, useCallback } from "react"; -import { keccak256, toUtf8Bytes } from "ethers"; +import { keccak256, toUtf8Bytes, getBytes } from "ethers"; +import { computeTagFromInitiator } from "@verbeth/sdk"; import { dbService } from "../services/DbService.js"; import { LOGCHAIN_SINGLETON_ADDR, @@ -22,6 +23,8 @@ import { interface UseMessageListenerProps { readProvider: any; address: string | undefined; + /** Safe address in fast mode, EOA in classic mode. Used for outbound confirmations. */ + emitterAddress: string | undefined; onLog: (message: string) => void; onEventsProcessed: (events: ProcessedEvent[]) => void; } @@ -29,6 +32,7 @@ interface UseMessageListenerProps { export const useMessageListener = ({ readProvider, address, + emitterAddress, onLog, onEventsProcessed, }: UseMessageListenerProps): MessageListenerResult => { @@ -183,6 +187,37 @@ export const useMessageListener = ({ return results; }; + /** + * Match HSR event to a pending contact using cryptographic tag verification. + * This works regardless of whether responder uses EOA or Safe. + */ + const matchHsrToContact = ( + log: any, + pendingContacts: Contact[] + ): Contact | null => { + const inResponseTo = log.topics[1] as string; + + // Extract responderEphemeralR (first bytes32 in log.data) + // ABI encoding: bytes32 is first 32 bytes = 64 hex chars + 0x prefix + const responderEphemeralR = log.data.slice(0, 66); + const R = getBytes(responderEphemeralR); + + for (const contact of pendingContacts) { + if (!contact.ephemeralKey) continue; + + try { + const expectedTag = computeTagFromInitiator(contact.ephemeralKey, R); + if (expectedTag.toLowerCase() === inResponseTo.toLowerCase()) { + return contact; + } + } catch { + // Skip contacts where tag computation fails + } + } + + return null; + }; + // scan specific block range - load contacts from db when needed const scanBlockRange = async ( fromBlock: number, @@ -225,6 +260,7 @@ export const useMessageListener = ({ ); if (pendingContacts.length > 0) { + // Fetch ALL HSR events (no address filter - responder could be Safe or EOA) const responseFilter = { address: LOGCHAIN_SINGLETON_ADDR, topics: [EVENT_SIGNATURES.HandshakeResponse], @@ -236,16 +272,12 @@ export const useMessageListener = ({ ); onLog( - `๐Ÿ” Found ${responseLogs.length} total handshake responses in blocks ${fromBlock}-${toBlock}` + `๐Ÿ” Found ${responseLogs.length} HSR events, checking against ${pendingContacts.length} pending contacts...` ); - // Match by responder address + // Match by cryptographic tag (not address) for (const log of responseLogs) { - const responderAddress = "0x" + log.topics[2].slice(-40); - - const matchingContact = pendingContacts.find( - (c) => c.address.toLowerCase() === responderAddress.toLowerCase() - ); + const matchingContact = matchHsrToContact(log, pendingContacts); if (matchingContact) { const logKey = `${log.transactionHash}-${log.logIndex}`; @@ -257,6 +289,7 @@ export const useMessageListener = ({ rawLog: log, blockNumber: log.blockNumber, timestamp: Date.now(), + matchedContactAddress: matchingContact.address, // Pass to processor }); } } @@ -298,10 +331,11 @@ export const useMessageListener = ({ } } - // 2) OUTBOUND CONFIRMATION: we do not need topic filter, we match logs where sender = our address - if (address) { + // 2) OUTBOUND CONFIRMATION: use emitterAddress (Safe in fast mode, EOA in classic) + const emitter = emitterAddress || address; + if (emitter) { const senderTopic = - "0x000000000000000000000000" + address.slice(2).toLowerCase(); + "0x000000000000000000000000" + emitter.slice(2).toLowerCase(); const messageFilterOutConfirm = { address: LOGCHAIN_SINGLETON_ADDR, topics: [EVENT_SIGNATURES.MessageSent, senderTopic], @@ -553,4 +587,4 @@ export const useMessageListener = ({ lastKnownBlock, oldestScannedBlock, }; -}; +}; \ No newline at end of file diff --git a/apps/demo/src/hooks/useMessageProcessor.ts b/apps/demo/src/hooks/useMessageProcessor.ts index bb2c2ad..d9afd52 100644 --- a/apps/demo/src/hooks/useMessageProcessor.ts +++ b/apps/demo/src/hooks/useMessageProcessor.ts @@ -6,6 +6,7 @@ import { type IdentityContext, decryptMessage, parseHandshakePayload, + parseBindingMessage, verifyHandshakeIdentity, IdentityKeyPair, decodeUnifiedPubKeys, @@ -32,6 +33,8 @@ import { interface UseMessageProcessorProps { readProvider: any; address: string | undefined; + /** Safe address in fast mode, EOA in classic mode. Used for outbound detection. */ + emitterAddress: string | undefined; identityKeyPair: IdentityKeyPair | null; identityContext: IdentityContext; onLog: (message: string) => void; @@ -56,6 +59,7 @@ interface UseMessageProcessorProps { export const useMessageProcessor = ({ readProvider, address, + emitterAddress, identityKeyPair, identityContext, onLog, @@ -205,10 +209,23 @@ export const useMessageProcessor = ({ } } + // Extract EOA (identity) from binding message + let identityAddress = cleanSenderAddress; // fallback to event sender + if (hasValidIdentityProof && handshakeContent.identityProof?.message) { + try { + const parsed = parseBindingMessage(handshakeContent.identityProof.message); + if (parsed.address) { + identityAddress = parsed.address; + } + } catch (e) { + } + } + const pendingHandshake: PendingHandshake = { id: log.transactionHash, ownerAddress: address, - sender: cleanSenderAddress, + sender: identityAddress, // EOA (identity) + emitterAddress: cleanSenderAddress, // Safe or EOA (event sender) identityPubKey, signingPubKey, ephemeralPubKey, @@ -229,7 +246,7 @@ export const useMessageProcessor = ({ const handshakeMessage: Message = { id: generateTempMessageId(), topic: "", - sender: cleanSenderAddress, + sender: identityAddress, recipient: address, ciphertext: "", timestamp: Date.now(), @@ -250,7 +267,7 @@ export const useMessageProcessor = ({ setMessages((prev) => [...prev, handshakeMessage]); onLog( - `๐Ÿ“จ Handshake received from ${cleanSenderAddress.slice(0, 8)}... ${ + `๐Ÿ“จ Handshake received from ${identityAddress.slice(0, 8)}... ${ isVerified ? "โœ…" : "โš ๏ธ" }: "${handshakeContent.plaintextPayload}"` ); @@ -286,18 +303,20 @@ export const useMessageProcessor = ({ `๐Ÿ” Debug: Loaded ${currentContacts.length} contacts from DB for handshake response` ); + // Use matchedContactAddress from listener (tag-based matching) + // This works regardless of whether responder is EOA or Safe const contact = currentContacts.find( (c) => - c.address.toLowerCase() === responder.toLowerCase() && + c.address.toLowerCase() === event.matchedContactAddress?.toLowerCase() && c.status === "handshake_sent" ); if (!contact || !contact.ephemeralKey) { onLog( - `โ“ Received handshake response from unknown contact: ${responder.slice( + `โ“ Received handshake response but no matching pending contact found (responder: ${responder.slice( 0, 8 - )}...` + )}...)` ); return; } @@ -319,7 +338,7 @@ export const useMessageProcessor = ({ if (!result.isValid || !result.keys) { onLog( - `โŒ Failed to verify handshake response from ${responder.slice( + `โŒ Failed to verify handshake response from ${contact.address.slice( 0, 8 )}... - invalid signature or tag mismatch` @@ -358,13 +377,13 @@ export const useMessageProcessor = ({ }); if (!isValidTopics) { onLog( - `โŒ Invalid duplex topics checksum for ${responder.slice(0, 8)}...` + `โŒ Invalid duplex topics checksum for ${contact.address.slice(0, 8)}...` ); return; } onLog( - `โœ… Handshake response verified from ${responder.slice(0, 8)}...` + `โœ… Handshake response verified from ${contact.address.slice(0, 8)}...` ); const updatedContact: Contact = { @@ -381,16 +400,17 @@ export const useMessageProcessor = ({ await dbService.saveContact(updatedContact); + // Use contact.address (the EOA we initiated to), not responder (could be Safe) setContacts((prev) => prev.map((c) => - c.address.toLowerCase() === responder.toLowerCase() + c.address.toLowerCase() === contact.address.toLowerCase() ? updatedContact : c ) ); onLog( - `๐Ÿค Handshake completed with ${responder.slice(0, 8)}... : "${ + `๐Ÿค Handshake completed with ${contact.address.slice(0, 8)}... : "${ note || "No message" }"` ); @@ -398,7 +418,7 @@ export const useMessageProcessor = ({ const responseMessage: Message = { id: generateTempMessageId(), topic: updatedContact.topicInbound || "", - sender: responder, + sender: contact.address, // Use contact address, not responder recipient: address, ciphertext: "", timestamp: Date.now(), @@ -443,7 +463,9 @@ export const useMessageProcessor = ({ const ciphertextJson = new TextDecoder().decode( hexToUint8Array(ciphertextBytes) ); - const isOurMessage = sender.toLowerCase() === address.toLowerCase(); + // Use emitterAddress (Safe in fast mode) for outbound detection + const emitter = emitterAddress || address; + const isOurMessage = emitter && sender.toLowerCase() === emitter.toLowerCase(); if (!isOurMessage) { const already = await dbService.getByDedupKey(key); @@ -583,29 +605,17 @@ export const useMessageProcessor = ({ } // INCOMING MESSAGE + // Match by topicInbound (not sender address) - works for EOA or Safe senders const currentContacts = await dbService.getAllContacts(address); const contact = currentContacts.find( (c) => - c.address.toLowerCase() === sender.toLowerCase() && + c.topicInbound === topic && c.status === "established" ); if (!contact || !contact.identityPubKey || !contact.signingPubKey) { onLog( - `โ“ Received message from unknown contact: ${sender.slice(0, 8)}...` - ); - return; - } - - if (contact.topicInbound && topic !== contact.topicInbound) { - onLog( - `โŒ Message topic mismatch from ${sender.slice( - 0, - 8 - )}... - expected ${contact.topicInbound.slice( - 0, - 10 - )}..., got ${topic.slice(0, 10)}...` + `โ“ Received message on unknown topic: ${topic.slice(0, 10)}... from ${sender.slice(0, 8)}...` ); return; } @@ -617,14 +627,14 @@ export const useMessageProcessor = ({ ); if (!decryptedMessage) { - onLog(`โœ— Failed to decrypt message from ${sender.slice(0, 8)}...`); + onLog(`โœ— Failed to decrypt message from ${contact.address.slice(0, 8)}...`); return; } const message: Message = { id: generateMessageId(log.transactionHash, log), topic: topic, - sender: sender, + sender: contact.address, // Use contact address, not on-chain sender recipient: address, ciphertext: ciphertextJson, timestamp: Number(timestamp) * 1000, @@ -663,15 +673,16 @@ export const useMessageProcessor = ({ await dbService.saveContact(updatedContact); + // Use contact.address (not sender from event) setContacts((prev) => prev.map((c) => - c.address.toLowerCase() === sender.toLowerCase() + c.address.toLowerCase() === contact.address.toLowerCase() ? updatedContact : c ) ); - onLog(`Message from ${sender.slice(0, 8)}...: "${decryptedMessage}"`); + onLog(`Message from ${contact.address.slice(0, 8)}...: "${decryptedMessage}"`); } } catch (error) { onLog(`โœ— Failed to process message log: ${error}`); @@ -767,4 +778,4 @@ export const useMessageProcessor = ({ updateContact, processEvents, }; -}; +}; \ No newline at end of file diff --git a/apps/demo/src/hooks/useSessionSetup.ts b/apps/demo/src/hooks/useSessionSetup.ts index d2930ce..caea0d3 100644 --- a/apps/demo/src/hooks/useSessionSetup.ts +++ b/apps/demo/src/hooks/useSessionSetup.ts @@ -5,7 +5,7 @@ import { getOrCreateSafeForOwner, ensureModuleEnabled, } from "../services/safeAccount.js"; -import { LOGCHAIN_SINGLETON_ADDR, SAFE_MODULE_ADDRESS } from "../types.js"; +import { LOGCHAIN_SINGLETON_ADDR, SAFE_MODULE_ADDRESS, ExecutionMode } from "../types.js"; interface UseSessionSetupParams { walletClient: any; @@ -21,6 +21,8 @@ interface UseSessionSetupParams { setIsSafeDeployed: (deployed: boolean) => void; setIsModuleEnabled: (enabled: boolean) => void; setNeedsSessionSetup: (needs: boolean) => void; + // NEW: Mode from useInitIdentity + executionMode: ExecutionMode | null; // Callbacks onSessionSetupComplete?: () => void; } @@ -38,21 +40,24 @@ export function useSessionSetup({ setIsSafeDeployed, setIsModuleEnabled, setNeedsSessionSetup, + executionMode, onSessionSetupComplete, }: UseSessionSetupParams) { - const [sessionSignerBalance, setSessionSignerBalance] = useState< - bigint | null - >(null); + const [sessionSignerBalance, setSessionSignerBalance] = useState(null); const [loading, setLoading] = useState(false); - // Refresh session signer balance periodically + // =========================================================================== + // NEW: Skip everything for classic mode + // =========================================================================== + const isClassicMode = executionMode === 'classic'; + + // Refresh session signer balance (only for fast mode) useEffect(() => { - if (!sessionSignerAddr || !readProvider) return; + if (isClassicMode || !sessionSignerAddr || !readProvider) return; const refreshBalance = async () => { try { const balance = await readProvider.getBalance(sessionSignerAddr); - console.log(`๐Ÿ”„ Balance refresh: ${Number(balance) / 1e18} ETH`); setSessionSignerBalance(balance); } catch (err) { console.error("Failed to refresh balance:", err); @@ -62,20 +67,26 @@ export function useSessionSetup({ refreshBalance(); const interval = setInterval(refreshBalance, 10000); return () => clearInterval(interval); - }, [sessionSignerAddr, readProvider]); + }, [sessionSignerAddr, readProvider, isClassicMode]); const refreshSessionBalance = useCallback(async () => { - if (!sessionSignerAddr || !readProvider) return; + if (isClassicMode || !sessionSignerAddr || !readProvider) return; try { const balance = await readProvider.getBalance(sessionSignerAddr); - console.log(`๐Ÿ”„ Manual balance refresh: ${Number(balance) / 1e18} ETH`); + console.log(`๐Ÿ”„ Balance: ${Number(balance) / 1e18} ETH`); setSessionSignerBalance(balance); } catch (err) { console.error("Failed to refresh balance:", err); } - }, [sessionSignerAddr, readProvider]); + }, [sessionSignerAddr, readProvider, isClassicMode]); const setupSession = useCallback(async () => { + // NEW: Guard for classic mode + if (isClassicMode) { + addLog("Classic mode: no session setup needed"); + return; + } + if (!walletClient || !address || !safeAddr || !sessionSignerAddr) { addLog("Missing requirements for session setup"); return; @@ -86,18 +97,15 @@ export function useSessionSetup({ const ethersProvider = new BrowserProvider(walletClient.transport); const ethersSigner = await ethersProvider.getSigner(); - console.log(`\n========== SETTING UP SESSION ==========`); - console.log(`Safe: ${safeAddr}`); - console.log(`Safe deployed: ${isSafeDeployed}`); + console.log(`\n========== SETTING UP SESSION (Fast Mode) ==========`); + console.log(`VerbEth Safe: ${safeAddr}`); + console.log(`Deployed: ${isSafeDeployed}`); console.log(`Module enabled: ${isModuleEnabled}`); console.log(`Session signer: ${sessionSignerAddr}`); - console.log(`Target (LogChain): ${LOGCHAIN_SINGLETON_ADDR}`); - // ============================================================ - // CASE 1: Safe not deployed โ†’ Single TX (deploy + module + session) - // ============================================================ + // Case 1: Safe not deployed โ†’ Deploy + enable + configure (1 tx via helper) if (!isSafeDeployed) { - addLog("Deploying Safe + enabling module + configuring session (1 tx)..."); + addLog("Deploying VerbEth Safe + enabling module + configuring session..."); const { isDeployed, moduleEnabled, sessionConfigured } = await getOrCreateSafeForOwner({ chainId, @@ -109,6 +117,7 @@ export function useSessionSetup({ sessionSigner: sessionSignerAddr, target: LOGCHAIN_SINGLETON_ADDR, }, + useApiLookup: false, // NEW: deterministic only }); if (!isDeployed) { @@ -119,24 +128,18 @@ export function useSessionSetup({ setIsModuleEnabled(moduleEnabled); if (sessionConfigured) { - console.log(`โœ… Safe deployed + module enabled + session configured in 1 tx`); - addLog("โœ“ Setup complete (1 tx)!"); - console.log(`==========================================\n`); + console.log(`โœ… All configured in 1 tx`); + addLog("โœ“ Setup complete!"); setNeedsSessionSetup(false); - // Allow RPC state propagation before reinit await new Promise(resolve => setTimeout(resolve, 1500)); onSessionSetupComplete?.(); return; } - - // Fallback: helper didn't configure session, need separate tx - console.warn("Session not configured during deploy, falling back to separate tx"); + console.warn("Session not configured during deploy, falling back..."); } - // ============================================================ - // CASE 2: Safe exists but module not enabled โ†’ Enable module first - // ============================================================ + // Case 2: Safe exists but module not enabled if (!isModuleEnabled) { addLog("Enabling session module..."); @@ -150,6 +153,7 @@ export function useSessionSetup({ sessionSigner: sessionSignerAddr, target: LOGCHAIN_SINGLETON_ADDR, }, + useApiLookup: false, }); await ensureModuleEnabled(protocolKit); @@ -157,30 +161,29 @@ export function useSessionSetup({ console.log(`โœ… Module enabled`); } - // ============================================================ - // CASE 3: Safe + module exist โ†’ Just setup session - // ============================================================ + // Case 3: Safe + module exist โ†’ Just setup session const moduleContract = new Contract( SAFE_MODULE_ADDRESS, ["function setupSession(address safe, address signer, uint256 expiry, address target)"], ethersSigner ); - addLog("Setting up session (signer + target)..."); + addLog("Setting up session..."); const tx = await moduleContract.setupSession( safeAddr, sessionSignerAddr, - BigInt("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"), // no expiry + BigInt("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"), LOGCHAIN_SINGLETON_ADDR ); - console.log(`TX hash: ${tx.hash}`); + console.log(`TX: ${tx.hash}`); await tx.wait(); - console.log(`โœ… Session signer authorized + LogChain target allowed`); + console.log(`โœ… Session configured`); addLog("โœ“ Session setup complete!"); - console.log(`==========================================\n`); + console.log(`=====================================================\n`); setNeedsSessionSetup(false); onSessionSetupComplete?.(); + } catch (err: any) { console.error(`Session setup error:`, err); addLog(`โœ— Session setup failed: ${err.message}`); @@ -195,6 +198,7 @@ export function useSessionSetup({ isSafeDeployed, isModuleEnabled, chainId, + isClassicMode, addLog, setIsSafeDeployed, setIsModuleEnabled, @@ -202,6 +206,16 @@ export function useSessionSetup({ onSessionSetupComplete, ]); + // NEW: Return null values for classic mode + if (isClassicMode) { + return { + sessionSignerBalance: null, + sessionLoading: false, + refreshSessionBalance: async () => {}, + setupSession: async () => {}, + }; + } + return { sessionSignerBalance, sessionLoading: loading, diff --git a/apps/demo/src/services/safeAccount.ts b/apps/demo/src/services/safeAccount.ts index f5b2f9d..9f96c97 100644 --- a/apps/demo/src/services/safeAccount.ts +++ b/apps/demo/src/services/safeAccount.ts @@ -20,25 +20,88 @@ export interface SessionConfig { target: string } +export async function predictVerbEthSafeAddress(params: { + chainId: number + ownerAddress: `0x${string}` + sessionSignerAddr: string + providerEip1193: any + contractNetworks?: any +}): Promise<`0x${string}`> { + const { chainId, ownerAddress, sessionSignerAddr, providerEip1193, contractNetworks } = params + + const sessionConfig: SessionConfig = { + sessionSigner: sessionSignerAddr, + target: LOGCHAIN_SINGLETON_ADDR, + } + + const safeAccountConfig = buildSafeAccountConfig( + getAddress(ownerAddress), + chainId, + sessionConfig + ) + + const predictedSafe = { + safeAccountConfig, + safeDeploymentConfig: { saltNonce: '0' }, + } + + const maybeNetworks = contractNetworks ? { contractNetworks } : {} + + const tempKit = await Safe.init({ + provider: providerEip1193, + signer: ownerAddress, + predictedSafe, + ...maybeNetworks, + }) + + return (await tempKit.getAddress()) as `0x${string}` +} + +export async function checkSafeOnChainStatus(params: { + safeAddress: `0x${string}` + providerEip1193: any + ownerAddress: `0x${string}` + contractNetworks?: any +}): Promise<{ + isDeployed: boolean + moduleEnabled: boolean +}> { + const { safeAddress, providerEip1193, ownerAddress, contractNetworks } = params + const maybeNetworks = contractNetworks ? { contractNetworks } : {} + + try { + const protocolKit = await Safe.init({ + provider: providerEip1193, + signer: ownerAddress, + safeAddress, + ...maybeNetworks, + }) + + const isDeployed = await protocolKit.isSafeDeployed() + if (!isDeployed) { + return { isDeployed: false, moduleEnabled: false } + } + + const moduleEnabled = await protocolKit.isModuleEnabled(SAFE_MODULE_ADDRESS) + return { isDeployed: true, moduleEnabled } + } catch { + return { isDeployed: false, moduleEnabled: false } + } +} + export async function getOrCreateSafeForOwner(params: { chainId: number ownerAddress: `0x${string}` providerEip1193: any ethersSigner: any - /** - * Deploy the Safe if it doesn't exist yet - */ deployIfMissing?: boolean - /** - * Session config - MUST be provided for consistent address prediction. - * The Safe address is deterministic based on setup params including to/data. - * Pass the same sessionConfig for both prediction and deployment. - */ sessionConfig: SessionConfig + contractNetworks?: any /** - * Pass Safe contractNetworks if on a chain not bundled in this protocol-kit version + * NEW: Only set to true for "custom" mode (import existing Safe) + * Default: false (deterministic VerbEth Safe only) */ - contractNetworks?: any + useApiLookup?: boolean }) { const { chainId, @@ -48,110 +111,86 @@ export async function getOrCreateSafeForOwner(params: { deployIfMissing = false, sessionConfig, contractNetworks, + useApiLookup = false, // NEW: defaults to false } = params const ownerAddress = getAddress(rawOwnerAddress) as `0x${string}` - - const apiKit = new SafeApiKit({ - chainId: BigInt(chainId), - ...(SAFE_API_KEY ? { apiKey: SAFE_API_KEY } : {}), - }) - - let existingSafeAddress: `0x${string}` | undefined - - // 1) Try to find an existing Safe for owner via API - // Note: This may return a Safe with different config. We'll verify below. - try { - const { safes } = await apiKit.getSafesByOwner(ownerAddress) - existingSafeAddress = safes?.[0] as `0x${string}` | undefined - } catch (e: any) { - const status = - e?.response?.status ?? - e?.status ?? - e?.cause?.status ?? - (typeof e?.message === 'string' && e.message.includes('404') ? 404 : undefined) - - if (status === 404) { - existingSafeAddress = undefined - } else { - throw new Error(`Safe Tx Service error: ${e?.message ?? String(e)}`) - } - } - - // Spread optional contractNetworks only if provided const maybeNetworks = contractNetworks ? { contractNetworks } : {} - // 2) Build predicted safe config - ALWAYS include sessionConfig for consistent address + // 1) ALWAYS build deterministic config first const safeAccountConfig = buildSafeAccountConfig(ownerAddress, chainId, sessionConfig) - const predictedSafe = { safeAccountConfig, - safeDeploymentConfig: { - saltNonce: '0', - }, + safeDeploymentConfig: { saltNonce: '0' }, } - // 2b) If API didn't find a Safe, check on-chain at predicted address - if (!existingSafeAddress) { - const tempKit = await Safe.init({ - provider: providerEip1193, - signer: ownerAddress, - predictedSafe, - ...maybeNetworks, - }) - const predictedAddress = await tempKit.getAddress() - const isDeployedOnChain = await tempKit.isSafeDeployed() + // 2) Compute deterministic VerbEth Safe address + const tempKit = await Safe.init({ + provider: providerEip1193, + signer: ownerAddress, + predictedSafe, + ...maybeNetworks, + }) + const verbEthSafeAddress = (await tempKit.getAddress()) as `0x${string}` - if (isDeployedOnChain) { - existingSafeAddress = predictedAddress as `0x${string}` - console.log(`Safe not in API but found on-chain at ${predictedAddress}`) - } - } + // 3) Check if OUR deterministic Safe exists on-chain + const isDeployedOnChain = await tempKit.isSafeDeployed() - // 3) If existing Safe found, use it (may have been deployed with different config) - if (existingSafeAddress) { + if (isDeployedOnChain) { + // Our VerbEth Safe exists - use it const protocolKit = await Safe.init({ provider: providerEip1193, signer: ownerAddress, - safeAddress: existingSafeAddress, + safeAddress: verbEthSafeAddress, ...maybeNetworks, }) const moduleEnabled = await protocolKit.isModuleEnabled(SAFE_MODULE_ADDRESS) + console.log(`Found VerbEth Safe on-chain at ${verbEthSafeAddress}`) return { - safeAddress: existingSafeAddress, + safeAddress: verbEthSafeAddress, protocolKit, isDeployed: true, moduleEnabled, - sessionConfigured: false, // Can't know without checking module state + sessionConfigured: moduleEnabled, // If module enabled via helper, session is configured } } - // 4) No existing Safe - predict address with our config - let protocolKit = await Safe.init({ - provider: providerEip1193, - signer: ownerAddress, - predictedSafe, - ...maybeNetworks, - }) + // 4) OPTIONAL: API lookup for custom mode only + if (useApiLookup) { + const apiKit = new SafeApiKit({ + chainId: BigInt(chainId), + ...(SAFE_API_KEY ? { apiKey: SAFE_API_KEY } : {}), + }) - const safeAddress = (await protocolKit.getAddress()) as `0x${string}` + try { + const { safes } = await apiKit.getSafesByOwner(ownerAddress) + if (safes?.length) { + console.log(`API found ${safes.length} Safe(s) for owner (custom mode)`) + // For custom mode, caller would handle Safe selection UI + // This is placeholder for "coming soon" feature + } + } catch (e: any) { + console.warn(`Safe API lookup failed: ${e?.message}`) + } + } + // 5) VerbEth Safe not deployed yet - return predicted address if (!deployIfMissing) { return { - safeAddress, - protocolKit, + safeAddress: verbEthSafeAddress, + protocolKit: tempKit, isDeployed: false, moduleEnabled: false, sessionConfigured: false, } } - // 5) Deploy (createProxyWithNonce tx) - console.log(`๐Ÿš€ Deploying Safe with module + session configured...`) + // 6) Deploy the VerbEth Safe + console.log(`๐Ÿš€ Deploying VerbEth Safe with module + session configured...`) - const deploymentTx = await protocolKit.createSafeDeploymentTransaction() + const deploymentTx = await tempKit.createSafeDeploymentTransaction() const txResp = await ethersSigner.sendTransaction({ to: deploymentTx.to, @@ -160,52 +199,44 @@ export async function getOrCreateSafeForOwner(params: { }) const receipt = await txResp.wait() - const statusOk = receipt?.status === 1 || receipt?.status === 1n - if (!statusOk) { + if (receipt?.status !== 1 && receipt?.status !== 1n) { throw new Error('Safe deployment reverted') } - console.log(`โœ… Safe deployed at ${safeAddress}`) + console.log(`โœ… VerbEth Safe deployed at ${verbEthSafeAddress}`) - // If we used the helper with sessionConfig, module + session are already configured - // Skip verification to avoid timing issues with RPC propagation const helperAddress = MODULE_SETUP_HELPER_ADDRESS[chainId] if (helperAddress && sessionConfig) { console.log(` Module enabled: true (via helper)`) console.log(` Session configured: true (via helper)`) return { - safeAddress, - protocolKit: null, // Not needed - caller should trigger reinit + safeAddress: verbEthSafeAddress, + protocolKit: null, isDeployed: true, moduleEnabled: true, sessionConfigured: true, } } - // Fallback: re-init and verify (for chains without helper) - // Add small delay to allow RPC propagation + // Fallback for chains without helper await new Promise((resolve) => setTimeout(resolve, 2000)) - protocolKit = await Safe.init({ + const protocolKit = await Safe.init({ provider: providerEip1193, signer: ownerAddress, - safeAddress, + safeAddress: verbEthSafeAddress, ...maybeNetworks, }) const moduleEnabled = await protocolKit.isModuleEnabled(SAFE_MODULE_ADDRESS) - const sessionConfigured = false // Helper wasn't used - - console.log(` Module enabled: ${moduleEnabled}`) - console.log(` Session configured: ${sessionConfigured}`) return { - safeAddress, + safeAddress: verbEthSafeAddress, protocolKit, isDeployed: true, moduleEnabled, - sessionConfigured, + sessionConfigured: false, } } @@ -251,6 +282,10 @@ function buildSafeAccountConfig( } } +export function isHelperAvailable(chainId: number): boolean { + return !!MODULE_SETUP_HELPER_ADDRESS[chainId] +} + /** * Enable module on an already-deployed Safe (separate tx, for legacy Safes) */ diff --git a/apps/demo/src/services/schema.ts b/apps/demo/src/services/schema.ts index 1172fdd..0bceb41 100644 --- a/apps/demo/src/services/schema.ts +++ b/apps/demo/src/services/schema.ts @@ -22,11 +22,11 @@ export class VerbEthDatabase extends Dexie { this.version(1).stores({ identity: "address", contacts: - "[address+ownerAddress], ownerAddress, lastTimestamp, status, topicOutbound, topicInbound", + "[address+ownerAddress], ownerAddress, lastTimestamp, status, topicOutbound, topicInbound, emitterAddress", messages: "id, ownerAddress, sender, recipient, topic, nonce, timestamp, blockTimestamp, read, status, [ownerAddress+sender+status], [ownerAddress+sender+topic+nonce+status]", - dedup: "key, messageId, txHash, blockNumber", // key is PRIMARY KEY - pendingHandshakes: "id, ownerAddress, sender, timestamp, verified", + dedup: "key, messageId, txHash, blockNumber", + pendingHandshakes: "id, ownerAddress, sender, timestamp, verified, emitterAddress", settings: "name", }); diff --git a/apps/demo/src/types.ts b/apps/demo/src/types.ts index 2887bed..d39b096 100644 --- a/apps/demo/src/types.ts +++ b/apps/demo/src/types.ts @@ -30,6 +30,8 @@ export const EVENT_SIGNATURES = { export interface Contact { /** Contact's address (EOA or Safe) */ address: string; + /** Contact's emitter address (Safe in fast mode, same as address in classic mode) */ + emitterAddress?: string; /** Owner's address (the user viewing this contact) */ ownerAddress: string; /** Contact's display name */ @@ -79,6 +81,7 @@ export interface Message { export interface PendingHandshake { id: string; ownerAddress: string; + emitterAddress?: string; sender: string; identityPubKey: Uint8Array; signingPubKey: Uint8Array; @@ -89,6 +92,8 @@ export interface PendingHandshake { verified: boolean; } +export type ExecutionMode = 'classic' | 'fast' | 'custom'; + export interface StoredIdentity { /** EOA address */ address: string; @@ -107,6 +112,8 @@ export interface StoredIdentity { * Ethereum address of the session signer. */ sessionAddress?: string; + executionMode?: ExecutionMode; + emitterAddress?: string; // EOA for classic, Safe for fast/custom } export interface AppSettings { @@ -147,6 +154,7 @@ export interface ProcessedEvent { rawLog: any; blockNumber: number; timestamp: number; + matchedContactAddress?: string; } export interface MessageListenerResult { From 52078cc0467711e03077cb37cec88a9becd6d09a Mon Sep 17 00:00:00 2001 From: Marco Esposito Date: Fri, 2 Jan 2026 19:00:53 +0100 Subject: [PATCH 07/51] fix reinitialization and overwriting --- apps/demo/src/App.tsx | 4 +--- apps/demo/src/components/IdentityCreation.tsx | 4 +--- .../src/components/SessionSetupPrompt.tsx | 1 - apps/demo/src/hooks/useSessionSetup.ts | 20 ++++++------------- apps/demo/src/services/safeAccount.ts | 2 +- 5 files changed, 9 insertions(+), 22 deletions(-) diff --git a/apps/demo/src/App.tsx b/apps/demo/src/App.tsx index 77fc531..a958260 100644 --- a/apps/demo/src/App.tsx +++ b/apps/demo/src/App.tsx @@ -83,7 +83,6 @@ export default function App() { executionMode, emitterAddress, createIdentity, - triggerReinit, } = useInitIdentity({ walletClient, address, @@ -116,7 +115,6 @@ export default function App() { setIsSafeDeployed, setIsModuleEnabled, setNeedsSessionSetup, - onSessionSetupComplete: () => triggerReinit(), executionMode, }); @@ -250,7 +248,7 @@ export default function App() { {/* LEFT: title */}

- WorldLog Chat + World Post

powered by Verbeth SDK diff --git a/apps/demo/src/components/IdentityCreation.tsx b/apps/demo/src/components/IdentityCreation.tsx index ab2663c..526c476 100644 --- a/apps/demo/src/components/IdentityCreation.tsx +++ b/apps/demo/src/components/IdentityCreation.tsx @@ -9,7 +9,6 @@ interface IdentityCreationProps { onImportIdentity?: () => void; address: string; signingStep?: 1 | 2 | null; - // NEW: Mode-related props needsModeSelection: boolean; fastModeAvailable: boolean; chainId: number; @@ -100,7 +99,6 @@ function StepIndicator({ step }: { step: 1 | 2 }) { ); } -// NEW: Mode selection card component function ModeCard({ mode, title, @@ -168,7 +166,7 @@ export function IdentityCreation({ fastModeAvailable, chainId, }: IdentityCreationProps) { - // NEW: Track selected mode locally before identity creation starts + //Track selected mode locally before identity creation starts const [selectedMode, setSelectedMode] = useState(null); const handleModeSelect = (mode: ExecutionMode) => { diff --git a/apps/demo/src/components/SessionSetupPrompt.tsx b/apps/demo/src/components/SessionSetupPrompt.tsx index 25cb64e..1a44152 100644 --- a/apps/demo/src/components/SessionSetupPrompt.tsx +++ b/apps/demo/src/components/SessionSetupPrompt.tsx @@ -44,7 +44,6 @@ export function SessionSetupPrompt({ // Determine what setup is needed const getSetupInfo = () => { if (!isSafeDeployed) { - // New user: everything in 1 tx return { txCount: "1 tx", title: "Deploy & Authorize", diff --git a/apps/demo/src/hooks/useSessionSetup.ts b/apps/demo/src/hooks/useSessionSetup.ts index caea0d3..b66b571 100644 --- a/apps/demo/src/hooks/useSessionSetup.ts +++ b/apps/demo/src/hooks/useSessionSetup.ts @@ -21,10 +21,7 @@ interface UseSessionSetupParams { setIsSafeDeployed: (deployed: boolean) => void; setIsModuleEnabled: (enabled: boolean) => void; setNeedsSessionSetup: (needs: boolean) => void; - // NEW: Mode from useInitIdentity executionMode: ExecutionMode | null; - // Callbacks - onSessionSetupComplete?: () => void; } export function useSessionSetup({ @@ -41,14 +38,10 @@ export function useSessionSetup({ setIsModuleEnabled, setNeedsSessionSetup, executionMode, - onSessionSetupComplete, }: UseSessionSetupParams) { const [sessionSignerBalance, setSessionSignerBalance] = useState(null); const [loading, setLoading] = useState(false); - // =========================================================================== - // NEW: Skip everything for classic mode - // =========================================================================== const isClassicMode = executionMode === 'classic'; // Refresh session signer balance (only for fast mode) @@ -81,7 +74,7 @@ export function useSessionSetup({ }, [sessionSignerAddr, readProvider, isClassicMode]); const setupSession = useCallback(async () => { - // NEW: Guard for classic mode + //Guard for classic mode if (isClassicMode) { addLog("Classic mode: no session setup needed"); return; @@ -117,7 +110,7 @@ export function useSessionSetup({ sessionSigner: sessionSignerAddr, target: LOGCHAIN_SINGLETON_ADDR, }, - useApiLookup: false, // NEW: deterministic only + useApiLookup: false, }); if (!isDeployed) { @@ -130,9 +123,10 @@ export function useSessionSetup({ if (sessionConfigured) { console.log(`โœ… All configured in 1 tx`); addLog("โœ“ Setup complete!"); + setIsModuleEnabled(true); setNeedsSessionSetup(false); - await new Promise(resolve => setTimeout(resolve, 1500)); - onSessionSetupComplete?.(); + // Don't call onSessionSetupComplete - state already updated via setters. + // Calling reinit would read stale RPC data and overwrite correct state. return; } @@ -182,7 +176,6 @@ export function useSessionSetup({ addLog("โœ“ Session setup complete!"); console.log(`=====================================================\n`); setNeedsSessionSetup(false); - onSessionSetupComplete?.(); } catch (err: any) { console.error(`Session setup error:`, err); @@ -203,10 +196,9 @@ export function useSessionSetup({ setIsSafeDeployed, setIsModuleEnabled, setNeedsSessionSetup, - onSessionSetupComplete, ]); - // NEW: Return null values for classic mode + //Return null values for classic mode if (isClassicMode) { return { sessionSignerBalance: null, diff --git a/apps/demo/src/services/safeAccount.ts b/apps/demo/src/services/safeAccount.ts index 9f96c97..910daad 100644 --- a/apps/demo/src/services/safeAccount.ts +++ b/apps/demo/src/services/safeAccount.ts @@ -111,7 +111,7 @@ export async function getOrCreateSafeForOwner(params: { deployIfMissing = false, sessionConfig, contractNetworks, - useApiLookup = false, // NEW: defaults to false + useApiLookup = false, } = params const ownerAddress = getAddress(rawOwnerAddress) as `0x${string}` From 9c7db3ef43e3c4dd8b8beba8805c4bd8995b84d4 Mon Sep 17 00:00:00 2001 From: Marco Esposito Date: Fri, 9 Jan 2026 18:15:57 +0100 Subject: [PATCH 08/51] core: double rathcet first refactor --- apps/demo/src/App.tsx | 2 +- apps/demo/src/components/InitialForm.tsx | 4 +- apps/demo/src/hooks/useChatActions.ts | 203 ++++++-- apps/demo/src/hooks/useMessageListener.ts | 7 +- apps/demo/src/hooks/useMessageProcessor.ts | 222 ++++++-- apps/demo/src/hooks/useMessageQueue.ts | 390 ++++++++++++++ apps/demo/src/services/DbService.ts | 243 ++++++++- apps/demo/src/services/schema.ts | 26 +- apps/demo/src/types.ts | 139 ++++- apps/docs/double-ratchet.md | 566 +++++++++++++++++++++ packages/sdk/src/client/VerbethClient.ts | 223 ++++---- packages/sdk/src/client/types.ts | 5 +- packages/sdk/src/crypto.ts | 73 ++- packages/sdk/src/index.ts | 4 +- packages/sdk/src/ratchet/auth.ts | 121 +++++ packages/sdk/src/ratchet/codec.ts | 192 +++++++ packages/sdk/src/ratchet/decrypt.ts | 325 ++++++++++++ packages/sdk/src/ratchet/encrypt.ts | 109 ++++ packages/sdk/src/ratchet/index.ts | 113 ++++ packages/sdk/src/ratchet/kdf.ts | 95 ++++ packages/sdk/src/ratchet/session.ts | 184 +++++++ packages/sdk/src/ratchet/types.ts | 225 ++++++++ packages/sdk/src/send.ts | 153 +++--- packages/sdk/test/executor.test.ts | 121 +---- packages/sdk/test/ratchet.test.ts | 445 ++++++++++++++++ packages/sdk/test/utils.test.ts | 70 --- plan.md | 205 ++++++++ 27 files changed, 3989 insertions(+), 476 deletions(-) create mode 100644 apps/demo/src/hooks/useMessageQueue.ts create mode 100644 apps/docs/double-ratchet.md create mode 100644 packages/sdk/src/ratchet/auth.ts create mode 100644 packages/sdk/src/ratchet/codec.ts create mode 100644 packages/sdk/src/ratchet/decrypt.ts create mode 100644 packages/sdk/src/ratchet/encrypt.ts create mode 100644 packages/sdk/src/ratchet/index.ts create mode 100644 packages/sdk/src/ratchet/kdf.ts create mode 100644 packages/sdk/src/ratchet/session.ts create mode 100644 packages/sdk/src/ratchet/types.ts create mode 100644 packages/sdk/test/ratchet.test.ts create mode 100644 plan.md diff --git a/apps/demo/src/App.tsx b/apps/demo/src/App.tsx index a958260..cddb6f1 100644 --- a/apps/demo/src/App.tsx +++ b/apps/demo/src/App.tsx @@ -251,7 +251,7 @@ export default function App() { World Post
- powered by Verbeth SDK + powered by the World Computer
{/* RIGHT: auth buttons - EOA only */} diff --git a/apps/demo/src/components/InitialForm.tsx b/apps/demo/src/components/InitialForm.tsx index c42c1e1..7d32a1f 100644 --- a/apps/demo/src/components/InitialForm.tsx +++ b/apps/demo/src/components/InitialForm.tsx @@ -78,11 +78,11 @@ export function InitialForm({ ) : (

- {isAnyConnected ? "Hi, start your first chat" : "just verb it"} + {isAnyConnected ? "Hi, start your first chat" : "Chat away with anyone"}

- Uncensorable. Private by design. + Private, unstoppable digital correspondence.
diff --git a/apps/demo/src/hooks/useChatActions.ts b/apps/demo/src/hooks/useChatActions.ts index db20977..1571224 100644 --- a/apps/demo/src/hooks/useChatActions.ts +++ b/apps/demo/src/hooks/useChatActions.ts @@ -1,12 +1,34 @@ +// src/hooks/useChatActions.ts + +/** + * Chat actions hook with Double Ratchet integration. + * + * Key changes from legacy: + * - acceptHandshake now creates ratchet session + * - sendMessageToContact uses ratchet encryption with two-phase commit + * - Sequential blocking: only one pending message per conversation + */ + import { useCallback } from "react"; +import { hexlify } from "ethers"; import { pickOutboundTopic, - VerbethClient + VerbethClient, + // Ratchet imports + initSessionAsResponder, + ratchetEncrypt, + packageRatchetPayload, } from "@verbeth/sdk"; -import { Contact, generateTempMessageId } from "../types.js"; +import { dbService } from "../services/DbService.js"; +import { + Contact, + PendingOutbound, + generateTempMessageId, + serializeRatchetSession, +} from "../types.js"; interface UseChatActionsProps { - verbethClient: VerbethClient | null; + verbethClient: VerbethClient | null; addLog: (message: string) => void; updateContact: (contact: Contact) => Promise; addMessage: (message: any) => Promise; @@ -29,6 +51,10 @@ export const useChatActions = ({ setRecipientAddress, }: UseChatActionsProps) => { + /** + * Send a handshake to initiate contact. + * Stores ephemeral secret for ratchet session init when response arrives. + */ const sendHandshake = useCallback( async (recipientAddress: string, message: string) => { if (!verbethClient) { @@ -40,7 +66,6 @@ export const useChatActions = ({ addLog("โœ— Missing recipient address or message"); return; } - setLoading(true); try { @@ -49,11 +74,13 @@ export const useChatActions = ({ message ); + // Store ephemeral secret for ratchet session init when response arrives const newContact: Contact = { address: recipientAddress, ownerAddress: verbethClient.userAddress, status: "handshake_sent", - ephemeralKey: ephemeralKeyPair.secretKey, + // Store ephemeral secret (hex) for later use in initSessionAsInitiator + handshakeEphemeralSecret: hexlify(ephemeralKeyPair.secretKey), lastMessage: message, lastTimestamp: Date.now(), }; @@ -99,7 +126,7 @@ export const useChatActions = ({ } }, [ - verbethClient, + verbethClient, addLog, updateContact, addMessage, @@ -110,6 +137,10 @@ export const useChatActions = ({ ] ); + /** + * Accept a handshake and create ratchet session. + * This is where the responder's ratchet session is initialized. + */ const acceptHandshake = useCallback( async (handshake: any, responseMessage: string) => { if (!verbethClient) { @@ -118,21 +149,46 @@ export const useChatActions = ({ } try { - const { tx, duplexTopics } = await verbethClient.acceptHandshake( + // Accept handshake - now returns ephemeral keys for ratchet + const { + tx, + duplexTopics, + responderEphemeralSecret, + responderEphemeralPublic, + } = await verbethClient.acceptHandshake( handshake.ephemeralPubKey, handshake.identityPubKey, responseMessage ); - // Client auto-derived topics, just use them! + // Determine topics from responder's perspective + const topicOutbound = pickOutboundTopic(false, duplexTopics); // Responder + const topicInbound = pickOutboundTopic(true, duplexTopics); // Responder + + // Initialize ratchet session as responder + const ratchetSession = initSessionAsResponder({ + myAddress: verbethClient.userAddress, + contactAddress: handshake.sender, + myResponderEphemeralSecret: responderEphemeralSecret, + myResponderEphemeralPublic: responderEphemeralPublic, + theirHandshakeEphemeralPubKey: handshake.ephemeralPubKey, + topicOutbound, + topicInbound, + }); + + // Save ratchet session + await dbService.saveRatchetSession(ratchetSession); + + // Update contact with session info const newContact: Contact = { address: handshake.sender, ownerAddress: verbethClient.userAddress, status: "established", identityPubKey: handshake.identityPubKey, signingPubKey: handshake.signingPubKey, - topicOutbound: pickOutboundTopic(false, duplexTopics), // Responder - topicInbound: pickOutboundTopic(true, duplexTopics), // Responder + topicOutbound, + topicInbound, + conversationId: ratchetSession.conversationId, lastMessage: responseMessage, lastTimestamp: Date.now(), }; @@ -143,7 +199,7 @@ export const useChatActions = ({ const acceptanceMessage = { id: generateTempMessageId(), - topic: duplexTopics.topicOut, + topic: topicOutbound, sender: verbethClient.userAddress, recipient: handshake.sender, ciphertext: "", @@ -163,10 +219,7 @@ export const useChatActions = ({ await addMessage(acceptanceMessage); addLog( - `โœ… Handshake accepted from ${handshake.sender.slice( - 0, - 8 - )}...: "${responseMessage}"` + `โœ… Handshake accepted from ${handshake.sender.slice(0, 8)}... - ratchet session created` ); } catch (error) { console.error("Failed to accept handshake:", error); @@ -178,7 +231,7 @@ export const useChatActions = ({ } }, [ - verbethClient, + verbethClient, addLog, updateContact, removePendingHandshake, @@ -187,6 +240,10 @@ export const useChatActions = ({ ] ); + /** + * Send an encrypted message using Double Ratchet. + * Implements two-phase commit with sequential blocking. + */ const sendMessageToContact = useCallback( async (contact: Contact, messageText: string) => { if (!verbethClient) { @@ -194,28 +251,65 @@ export const useChatActions = ({ return; } - if (!contact.identityPubKey) { - addLog("โœ— Contact not established or missing identity key"); + if (!contact.conversationId) { + addLog("โœ— Contact doesn't have a ratchet session"); + return; + } + + // 1. SEQUENTIAL BLOCKING: Check for existing pending outbound + const existingPending = await dbService.getPendingOutboundByConversation( + contact.conversationId + ); + if (existingPending.length > 0) { + addLog("โณ Please wait for previous message to confirm before sending another"); return; } setLoading(true); + const pendingId = generateTempMessageId(); + try { - if (!contact.topicOutbound) { - addLog("โœ— Contact doesn't have outbound topic established"); + // 2. Load ratchet session + const session = await dbService.getRatchetSessionByConversation( + contact.conversationId + ); + if (!session) { + addLog("โœ— No ratchet session for this contact"); + setLoading(false); return; } - await verbethClient.sendMessage( - contact.topicOutbound, - contact.identityPubKey, - messageText + // 3. Encrypt with ratchet (returns new session state, doesn't mutate) + const plaintext = new TextEncoder().encode(messageText); + const { session: nextSession, header, ciphertext, signature } = ratchetEncrypt( + session, + plaintext, + verbethClient.identityKeyPairInstance.signingSecretKey ); - // Create pending message for UI - const pendingMessage = { - id: generateTempMessageId(), - topic: contact.topicOutbound, + // 4. Package binary payload + const payload = packageRatchetPayload(signature, header, ciphertext); + const payloadHex = hexlify(payload); + + // 5. Create pending record (two-phase commit) + const pending: PendingOutbound = { + id: pendingId, + conversationId: session.conversationId, + topic: session.topicOutbound, + payloadHex, + plaintext: messageText, + sessionStateBefore: JSON.stringify(serializeRatchetSession(session)), + sessionStateAfter: JSON.stringify(serializeRatchetSession(nextSession)), + createdAt: Date.now(), + txHash: null, + status: "preparing", + }; + await dbService.savePendingOutbound(pending); + + // 6. Add optimistic UI message + await addMessage({ + id: pendingId, + topic: session.topicOutbound, sender: verbethClient.userAddress, recipient: contact.address, ciphertext: "", @@ -225,15 +319,36 @@ export const useChatActions = ({ direction: "outgoing" as const, decrypted: messageText, read: true, - nonce: 0, - dedupKey: `pending-${generateTempMessageId()}`, + nonce: nextSession.sendingMsgNumber - 1, + dedupKey: `pending-${pendingId}`, type: "text" as const, ownerAddress: verbethClient.userAddress, status: "pending" as const, - }; + }); + + // 7. Send transaction + const timestamp = Math.floor(Date.now() / 1000); + const nonce = nextSession.sendingMsgNumber - 1; + + await dbService.updatePendingOutboundStatus(pendingId, "submitted"); + + // Send the binary payload as bytes + // The executor.sendMessage expects: (payload: Uint8Array | bytes, topic, timestamp, nonce) + const tx = await verbethClient.executorInstance.sendMessage( + payload, // Raw binary payload + session.topicOutbound, // Topic (bytes32 hex) + timestamp, // Unix timestamp + BigInt(nonce) // Convert to bigint + ); + + // Update with txHash for confirmation matching + await dbService.updatePendingOutboundStatus(pendingId, "submitted", tx.hash); - await addMessage(pendingMessage); + addLog( + `Message sent to ${contact.address.slice(0, 8)}...: "${messageText}" (tx: ${tx.hash})` + ); + // Update contact last message const updatedContact: Contact = { ...contact, lastMessage: messageText, @@ -241,11 +356,25 @@ export const useChatActions = ({ }; await updateContact(updatedContact); - addLog( - `Message sent to ${contact.address.slice(0, 8)}...: "${messageText}"` - ); + // Note: Actual session state commit happens in useMessageProcessor + // when we see the on-chain confirmation + } catch (error) { console.error("Failed to send message:", error); + + // Rollback: delete pending record, keep old session state + try { + await dbService.deletePendingOutbound(pendingId); + } catch (cleanupError) { + console.error("Failed to cleanup pending outbound:", cleanupError); + } + + try { + await dbService.updateMessage(pendingId, { status: "failed" }); + } catch (updateError) { + console.error("Failed to mark message as failed:", updateError); + } + addLog( `โœ— Failed to send message: ${ error instanceof Error ? error.message : "Unknown error" @@ -256,7 +385,7 @@ export const useChatActions = ({ } }, [ - verbethClient, + verbethClient, addLog, addMessage, updateContact, @@ -269,4 +398,4 @@ export const useChatActions = ({ acceptHandshake, sendMessageToContact, }; -}; +}; \ No newline at end of file diff --git a/apps/demo/src/hooks/useMessageListener.ts b/apps/demo/src/hooks/useMessageListener.ts index a4a7eed..814a512 100644 --- a/apps/demo/src/hooks/useMessageListener.ts +++ b/apps/demo/src/hooks/useMessageListener.ts @@ -203,10 +203,13 @@ export const useMessageListener = ({ const R = getBytes(responderEphemeralR); for (const contact of pendingContacts) { - if (!contact.ephemeralKey) continue; + if (!contact.handshakeEphemeralSecret) continue; try { - const expectedTag = computeTagFromInitiator(contact.ephemeralKey, R); + const expectedTag = computeTagFromInitiator( + getBytes(contact.handshakeEphemeralSecret), + R + ); if (expectedTag.toLowerCase() === inResponseTo.toLowerCase()) { return contact; } diff --git a/apps/demo/src/hooks/useMessageProcessor.ts b/apps/demo/src/hooks/useMessageProcessor.ts index d9afd52..35c615c 100644 --- a/apps/demo/src/hooks/useMessageProcessor.ts +++ b/apps/demo/src/hooks/useMessageProcessor.ts @@ -1,10 +1,9 @@ // apps/demo/src/hooks/useMessageProcessor.ts import { useState, useEffect, useCallback, useRef } from "react"; -import { AbiCoder } from "ethers"; +import { AbiCoder, getBytes } from "ethers"; import { type IdentityContext, - decryptMessage, parseHandshakePayload, parseBindingMessage, verifyHandshakeIdentity, @@ -15,6 +14,12 @@ import { verifyDerivedDuplexTopics, computeTagFromInitiator, pickOutboundTopic, + // Ratchet imports + initSessionAsInitiator, + ratchetDecrypt, + parseRatchetPayload, + isRatchetPayload, + verifyMessageSignature, } from "@verbeth/sdk"; import { dbService } from "../services/DbService.js"; @@ -213,19 +218,20 @@ export const useMessageProcessor = ({ let identityAddress = cleanSenderAddress; // fallback to event sender if (hasValidIdentityProof && handshakeContent.identityProof?.message) { try { - const parsed = parseBindingMessage(handshakeContent.identityProof.message); + const parsed = parseBindingMessage( + handshakeContent.identityProof.message + ); if (parsed.address) { identityAddress = parsed.address; } - } catch (e) { - } + } catch (e) {} } const pendingHandshake: PendingHandshake = { id: log.transactionHash, ownerAddress: address, - sender: identityAddress, // EOA (identity) - emitterAddress: cleanSenderAddress, // Safe or EOA (event sender) + sender: identityAddress, // EOA (identity) + emitterAddress: cleanSenderAddress, // Safe or EOA (event sender) identityPubKey, signingPubKey, ephemeralPubKey, @@ -307,11 +313,12 @@ export const useMessageProcessor = ({ // This works regardless of whether responder is EOA or Safe const contact = currentContacts.find( (c) => - c.address.toLowerCase() === event.matchedContactAddress?.toLowerCase() && + c.address.toLowerCase() === + event.matchedContactAddress?.toLowerCase() && c.status === "handshake_sent" ); - if (!contact || !contact.ephemeralKey) { + if (!contact || !contact.handshakeEphemeralSecret) { onLog( `โ“ Received handshake response but no matching pending contact found (responder: ${responder.slice( 0, @@ -331,7 +338,7 @@ export const useMessageProcessor = ({ // Pass identityContext for domain & chain bound verification const result = await verifyAndExtractHandshakeResponseKeys( responseEvent, - contact.ephemeralKey, // initiator's ephemeral secret key + getBytes(contact.handshakeEphemeralSecret!), readProvider, identityContext ); @@ -355,8 +362,8 @@ export const useMessageProcessor = ({ } const saltHex = computeTagFromInitiator( - contact.ephemeralKey, // Alice's ephemeral secret (stored when she sent handshake) - hexToUint8Array(responderEphemeralRBytes) // Bob's public R from the response event + getBytes(contact.handshakeEphemeralSecret!), // Alice's ephemeral secret (hex โ†’ Uint8Array) + hexToUint8Array(responderEphemeralRBytes) // Bob's public R from the response event ); const salt = Uint8Array.from(Buffer.from(saltHex.slice(2), "hex")); @@ -377,23 +384,52 @@ export const useMessageProcessor = ({ }); if (!isValidTopics) { onLog( - `โŒ Invalid duplex topics checksum for ${contact.address.slice(0, 8)}...` + `โŒ Invalid duplex topics checksum for ${contact.address.slice( + 0, + 8 + )}...` ); return; } onLog( - `โœ… Handshake response verified from ${contact.address.slice(0, 8)}...` + `โœ… Handshake response verified from ${contact.address.slice( + 0, + 8 + )}...` ); + // Determine topics from initiator's perspective + const topicOutbound = pickOutboundTopic(true, duplexTopics); // Alice is initiator + const topicInbound = pickOutboundTopic(false, duplexTopics); // Bob is responder + + // ===================================================================== + // RATCHET: Initialize session as INITIATOR + // CRITICAL: Use ephemeralPubKey from INSIDE the decrypted payload, + // NOT the on-chain responderEphemeralR (which is only for tag verification). + // This separation provides unlinkability between handshake and conversation. + // ===================================================================== + const ratchetSession = initSessionAsInitiator({ + myAddress: address, + contactAddress: contact.address, + myHandshakeEphemeralSecret: getBytes(contact.handshakeEphemeralSecret!), + theirResponderEphemeralPubKey: ephemeralPubKey, // From decrypted payload! + topicOutbound, + topicInbound, + }); + + // Save ratchet session + await dbService.saveRatchetSession(ratchetSession); + const updatedContact: Contact = { ...contact, status: "established" as ContactStatus, identityPubKey, signingPubKey, - ephemeralKey: undefined, - topicOutbound: pickOutboundTopic(true, duplexTopics), // Alice is initiator - topicInbound: pickOutboundTopic(false, duplexTopics), // Bob is responder + handshakeEphemeralSecret: undefined, // Clear ephemeral secret (no longer needed) + topicOutbound, + topicInbound, + conversationId: ratchetSession.conversationId, lastMessage: note || "Handshake accepted", lastTimestamp: Date.now(), }; @@ -458,14 +494,18 @@ export const useMessageProcessor = ({ const [ciphertextBytes, timestamp, nonce] = decoded; const topic = log.topics[2]; const sender = "0x" + log.topics[1].slice(-40); - const key = `${address.toLowerCase()}:${generateMessageId(log.transactionHash, log)}`; - - const ciphertextJson = new TextDecoder().decode( - hexToUint8Array(ciphertextBytes) - ); + const key = `${address.toLowerCase()}:${generateMessageId( + log.transactionHash, + log + )}`; + + // Raw ciphertext bytes (could be ratchet binary or legacy JSON) + const ciphertextHex = ciphertextBytes as string; + const ciphertextRaw = hexToUint8Array(ciphertextHex); // Use emitterAddress (Safe in fast mode) for outbound detection const emitter = emitterAddress || address; - const isOurMessage = emitter && sender.toLowerCase() === emitter.toLowerCase(); + const isOurMessage = + emitter && sender.toLowerCase() === emitter.toLowerCase(); if (!isOurMessage) { const already = await dbService.getByDedupKey(key); @@ -491,13 +531,58 @@ export const useMessageProcessor = ({ )}..., nonce=${Number(nonce)}` ); + // ===================================================================== + // RATCHET TWO-PHASE COMMIT: Match by txHash (primary method) + // ===================================================================== + const pending = await dbService.getPendingOutboundByTxHash(log.transactionHash); + + if (pending && pending.status === "submitted") { + // Commit the session state (applies sessionStateAfter) + await dbService.commitPendingOutbound(pending.id); + + // Update message status from pending to confirmed + const newId = generateMessageId(log.transactionHash, log); + await dbService.updateMessage(pending.id, { + id: newId, + status: "confirmed", + blockNumber: log.blockNumber, + blockTimestamp: Date.now(), + ciphertext: ciphertextHex, + nonce: Number(nonce), + dedupKey: key, + }); + + await dbService.upsertDedup({ + key, + messageId: newId, + txHash: log.transactionHash, + blockNumber: log.blockNumber, + }); + + setMessages((prev) => + prev.map((m) => + m.id === pending.id + ? { ...m, id: newId, status: "confirmed", blockNumber: log.blockNumber } + : m + ) + ); + + onLog( + `โœ… Message confirmed: "${pending.plaintext.slice(0, 30)}..." (${pending.id.slice(0, 8)} โ†’ ${newId.slice(0, 8)})` + ); + return; + } + + // ===================================================================== + // LEGACY FALLBACK: In-memory FIFO matching (for non-ratchet messages) + // ===================================================================== const q = pendingMessagesRef.current.get(topic) ?? []; - const pendingMessage = q.shift(); // confirm the oldest + const pendingMessage = q.shift(); pendingMessagesRef.current.set(topic, q); if (pendingMessage) { onLog( - `Matched pending by topic. Content preview:: "${pendingMessage.decrypted?.slice( + `Matched pending by topic (legacy). Content preview: "${pendingMessage.decrypted?.slice( 0, 100 )}..."` @@ -509,7 +594,7 @@ export const useMessageProcessor = ({ id: newId, blockNumber: log.blockNumber, blockTimestamp: Date.now(), - ciphertext: ciphertextJson, + ciphertext: ciphertextHex, nonce: Number(nonce), dedupKey: key, status: "confirmed", @@ -540,6 +625,7 @@ export const useMessageProcessor = ({ )}..." (${pendingMessage.id} โ†’ ${newId})` ); } else { + // DB fallback for multi-tab / refresh scenarios const dbFallback = await dbService.findPendingMessage( address, topic, @@ -547,7 +633,6 @@ export const useMessageProcessor = ({ address ); - // for "lastMessage" updates const allContacts = await dbService.getAllContacts(address); const byTopic = allContacts.find((c) => c.topicOutbound === topic); @@ -557,7 +642,7 @@ export const useMessageProcessor = ({ topic, sender: address, recipient: byTopic?.address, - ciphertext: ciphertextJson, + ciphertext: ciphertextHex, timestamp: Number(timestamp) * 1000, blockTimestamp: Date.now(), blockNumber: log.blockNumber, @@ -572,7 +657,6 @@ export const useMessageProcessor = ({ }; if (dbFallback) { - // Replace the pending row in-place (preserves the bubble) await dbService.updateMessage(dbFallback.id, confirmed); await dbService.upsertDedup({ key, @@ -604,44 +688,81 @@ export const useMessageProcessor = ({ return; } - // INCOMING MESSAGE - // Match by topicInbound (not sender address) - works for EOA or Safe senders - const currentContacts = await dbService.getAllContacts(address); - const contact = currentContacts.find( - (c) => - c.topicInbound === topic && - c.status === "established" - ); - - if (!contact || !contact.identityPubKey || !contact.signingPubKey) { +// ===================================================================== + // INCOMING MESSAGE - Use ratchet session for decryption + // ===================================================================== + + // Try to find ratchet session by inbound topic + const session = await dbService.getRatchetSessionByTopic(topic); + + if (!session) { onLog( `โ“ Received message on unknown topic: ${topic.slice(0, 10)}... from ${sender.slice(0, 8)}...` ); return; } - const decryptedMessage = decryptMessage( - ciphertextJson, - identityKeyPair.secretKey, + // Find contact for signing key verification + const contact = await dbService.getContact(session.contactAddress, address); + if (!contact?.signingPubKey) { + onLog(`โœ— No signing key for contact ${session.contactAddress.slice(0, 8)}...`); + return; + } + + // Check if ratchet format + if (!isRatchetPayload(ciphertextRaw)) { + onLog(`โœ— Message not in ratchet format from ${contact.address.slice(0, 8)}...`); + return; + } + + const parsed = parseRatchetPayload(ciphertextRaw); + if (!parsed) { + onLog(`โœ— Failed to parse ratchet payload from ${contact.address.slice(0, 8)}...`); + return; + } + + // ===================================================================== + // AUTH-FIRST: Verify signature BEFORE any ratchet operations (DoS protection) + // ===================================================================== + const sigValid = verifyMessageSignature( + parsed.signature, + parsed.header, + parsed.ciphertext, contact.signingPubKey ); - if (!decryptedMessage) { - onLog(`โœ— Failed to decrypt message from ${contact.address.slice(0, 8)}...`); + if (!sigValid) { + onLog(`โœ— Invalid signature on message from ${contact.address.slice(0, 8)}..., ignoring`); return; } + // ===================================================================== + // DECRYPT with ratchet (signature verified, safe to proceed) + // ===================================================================== + const decryptResult = ratchetDecrypt(session, parsed.header, parsed.ciphertext); + + if (!decryptResult) { + onLog(`โœ— Ratchet decryption failed from ${contact.address.slice(0, 8)}...`); + return; + } + + // Commit new session state immediately (receiving is safe to commit) + await dbService.saveRatchetSession(decryptResult.session); + + // Decode plaintext + const decryptedText = new TextDecoder().decode(decryptResult.plaintext); + const message: Message = { id: generateMessageId(log.transactionHash, log), topic: topic, sender: contact.address, // Use contact address, not on-chain sender recipient: address, - ciphertext: ciphertextJson, + ciphertext: ciphertextHex, timestamp: Number(timestamp) * 1000, blockTimestamp: Date.now(), blockNumber: log.blockNumber, direction: "incoming" as MessageDirection, - decrypted: decryptedMessage, + decrypted: decryptedText, read: false, nonce: Number(nonce), dedupKey: key, @@ -667,13 +788,12 @@ export const useMessageProcessor = ({ const updatedContact: Contact = { ...contact, - lastMessage: decryptedMessage, + lastMessage: decryptedText, lastTimestamp: Date.now(), }; await dbService.saveContact(updatedContact); - // Use contact.address (not sender from event) setContacts((prev) => prev.map((c) => c.address.toLowerCase() === contact.address.toLowerCase() @@ -682,13 +802,13 @@ export const useMessageProcessor = ({ ) ); - onLog(`Message from ${contact.address.slice(0, 8)}...: "${decryptedMessage}"`); + onLog(`๐Ÿ“ฉ Message from ${contact.address.slice(0, 8)}...: "${decryptedText}"`); } } catch (error) { onLog(`โœ— Failed to process message log: ${error}`); } }, - [address, identityKeyPair, onLog] + [address, emitterAddress, identityKeyPair, onLog] ); const processEvents = useCallback( @@ -778,4 +898,4 @@ export const useMessageProcessor = ({ updateContact, processEvents, }; -}; \ No newline at end of file +}; diff --git a/apps/demo/src/hooks/useMessageQueue.ts b/apps/demo/src/hooks/useMessageQueue.ts new file mode 100644 index 0000000..2644cca --- /dev/null +++ b/apps/demo/src/hooks/useMessageQueue.ts @@ -0,0 +1,390 @@ +// src/hooks/useMessageQueue.ts + +/** + * Message Queue Hook for Sequential Processing with Optimistic UI. + * + * Solves the race condition problem by: + * 1. Immediately showing messages in UI (optimistic) + * 2. Queuing messages per conversation + * 3. Processing queue sequentially in background + * 4. Handling failures with retry capability + */ + +import { useCallback, useRef, useEffect } from "react"; +import { hexlify } from "ethers"; +import { + VerbethClient, + ratchetEncrypt, + packageRatchetPayload, + RatchetSession, +} from "@verbeth/sdk"; +import { dbService } from "../services/DbService.js"; +import { + Contact, + Message, + PendingOutbound, + generateTempMessageId, + serializeRatchetSession, +} from "../types.js"; + +// ============================================================================= +// Types +// ============================================================================= + +export type QueuedMessageStatus = + | "queued" // In queue, waiting for previous to complete + | "sending" // Currently being sent + | "pending" // Tx submitted, waiting for confirmation + | "confirmed" // On-chain confirmed + | "failed"; // Failed, can retry + +export interface QueuedMessage { + id: string; + conversationId: string; + contact: Contact; + plaintext: string; + status: QueuedMessageStatus; + error?: string; + txHash?: string; + createdAt: number; + // Pre-computed encryption (computed when message reaches front of queue) + encryptedPayload?: Uint8Array; + sessionStateAfter?: string; +} + +interface ConversationQueue { + messages: QueuedMessage[]; + isProcessing: boolean; +} + +interface UseMessageQueueProps { + verbethClient: VerbethClient | null; + addLog: (message: string) => void; + addMessage: (message: Message) => Promise; + updateMessageStatus: (id: string, status: Message["status"], error?: string) => Promise; + updateContact: (contact: Contact) => Promise; +} + +// ============================================================================= +// Hook +// ============================================================================= + +export const useMessageQueue = ({ + verbethClient, + addLog, + addMessage, + updateMessageStatus, + updateContact, +}: UseMessageQueueProps) => { + // Queue per conversation + const queuesRef = useRef>(new Map()); + + // Track mounted state to prevent updates after unmount + const mountedRef = useRef(true); + + useEffect(() => { + mountedRef.current = true; + return () => { + mountedRef.current = false; + }; + }, []); + + // =========================================================================== + // Queue Processor + // =========================================================================== + + const processQueue = useCallback(async (conversationId: string) => { + if (!verbethClient || !mountedRef.current) return; + + const queue = queuesRef.current.get(conversationId); + if (!queue || queue.isProcessing || queue.messages.length === 0) return; + + // Mark as processing + queue.isProcessing = true; + + while (queue.messages.length > 0 && mountedRef.current) { + const message = queue.messages[0]; + + // Skip already processed messages + if (message.status === "confirmed" || message.status === "pending") { + queue.messages.shift(); + continue; + } + + // Skip failed messages (user must explicitly retry) + if (message.status === "failed") { + queue.messages.shift(); + continue; + } + + try { + message.status = "sending"; + + // 1. Load current session state + const session = await dbService.getRatchetSessionByConversation(conversationId); + if (!session) { + throw new Error("No ratchet session found"); + } + + // 2. Encrypt with ratchet + const plaintext = new TextEncoder().encode(message.plaintext); + const { session: nextSession, header, ciphertext, signature } = ratchetEncrypt( + session, + plaintext, + verbethClient.identityKeyPairInstance.signingSecretKey + ); + + // 3. Package binary payload + const payload = packageRatchetPayload(signature, header, ciphertext); + const payloadHex = hexlify(payload); + + // 4. Create pending record (two-phase commit) + const pending: PendingOutbound = { + id: message.id, + conversationId, + topic: session.topicOutbound, + payloadHex, + plaintext: message.plaintext, + sessionStateBefore: JSON.stringify(serializeRatchetSession(session)), + sessionStateAfter: JSON.stringify(serializeRatchetSession(nextSession)), + createdAt: message.createdAt, + txHash: null, + status: "preparing", + }; + await dbService.savePendingOutbound(pending); + + // 5. Send transaction + const timestamp = Math.floor(Date.now() / 1000); + const nonce = nextSession.sendingMsgNumber - 1; + + await dbService.updatePendingOutboundStatus(message.id, "submitted"); + + const tx = await verbethClient.executorInstance.sendMessage( + payload, + session.topicOutbound, + timestamp, + BigInt(nonce) + ); + + // 6. Update with txHash + message.txHash = tx.hash; + message.status = "pending"; + await dbService.updatePendingOutboundStatus(message.id, "submitted", tx.hash); + + addLog(`๐Ÿ“ค Message sent: "${message.plaintext.slice(0, 30)}..." (tx: ${tx.hash.slice(0, 10)}...)`); + + // Update contact + const updatedContact: Contact = { + ...message.contact, + lastMessage: message.plaintext, + lastTimestamp: Date.now(), + }; + await updateContact(updatedContact); + + // Remove from queue (confirmation will be handled by useMessageProcessor) + queue.messages.shift(); + + } catch (error) { + const errorMessage = error instanceof Error ? error.message : "Unknown error"; + + // Mark as failed + message.status = "failed"; + message.error = errorMessage; + + // Rollback: delete pending record if it was created + try { + await dbService.deletePendingOutbound(message.id); + } catch { + // Ignore cleanup errors + } + + // Update UI message status + await updateMessageStatus(message.id, "failed", errorMessage); + + addLog(`โœ— Failed to send: "${message.plaintext.slice(0, 20)}..." - ${errorMessage}`); + + // Remove failed message from queue (user can retry via UI) + queue.messages.shift(); + + // Don't break - continue processing remaining messages + // (they might succeed if the failure was transient) + } + } + + queue.isProcessing = false; + }, [verbethClient, addLog, updateContact, updateMessageStatus]); + + // =========================================================================== + // Public API + // =========================================================================== + + /** + * Queue a message for sending. + * Shows optimistically in UI immediately, processes sequentially. + */ + const queueMessage = useCallback(async ( + contact: Contact, + messageText: string + ): Promise => { + if (!verbethClient) { + addLog("โœ— Client not initialized"); + return null; + } + + if (!contact.conversationId) { + addLog("โœ— Contact doesn't have a ratchet session"); + return null; + } + + const messageId = generateTempMessageId(); + const conversationId = contact.conversationId; + + // 1. Create queued message + const queuedMessage: QueuedMessage = { + id: messageId, + conversationId, + contact, + plaintext: messageText, + status: "queued", + createdAt: Date.now(), + }; + + // 2. Get or create queue for this conversation + let queue = queuesRef.current.get(conversationId); + if (!queue) { + queue = { messages: [], isProcessing: false }; + queuesRef.current.set(conversationId, queue); + } + + // 3. Add to queue + queue.messages.push(queuedMessage); + + // 4. Show optimistic UI message immediately + const optimisticMessage: Message = { + id: messageId, + topic: contact.topicOutbound || "", + sender: verbethClient.userAddress, + recipient: contact.address, + ciphertext: "", + timestamp: Date.now(), + blockTimestamp: Date.now(), + blockNumber: 0, + direction: "outgoing", + decrypted: messageText, + read: true, + nonce: 0, + dedupKey: `pending-${messageId}`, + type: "text", + ownerAddress: verbethClient.userAddress, + status: "pending", + }; + + await addMessage(optimisticMessage); + + addLog(`๐Ÿ“ Message queued: "${messageText.slice(0, 30)}..."`); + + // 5. Trigger queue processing (non-blocking) + // Use setTimeout to ensure this runs after current execution + setTimeout(() => processQueue(conversationId), 0); + + return messageId; + }, [verbethClient, addLog, addMessage, processQueue]); + + /** + * Retry a failed message. + */ + const retryMessage = useCallback(async (messageId: string): Promise => { + // Find the message in any queue + for (const [conversationId, queue] of queuesRef.current.entries()) { + const messageIndex = queue.messages.findIndex( + m => m.id === messageId && m.status === "failed" + ); + + if (messageIndex !== -1) { + const message = queue.messages[messageIndex]; + + // Reset status and re-add to queue + message.status = "queued"; + message.error = undefined; + message.createdAt = Date.now(); + + // Move to end of queue + queue.messages.splice(messageIndex, 1); + queue.messages.push(message); + + // Update UI + await updateMessageStatus(messageId, "pending"); + + addLog(`๐Ÿ”„ Retrying message: "${message.plaintext.slice(0, 30)}..."`); + + // Trigger processing + setTimeout(() => processQueue(conversationId), 0); + + return true; + } + } + + // Message not in queue - might need to reload from DB + // For now, return false + addLog(`โœ— Could not find message ${messageId} to retry`); + return false; + }, [addLog, updateMessageStatus, processQueue]); + + /** + * Cancel a queued (not yet sent) message. + */ + const cancelMessage = useCallback(async (messageId: string): Promise => { + for (const [, queue] of queuesRef.current.entries()) { + const messageIndex = queue.messages.findIndex( + m => m.id === messageId && (m.status === "queued" || m.status === "failed") + ); + + if (messageIndex !== -1) { + const message = queue.messages[messageIndex]; + queue.messages.splice(messageIndex, 1); + + // Remove from DB/UI + await dbService.deleteMessage(messageId); + + addLog(`๐Ÿ—‘๏ธ Cancelled message: "${message.plaintext.slice(0, 30)}..."`); + return true; + } + } + + return false; + }, [addLog]); + + /** + * Get queue status for a conversation. + */ + const getQueueStatus = useCallback((conversationId: string): { + queueLength: number; + isProcessing: boolean; + pendingMessages: QueuedMessage[]; + } => { + const queue = queuesRef.current.get(conversationId); + if (!queue) { + return { queueLength: 0, isProcessing: false, pendingMessages: [] }; + } + return { + queueLength: queue.messages.length, + isProcessing: queue.isProcessing, + pendingMessages: [...queue.messages], + }; + }, []); + + /** + * Clear all queues (e.g., on logout). + */ + const clearAllQueues = useCallback(() => { + queuesRef.current.clear(); + }, []); + + return { + queueMessage, + retryMessage, + cancelMessage, + getQueueStatus, + clearAllQueues, + }; +}; \ No newline at end of file diff --git a/apps/demo/src/services/DbService.ts b/apps/demo/src/services/DbService.ts index 8836907..13641dc 100644 --- a/apps/demo/src/services/DbService.ts +++ b/apps/demo/src/services/DbService.ts @@ -4,7 +4,15 @@ import type { Contact, Message, PendingHandshake, + StoredRatchetSession, + PendingOutbound, } from "../types.js"; +import { + serializeRatchetSession, + deserializeRatchetSession, +} from "../types.js"; +import type { RatchetSession, SessionStatus } from "@verbeth/sdk"; +import { pruneExpiredSkippedKeys } from "@verbeth/sdk"; export class DbService { private readonly db: VerbEthDatabase; @@ -398,6 +406,212 @@ export class DbService { return this.db.pendingHandshakes.delete(id); } + /* ========================= RATCHET SESSIONS ========================= */ + + /** + * Save or update a ratchet session. + * Automatically serializes Uint8Arrays to hex strings. + */ + async saveRatchetSession(session: RatchetSession): Promise { + const stored = serializeRatchetSession(session); + console.log(`๐Ÿ’พ Saving ratchet session: ${stored.conversationId.slice(0, 10)}...`); + await this.db.ratchetSessions.put(stored); + } + + /** + * Get ratchet session by conversation ID. + */ + async getRatchetSessionByConversation(conversationId: string): Promise { + const stored = await this.db.ratchetSessions.get(conversationId); + if (!stored) return null; + + const session = deserializeRatchetSession(stored); + const pruned = pruneExpiredSkippedKeys(session); + + if (pruned.skippedKeys.length !== session.skippedKeys.length) { + await this.saveRatchetSession(pruned); + } + + return pruned; +} + + /** + * Get ratchet session by inbound topic (for incoming message processing). + */ + async getRatchetSessionByTopic(topicInbound: string): Promise { + const stored = await this.db.ratchetSessions + .where("topicInbound") + .equals(topicInbound.toLowerCase()) + .first(); + if (!stored) return null; + const session = deserializeRatchetSession(stored); + + // Prune expired skipped keys (24h TTL) + const pruned = pruneExpiredSkippedKeys(session); + + // If keys were pruned, persist the cleaned session + if (pruned.skippedKeys.length !== session.skippedKeys.length) { + await this.saveRatchetSession(pruned); + } + + return pruned; +} + + /** + * Update ratchet session status. + */ + async updateRatchetSessionStatus( + conversationId: string, + status: SessionStatus + ): Promise { + await this.db.ratchetSessions.update(conversationId, { + status, + updatedAt: Date.now(), + }); + console.log(`๐Ÿ“ Updated session ${conversationId.slice(0, 10)}... status to: ${status}`); + } + + /** + * Delete ratchet session. + */ + async deleteRatchetSession(conversationId: string): Promise { + await this.db.ratchetSessions.delete(conversationId); + console.log(`๐Ÿ—‘๏ธ Deleted ratchet session: ${conversationId.slice(0, 10)}...`); + } + + /* ========================= PENDING OUTBOUND ========================= */ + + /** + * Save a pending outbound message (for two-phase commit). + */ + async savePendingOutbound(pending: PendingOutbound): Promise { + console.log(`๐Ÿ“ค Saving pending outbound: ${pending.id.slice(0, 10)}...`); + await this.db.pendingOutbound.put(pending); + } + + /** + * Get pending outbound by ID. + */ + async getPendingOutbound(id: string): Promise { + return await this.db.pendingOutbound.get(id) ?? null; + } + + /** + * Get pending outbound by transaction hash (for confirmation matching). + * This is the PRIMARY lookup method for confirmations. + */ + async getPendingOutboundByTxHash(txHash: string): Promise { + return await this.db.pendingOutbound + .where("txHash") + .equals(txHash.toLowerCase()) + .first() ?? null; + } + + /** + * Get all pending outbound for a conversation (for sequential blocking check). + */ + async getPendingOutboundByConversation(conversationId: string): Promise { + return await this.db.pendingOutbound + .where("conversationId") + .equals(conversationId) + .filter((p) => p.status === "preparing" || p.status === "submitted") + .toArray(); + } + + /** + * Update pending outbound status and optionally set txHash. + */ + async updatePendingOutboundStatus( + id: string, + status: PendingOutbound["status"], + txHash?: string + ): Promise { + const updates: Partial = { status }; + if (txHash) { + updates.txHash = txHash.toLowerCase(); + } + await this.db.pendingOutbound.update(id, updates); + console.log(`๐Ÿ“ Updated pending outbound ${id.slice(0, 10)}... status to: ${status}`); + } + + /** + * Commit pending outbound: apply sessionStateAfter and delete pending record. + * Called when on-chain confirmation is received. + */ + async commitPendingOutbound(id: string): Promise { + const pending = await this.db.pendingOutbound.get(id); + if (!pending) { + console.warn(`โš ๏ธ Pending outbound ${id} not found for commit`); + return; + } + + // Parse and save the committed session state + const sessionAfter: StoredRatchetSession = JSON.parse(pending.sessionStateAfter); + await this.db.ratchetSessions.put(sessionAfter); + + // Delete the pending record + await this.db.pendingOutbound.delete(id); + + console.log(`โœ… Committed pending outbound ${id.slice(0, 10)}... - session state updated`); + } + + /** + * Delete pending outbound (on failure - no session state change). + */ + async deletePendingOutbound(id: string): Promise { + await this.db.pendingOutbound.delete(id); + console.log(`๐Ÿ—‘๏ธ Deleted pending outbound: ${id.slice(0, 10)}...`); + } + + /** + * Clean up stale pending outbound records (older than maxAge). + */ + async cleanupStalePendingOutbound(maxAgeMs: number = 24 * 60 * 60 * 1000): Promise { + const cutoff = Date.now() - maxAgeMs; + const stale = await this.db.pendingOutbound + .where("createdAt") + .below(cutoff) + .toArray(); + + for (const p of stale) { + await this.db.pendingOutbound.delete(p.id); + } + + if (stale.length > 0) { + console.log(`๐Ÿงน Cleaned up ${stale.length} stale pending outbound records`); + } + + return stale.length; + } + + /** + * Clear all ratchet data for a user (for reset/debug). + */ + async clearRatchetData(myAddress: string): Promise { + const normalizedAddress = this.normalizeAddress(myAddress); + + await this.db.transaction( + "rw", + [this.db.ratchetSessions, this.db.pendingOutbound], + async () => { + const sessions = await this.db.ratchetSessions + .where("myAddress") + .equals(normalizedAddress) + .toArray(); + + for (const s of sessions) { + await this.db.ratchetSessions.delete(s.conversationId); + await this.db.pendingOutbound + .where("conversationId") + .equals(s.conversationId) + .delete(); + } + } + ); + + console.log(`๐Ÿงน Cleared all ratchet data for ${normalizedAddress.slice(0, 8)}...`); + } + /* -------------------------------- SETTINGS ------------------------------ */ setSetting(name: string, value: any) { return this.db.settings.put({ name, value }); @@ -446,6 +660,8 @@ export class DbService { this.db.messages, this.db.pendingHandshakes, this.db.settings, + this.db.ratchetSessions, + this.db.pendingOutbound, ], async () => { await this.db.identity.clear(); @@ -453,6 +669,8 @@ export class DbService { await this.db.messages.clear(); await this.db.pendingHandshakes.clear(); await this.db.settings.clear(); + await this.db.ratchetSessions.clear(); + await this.db.pendingOutbound.clear(); } ); console.log("All database data cleared"); @@ -469,6 +687,8 @@ export class DbService { this.db.messages, this.db.pendingHandshakes, this.db.settings, + this.db.ratchetSessions, + this.db.pendingOutbound, ], async () => { await this.db.identity.delete(normalizedAddr); @@ -487,6 +707,19 @@ export class DbService { .equals(normalizedAddr) .delete(); + //Delete ratchet data + const sessions = await this.db.ratchetSessions + .where("myAddress") + .equals(normalizedAddr) + .toArray(); + for (const s of sessions) { + await this.db.ratchetSessions.delete(s.conversationId); + await this.db.pendingOutbound + .where("conversationId") + .equals(s.conversationId) + .delete(); + } + const staleSettings = await this.db.settings .where("name") .startsWith(`initialScanComplete_${normalizedAddr}`) @@ -511,11 +744,13 @@ export class DbService { messages: await this.db.messages.toArray(), pendingHandshakes: await this.db.pendingHandshakes.toArray(), settings: await this.db.settings.toArray(), + ratchetSessions: await this.db.ratchetSessions.toArray(), + pendingOutbound: await this.db.pendingOutbound.toArray(), exportedAt: Date.now(), } as const; console.log( - `Exported ${payload.identity.length} identities, ${payload.contacts.length} contacts, ${payload.messages.length} messages` + `Exported ${payload.identity.length} identities, ${payload.contacts.length} contacts, ${payload.messages.length} messages, ${payload.ratchetSessions.length} ratchet sessions` ); return JSON.stringify(payload); } @@ -532,6 +767,8 @@ export class DbService { this.db.messages, this.db.pendingHandshakes, this.db.settings, + this.db.ratchetSessions, + this.db.pendingOutbound, ], async () => { if (data.identity) await this.db.identity.bulkPut(data.identity); @@ -540,6 +777,10 @@ export class DbService { if (data.pendingHandshakes) await this.db.pendingHandshakes.bulkPut(data.pendingHandshakes); if (data.settings) await this.db.settings.bulkPut(data.settings); + if (data.ratchetSessions) + await this.db.ratchetSessions.bulkPut(data.ratchetSessions); + if (data.pendingOutbound) + await this.db.pendingOutbound.bulkPut(data.pendingOutbound); } ); console.log("โœ… Database import completed"); diff --git a/apps/demo/src/services/schema.ts b/apps/demo/src/services/schema.ts index 0bceb41..33b1a9c 100644 --- a/apps/demo/src/services/schema.ts +++ b/apps/demo/src/services/schema.ts @@ -1,3 +1,5 @@ +// src/services/schema.ts + import { Dexie, Table } from "dexie"; import type { StoredIdentity, @@ -5,6 +7,8 @@ import type { Message, PendingHandshake, AppSettings, + StoredRatchetSession, + PendingOutbound, } from "../types.js"; export class VerbEthDatabase extends Dexie { @@ -13,8 +17,11 @@ export class VerbEthDatabase extends Dexie { messages!: Table; pendingHandshakes!: Table; settings!: Table; - dedup!: Dexie.Table<{ key: string; messageId: string; txHash: string; blockNumber: number }, string>; - + dedup!: Table<{ key: string; messageId: string; txHash: string; blockNumber: number }, string>; + + // Ratchet tables + ratchetSessions!: Table; + pendingOutbound!: Table; constructor() { super("VerbEthDB"); @@ -22,13 +29,22 @@ export class VerbEthDatabase extends Dexie { this.version(1).stores({ identity: "address", contacts: - "[address+ownerAddress], ownerAddress, lastTimestamp, status, topicOutbound, topicInbound, emitterAddress", + "[address+ownerAddress], ownerAddress, lastTimestamp, status, topicOutbound, topicInbound, emitterAddress, conversationId", messages: "id, ownerAddress, sender, recipient, topic, nonce, timestamp, blockTimestamp, read, status, [ownerAddress+sender+status], [ownerAddress+sender+topic+nonce+status]", dedup: "key, messageId, txHash, blockNumber", pendingHandshakes: "id, ownerAddress, sender, timestamp, verified, emitterAddress", settings: "name", + + // Ratchet session storage + // Primary key: conversationId + // Indexes: topicInbound (for incoming message lookup), topicOutbound, status + ratchetSessions: "conversationId, topicInbound, topicOutbound, status, myAddress, contactAddress", + + // Pending outbound for two-phase commit + // Primary key: id + // Indexes: conversationId (for sequential blocking), txHash (for confirmation matching) + pendingOutbound: "id, conversationId, txHash, status, createdAt", }); - } -} +} \ No newline at end of file diff --git a/apps/demo/src/types.ts b/apps/demo/src/types.ts index d39b096..8c7eb27 100644 --- a/apps/demo/src/types.ts +++ b/apps/demo/src/types.ts @@ -1,5 +1,6 @@ -import type { IdentityKeyPair, IdentityProof } from '@verbeth/sdk'; -import { keccak256, toUtf8Bytes } from 'ethers'; +import type { IdentityKeyPair, IdentityProof, RatchetSession as SDKRatchetSession, SessionStatus, SkippedKey } from '@verbeth/sdk'; +import { keccak256, toUtf8Bytes, hexlify, getBytes } from 'ethers'; +export type { SessionStatus } from '@verbeth/sdk'; /* ------------------------------- CONSTANTS -------------------------------- */ export const LOGCHAIN_SINGLETON_ADDR = @@ -40,8 +41,6 @@ export interface Contact { identityPubKey?: Uint8Array; /** Contact's Ed25519 public key for signature verification */ signingPubKey?: Uint8Array; - /** Contact's ephemeral public key from handshake */ - ephemeralKey?: Uint8Array; /** Topic for outbound messages (owner โ†’ contact) */ topicOutbound?: string; /** Topic for inbound messages (contact โ†’ owner) */ @@ -55,6 +54,13 @@ export interface Contact { /** Unread message count */ unreadCount?: number; note?: string; + + /** Conversation ID for ratchet session lookup */ + conversationId?: string; + /** Previous conversation ID (after session reset) */ + previousConversationId?: string; + /** Initiator's ephemeral secret (stored until handshake response received) */ + handshakeEphemeralSecret?: string; // hex } @@ -116,6 +122,53 @@ export interface StoredIdentity { emitterAddress?: string; // EOA for classic, Safe for fast/custom } +// ** +// * Stored ratchet session in IndexedDB. +// * Extends SDK RatchetSession with serialization-friendly format. +// */ +export interface StoredRatchetSession { + conversationId: string; + topicOutbound: string; + topicInbound: string; + myAddress: string; + contactAddress: string; + rootKey: string; + dhMySecretKey: string; + dhMyPublicKey: string; + dhTheirPublicKey: string; + sendingChainKey: string | null; + sendingMsgNumber: number; + receivingChainKey: string | null; + receivingMsgNumber: number; + previousChainLength: number; + skippedKeys: StoredSkippedKey[]; + createdAt: number; + updatedAt: number; + epoch: number; + status: SessionStatus; +} + +export interface StoredSkippedKey { + dhPubKeyHex: string; + msgNumber: number; + messageKey: string; + createdAt: number; +} + +export interface PendingOutbound { + id: string; + conversationId: string; + topic: string; + payloadHex: string; + plaintext: string; + sessionStateBefore: string; + sessionStateAfter: string; + createdAt: number; + txHash: string | null; + status: 'preparing' | 'submitted' | 'confirmed' | 'failed'; +} + + export interface AppSettings { name: string; value: any; @@ -177,4 +230,80 @@ export interface MessageProcessorResult { processEvents: (events: ProcessedEvent[]) => Promise; } -export const generateTempMessageId = () => `temp-${Date.now()}-${Math.random()}`; \ No newline at end of file +export const generateTempMessageId = () => `temp-${Date.now()}-${Math.random()}`; + +// ============================================================================= +// SERIALIZATION HELPERS +// ============================================================================= + +/** + * Convert SDK RatchetSession to storable format. + */ +export function serializeRatchetSession(session: SDKRatchetSession): StoredRatchetSession { + return { + conversationId: session.conversationId, + topicOutbound: session.topicOutbound.toLowerCase() as `0x${string}`, + topicInbound: session.topicInbound.toLowerCase() as `0x${string}`, + myAddress: session.myAddress, + contactAddress: session.contactAddress, + + rootKey: hexlify(session.rootKey), + dhMySecretKey: hexlify(session.dhMySecretKey), + dhMyPublicKey: hexlify(session.dhMyPublicKey), + dhTheirPublicKey: hexlify(session.dhTheirPublicKey), + + sendingChainKey: session.sendingChainKey ? hexlify(session.sendingChainKey) : null, + sendingMsgNumber: session.sendingMsgNumber, + receivingChainKey: session.receivingChainKey ? hexlify(session.receivingChainKey) : null, + receivingMsgNumber: session.receivingMsgNumber, + + previousChainLength: session.previousChainLength, + skippedKeys: session.skippedKeys.map((sk: any) => ({ + dhPubKeyHex: sk.dhPubKeyHex, + msgNumber: sk.msgNumber, + messageKey: hexlify(sk.messageKey), + createdAt: sk.createdAt, + })), + + createdAt: session.createdAt, + updatedAt: session.updatedAt, + epoch: session.epoch, + status: session.status, + }; +} + +/** + * Convert stored format back to SDK RatchetSession. + */ +export function deserializeRatchetSession(stored: StoredRatchetSession): SDKRatchetSession { + return { + conversationId: stored.conversationId, + topicOutbound: stored.topicOutbound as `0x${string}`, + topicInbound: stored.topicInbound as `0x${string}`, + myAddress: stored.myAddress, + contactAddress: stored.contactAddress, + + rootKey: getBytes(stored.rootKey), + dhMySecretKey: getBytes(stored.dhMySecretKey), + dhMyPublicKey: getBytes(stored.dhMyPublicKey), + dhTheirPublicKey: getBytes(stored.dhTheirPublicKey), + + sendingChainKey: stored.sendingChainKey ? getBytes(stored.sendingChainKey) : null, + sendingMsgNumber: stored.sendingMsgNumber, + receivingChainKey: stored.receivingChainKey ? getBytes(stored.receivingChainKey) : null, + receivingMsgNumber: stored.receivingMsgNumber, + + previousChainLength: stored.previousChainLength, + skippedKeys: stored.skippedKeys.map((sk) => ({ + dhPubKeyHex: sk.dhPubKeyHex, + msgNumber: sk.msgNumber, + messageKey: getBytes(sk.messageKey), + createdAt: sk.createdAt, + })), + + createdAt: stored.createdAt, + updatedAt: stored.updatedAt, + epoch: stored.epoch, + status: stored.status, + }; +} \ No newline at end of file diff --git a/apps/docs/double-ratchet.md b/apps/docs/double-ratchet.md new file mode 100644 index 0000000..aacd12b --- /dev/null +++ b/apps/docs/double-ratchet.md @@ -0,0 +1,566 @@ +# Double Ratchet Flow: Alice โ†” Bob + +## Overview + +``` +โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” +โ”‚ PROTOCOL PHASES โ”‚ +โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค +โ”‚ PHASE 1: Handshake (on-chain) โ†’ Establish identity + ephemeral keys โ”‚ +โ”‚ PHASE 2: Session Init (local) โ†’ Create RatchetSession from ephemerals โ”‚ +โ”‚ PHASE 3: Messaging (on-chain) โ†’ Encrypt/decrypt with ratchet โ”‚ +โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ +``` + +--- + +## Phase 1: Handshake (Existing Flow) + +``` + ALICE (Initiator) BOB (Responder) + โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• + โ”‚ โ”‚ + โ”‚ 1. Generate ephemeral keypair โ”‚ + โ”‚ eA = (eA.secret, eA.public) โ”‚ + โ”‚ โ”‚ + โ”‚ 2. Create Handshake tx: โ”‚ + โ”‚ โ€ข recipientHash โ”‚ + โ”‚ โ€ข pubKeys (identity X25519 + Ed25519) โ”‚ + โ”‚ โ€ข ephemeralPubKey = eA.public โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–บ โ”‚ + โ”‚ โ€ข plaintextPayload + identityProof โ”‚ + โ”‚ โ”‚ + โ”‚ 3. Store eA.secret locally โ”‚ + โ”‚ (needed to derive session later) โ”‚ + โ”‚ โ”‚ + โ”‚ 4. Verify handshake + โ”‚ (signature, proof) + โ”‚ โ”‚ + โ”‚ 5. Generate ephemeral + โ”‚ eB = (eB.secret, eB.public) + โ”‚ โ”‚ + โ”‚ 6. Create HandshakeResponse: + โ”‚ โ€ข inResponseTo (tag) + โ”‚ โ—„โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ€ข responderEphemeralR = eB.public + โ”‚ โ€ข encrypted payload + โ”‚ โ”‚ + โ”‚ 7. โš ๏ธ STORE eB.secret + โ”‚ (becomes dhMySecretKey!) + โ”‚ โ”‚ + 8. Verify response โ”‚ + (decrypt, verify proof) โ”‚ + โ”‚ โ”‚ + โ”‚ โ”‚ + โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• + โ”‚ HANDSHAKE COMPLETE โ”‚ + โ”‚ Both have: eA.public, eB.public โ”‚ + โ”‚ Alice has: eA.secret โ”‚ + โ”‚ Bob has: eB.secret โ”‚ + โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• +``` + +### On-Chain Data After Handshake + +``` +โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” +โ”‚ Handshake Event (from Alice's emitter) โ”‚ +โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค +โ”‚ โ€ข sender: Alice's Safe/EOA โ”‚ +โ”‚ โ€ข pubKeys: Alice's identity keys (X25519 + Ed25519) โ”‚ +โ”‚ โ€ข ephemeralPubKey: eA.public โ—„โ”€โ”€ Used for initial DH โ”‚ +โ”‚ โ€ข plaintextPayload: message + identity proof โ”‚ +โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ + +โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” +โ”‚ HandshakeResponse Event (from Bob's emitter) โ”‚ +โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค +โ”‚ โ€ข responder: Bob's Safe/EOA โ”‚ +โ”‚ โ€ข responderEphemeralR: eB.public โ—„โ”€โ”€ Bob's first DH key โ”‚ +โ”‚ โ€ข inResponseTo: tag (links to Alice's handshake) โ”‚ +โ”‚ โ€ข ciphertext: encrypted response โ”‚ +โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ +``` + +--- + +## Phase 2 (local): Session Initialization + +### Initial Shared Secret (Ephemeral-Only!) + +``` +โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” +โ”‚ CRITICAL: NO IDENTITY KEYS IN DH โ”‚ +โ”‚ โ”‚ +โ”‚ sharedSecret = DH(eA.secret, eB.public) // Alice computes โ”‚ +โ”‚ = DH(eB.secret, eA.public) // Bob computes (same result) โ”‚ +โ”‚ โ”‚ +โ”‚ WHY: Compromise of identity keys NEVER decrypts past messages โ”‚ +โ”‚ (not even message #0) โ”‚ +โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ +``` + +### Bob's Session Init (Responder - happens first) + +``` + BOB (initSessionAsResponder) + โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• + + INPUT: + โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” + โ”‚ myResponderEphemeralSecret: eB.secretโ”‚ + โ”‚ myResponderEphemeralPublic: eB.publicโ”‚ + โ”‚ theirHandshakeEphemeralPubKey: eA.publicโ”‚ + โ”‚ topicOutbound, topicInbound โ”‚ + โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ + + DERIVATION: + + sharedSecret = DH(eB.secret, eA.public) + โ”‚ + โ–ผ + โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” + โ”‚ KDF_RK(zeros, sharedSecret) โ”‚ + โ”‚ โ†’ rootKeyโ‚€ โ”‚ + โ”‚ โ†’ sendingChainKeyโ‚€ โ”‚ + โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ + + OUTPUT SESSION: + โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” + โ”‚ rootKey: rootKeyโ‚€ โ”‚ + โ”‚ dhMySecretKey: eB.secret โ—„โ”€โ”€ REUSEโ”‚ + โ”‚ dhMyPublicKey: eB.public โ”‚ + โ”‚ dhTheirPublicKey: eA.public โ”‚ + โ”‚ sendingChainKey: sendingChainKeyโ‚€ โ”‚ + โ”‚ sendingMsgNumber: 0 โ”‚ + โ”‚ receivingChainKey: null โ—„โ”€โ”€ Not yetโ”‚ + โ”‚ receivingMsgNumber: 0 โ”‚ + โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ + + Bob can SEND immediately, but cannot RECEIVE + until Alice sends (with her new DH key) +``` + +### Alice's Session Init (Initiator - happens after receiving response) + +``` + ALICE (initSessionAsInitiator) + โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• + + INPUT: + โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” + โ”‚ myHandshakeEphemeralSecret: eA.secretโ”‚ + โ”‚ theirResponderEphemeralPubKey: eB.publicโ”‚ + โ”‚ topicOutbound, topicInbound โ”‚ + โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ + + DERIVATION: + + 1. Same initial secret as Bob: + sharedSecret = DH(eA.secret, eB.public) + โ”‚ + โ–ผ + KDF_RK(zeros, sharedSecret) โ†’ rootKeyโ‚€, bobsSendingChain + + 2. Generate NEW DH keypair for Alice: + dh1 = generateDHKeyPair() โ†’ (dh1.secret, dh1.public) + + 3. Perform sending ratchet step: + dhSend = DH(dh1.secret, eB.public) + โ”‚ + โ–ผ + KDF_RK(rootKeyโ‚€, dhSend) โ†’ rootKeyโ‚, aliceSendingChain + + OUTPUT SESSION: + โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” + โ”‚ rootKey: rootKeyโ‚ โ”‚ + โ”‚ dhMySecretKey: dh1.secret โ—„โ”€โ”€ NEW โ”‚ + โ”‚ dhMyPublicKey: dh1.public โ”‚ + โ”‚ dhTheirPublicKey: eB.public โ”‚ + โ”‚ sendingChainKey: aliceSendingChain โ”‚ + โ”‚ sendingMsgNumber: 0 โ”‚ + โ”‚ receivingChainKey: bobsSendingChain โ”‚โ—„โ”€โ”€ Can receive Bob's msgs! + โ”‚ receivingMsgNumber: 0 โ”‚ + โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ + + Alice can SEND and RECEIVE immediately +``` + +### Session State After Init + +``` + โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” + โ”‚ ALICE SESSION โ”‚ โ”‚ BOB SESSION โ”‚ + โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค + โ”‚ dhMyPub: dh1.public โ”‚ โ”‚ dhMyPub: eB.public โ”‚ + โ”‚ dhTheirPub: eB.public โ”‚ โ”‚ dhTheirPub: eA.public โ”‚ + โ”‚ โ”‚ โ”‚ โ”‚ + โ”‚ sendingChain: โœ“ โ”‚ โ”‚ sendingChain: โœ“ โ”‚ + โ”‚ receivingChain: โœ“ โ”‚ โ”‚ receivingChain: null โ”‚ + โ”‚ โ”‚ โ”‚ โ”‚ + โ”‚ Can send: YES โ”‚ โ”‚ Can send: YES โ”‚ + โ”‚ Can receive: YES โ”‚ โ”‚ Can receive: NO* โ”‚ + โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ + + * Bob's receivingChain is established when Alice sends her first message + (which includes dh1.public in the header) +``` + +--- + +## Phase 3: Message Exchange + +### Message Format (Binary) + +``` +โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” +โ”‚ Offset โ”‚ Size โ”‚ Field โ”‚ +โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค +โ”‚ 0 โ”‚ 1 โ”‚ Version (0x01) โ”‚ +โ”‚ 1 โ”‚ 64 โ”‚ Ed25519 signature (over header + ciphertext) โ”‚ +โ”‚ 65 โ”‚ 32 โ”‚ DH ratchet public key (sender's current) โ”‚ +โ”‚ 97 โ”‚ 4 โ”‚ pn (previous chain length) โ”‚ +โ”‚ 101 โ”‚ 4 โ”‚ n (message number in current chain) โ”‚ +โ”‚ 105 โ”‚ var โ”‚ nonce (24) + secretbox ciphertext โ”‚ +โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ +``` + +### Scenario 1: Alice Sends First Message + +``` + ALICE BOB + โ•โ•โ•โ•โ• โ•โ•โ• + โ”‚ โ”‚ + โ”‚ ratchetEncrypt(session, "Hello Bob!") โ”‚ + โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ + โ”‚ โ”‚ 1. KDF_CK(sendingChainKey) โ”‚ โ”‚ + โ”‚ โ”‚ โ†’ newChainKey, messageKey โ”‚ โ”‚ + โ”‚ โ”‚ โ”‚ โ”‚ + โ”‚ โ”‚ 2. Header: โ”‚ โ”‚ + โ”‚ โ”‚ dh = dh1.public โ”‚ โ”‚ + โ”‚ โ”‚ pn = 0 โ”‚ โ”‚ + โ”‚ โ”‚ n = 0 โ”‚ โ”‚ + โ”‚ โ”‚ โ”‚ โ”‚ + โ”‚ โ”‚ 3. Encrypt with messageKey โ”‚ โ”‚ + โ”‚ โ”‚ 4. Sign(header || ciphertext) โ”‚ โ”‚ + โ”‚ โ”‚ 5. session.sendingMsgNumber = 1 โ”‚ โ”‚ + โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ + โ”‚ โ”‚ + โ”‚ โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• ON-CHAIN TX โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ–บ โ”‚ + โ”‚ Message event on Alice's topicOutbound โ”‚ + โ”‚ โ”‚ + โ”‚ verifySignature() + โ”‚ โœ“ Valid โ”‚ + โ”‚ โ”‚ + โ”‚ ratchetDecrypt() + โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” + โ”‚ โ”‚ 1. header.dh โ‰  dhTheirPub? โ”‚ + โ”‚ โ”‚ YES! (dh1.public โ‰  eA.public) โ”‚ + โ”‚ โ”‚ โ”‚ + โ”‚ โ”‚ 2. DH Ratchet Step: โ”‚ + โ”‚ โ”‚ dhRecv = DH(eB.secret, dh1.pub) โ”‚ + โ”‚ โ”‚ KDF_RK โ†’ rootKey', recvChain โ”‚ + โ”‚ โ”‚ โ”‚ + โ”‚ โ”‚ Generate new DH: โ”‚ + โ”‚ โ”‚ dh2 = generateDHKeyPair() โ”‚ + โ”‚ โ”‚ โ”‚ + โ”‚ โ”‚ dhSend = DH(dh2.secret, dh1.pub)โ”‚ + โ”‚ โ”‚ KDF_RK โ†’ rootKey'', sendChain โ”‚ + โ”‚ โ”‚ โ”‚ + โ”‚ โ”‚ 3. KDF_CK(recvChain) โ†’ messageKey โ”‚ + โ”‚ โ”‚ 4. Decrypt โ†’ "Hello Bob!" โ”‚ + โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ + โ”‚ โ”‚ +``` + +### Session State After Alice's First Message + +``` + โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” + โ”‚ ALICE SESSION โ”‚ โ”‚ BOB SESSION โ”‚ + โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค + โ”‚ dhMyPub: dh1.public โ”‚ โ”‚ dhMyPub: dh2.public โ—„NEW โ”‚ + โ”‚ dhTheirPub: eB.public โ”‚ โ”‚ dhTheirPub: dh1.public โ”‚ + โ”‚ โ”‚ โ”‚ โ”‚ + โ”‚ sendingMsgNumber: 1 โ”‚ โ”‚ sendingMsgNumber: 0 โ”‚ + โ”‚ receivingMsgNumber: 0 โ”‚ โ”‚ receivingMsgNumber: 1 โ”‚ + โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ +``` + +### Scenario 2: Bob Replies + +``` + ALICE BOB + โ•โ•โ•โ•โ• โ•โ•โ• + โ”‚ โ”‚ + โ”‚ ratchetEncrypt("Hi Alice!") + โ”‚ Header: โ”‚ + โ”‚ dh = dh2.public + โ”‚ pn = 0 โ”‚ + โ”‚ n = 0 โ”‚ + โ”‚ โ”‚ + โ”‚ โ—„โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• ON-CHAIN TX โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• โ”‚ + โ”‚ โ”‚ + โ”‚ verifySignature() โœ“ โ”‚ + โ”‚ โ”‚ + โ”‚ ratchetDecrypt() โ”‚ + โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ + โ”‚ โ”‚ header.dh โ‰  dhTheirPub? โ”‚ โ”‚ + โ”‚ โ”‚ YES! (dh2.public โ‰  eB.public) โ”‚ โ”‚ + โ”‚ โ”‚ โ”‚ โ”‚ + โ”‚ โ”‚ DH Ratchet Step: โ”‚ โ”‚ + โ”‚ โ”‚ Generate dh3 โ”‚ โ”‚ + โ”‚ โ”‚ Update chains โ”‚ โ”‚ + โ”‚ โ”‚ โ”‚ โ”‚ + โ”‚ โ”‚ Decrypt โ†’ "Hi Alice!" โ”‚ โ”‚ + โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ + โ”‚ โ”‚ +``` + +### Scenario 3: Multiple Messages Same Direction (No DH Ratchet) + +``` + BOB sends 3 messages without Alice replying: + + Message 1: header.dh = dh2.public, n = 0 + Message 2: header.dh = dh2.public, n = 1 โ—„โ”€โ”€ Same DH key! + Message 3: header.dh = dh2.public, n = 2 + + Alice receives in order: + - No DH ratchet needed (same header.dh) + - Just advance receivingChainKey for each message +``` + +--- + +## Edge Cases + +### Edge Case 1: Out-of-Order Messages (Skip Keys) + +``` + BOB sends: Msg0, Msg1, Msg2 + + ALICE receives in order: Msg2, Msg0, Msg1 + + โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” + โ”‚ RECEIVE Msg2 (n=2, but Alice expects n=0) โ”‚ + โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค + โ”‚ 1. header.n (2) > receivingMsgNumber (0) โ”‚ + โ”‚ 2. Skip messages 0 and 1: โ”‚ + โ”‚ - Derive messageKeyโ‚€, store in skippedKeys โ”‚ + โ”‚ - Derive messageKeyโ‚, store in skippedKeys โ”‚ + โ”‚ 3. Derive messageKeyโ‚‚, decrypt Msg2 โ”‚ + โ”‚ 4. receivingMsgNumber = 3 โ”‚ + โ”‚ โ”‚ + โ”‚ skippedKeys = [ โ”‚ + โ”‚ { dhPubKeyHex: "0x...", msgNumber: 0, messageKey: keyโ‚€ }, โ”‚ + โ”‚ { dhPubKeyHex: "0x...", msgNumber: 1, messageKey: keyโ‚ }, โ”‚ + โ”‚ ] โ”‚ + โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ + + โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” + โ”‚ RECEIVE Msg0 (n=0, using skip key) โ”‚ + โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค + โ”‚ 1. Look up in skippedKeys: found! โ”‚ + โ”‚ 2. Decrypt with stored messageKeyโ‚€ โ”‚ + โ”‚ 3. Remove keyโ‚€ from skippedKeys โ”‚ + โ”‚ 4. Session state unchanged (no chain advance) โ”‚ + โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ + + โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” + โ”‚ RECEIVE Msg1 (n=1, using skip key) โ”‚ + โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค + โ”‚ Same process, use stored messageKeyโ‚ โ”‚ + โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ +``` + +### Edge Case 2: DH Ratchet + Skip Keys Combined + +``` + Scenario: + - Bob sends Msg0, Msg1 with dh2.public + - Alice replies (triggers Bob's DH ratchet to dh3) + - Bob sends Msg0', Msg1' with dh3.public + - Alice receives: Msg1' (new epoch), Msg0 (old epoch) + + โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” + โ”‚ RECEIVE Msg1' (new dh3.public, n=1) โ”‚ + โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค + โ”‚ 1. header.dh (dh3) โ‰  dhTheirPub (dh2) โ†’ DH ratchet! โ”‚ + โ”‚ 2. But first: skip remaining msgs from OLD epoch (dh2) โ”‚ + โ”‚ header.pn = 2 means Bob sent 2 msgs on old chain โ”‚ + โ”‚ Alice received 0, so skip Msg0, Msg1 from old epoch โ”‚ + โ”‚ Store their keys tagged with dh2.public โ”‚ + โ”‚ 3. Perform DH ratchet (new receivingChain for dh3) โ”‚ + โ”‚ 4. Skip Msg0' in new epoch (n=1, expect n=0) โ”‚ + โ”‚ Store key tagged with dh3.public โ”‚ + โ”‚ 5. Decrypt Msg1' โ”‚ + โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ + + โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” + โ”‚ RECEIVE Msg0 (old dh2.public, n=0) โ”‚ + โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค + โ”‚ 1. Look up skippedKeys by (dh2.public, n=0) โ”‚ + โ”‚ 2. Found! Decrypt with stored key โ”‚ + โ”‚ 3. Remove from skippedKeys โ”‚ + โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ +``` + +### Edge Case 3: Invalid Signature (DoS Attack) + +``` + ATTACKER posts garbage message to Alice's topicInbound + + โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” + โ”‚ ALICE PROCESSING โ”‚ + โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค + โ”‚ 1. parseRatchetPayload() โ†’ parsed โ”‚ + โ”‚ 2. verifyMessageSignature(sig, header, ct, bob.signingPubKey) โ”‚ + โ”‚ โ†’ FALSE โœ— โ”‚ + โ”‚ 3. REJECT immediately โ”‚ + โ”‚ - No ratchet operations performed โ”‚ + โ”‚ - No state changes โ”‚ + โ”‚ - O(1) cost (just signature verify) โ”‚ + โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ + + PROTECTION: Even if attacker sets header.n = 999999, we never + reach the skip key derivation loop because signature fails first. +``` + +### Edge Case 4: Transaction Failure (Two-Phase Commit) + +``` + ALICE tries to send message + + โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” + โ”‚ SEND FLOW WITH TWO-PHASE COMMIT โ”‚ + โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค + โ”‚ 1. Load session (sendingMsgNumber = 5) โ”‚ + โ”‚ โ”‚ + โ”‚ 2. ratchetEncrypt() returns: โ”‚ + โ”‚ - NEW session object (sendingMsgNumber = 6) โ”‚ + โ”‚ - Original session UNCHANGED โ”‚ + โ”‚ โ”‚ + โ”‚ 3. Create PendingOutbound: โ”‚ + โ”‚ { sessionBefore: original, sessionAfter: new } โ”‚ + โ”‚ โ”‚ + โ”‚ 4. Send transaction... โ”‚ + โ”‚ โ”‚ + โ”‚ IF TX SUCCEEDS: IF TX FAILS: โ”‚ + โ”‚ โ”œโ”€ See event on-chain โ”œโ”€ Delete PendingOutbound โ”‚ + โ”‚ โ”œโ”€ Commit sessionAfter to DB โ”œโ”€ Session state = original โ”‚ + โ”‚ โ””โ”€ Delete PendingOutbound โ””โ”€ User can retry โ”‚ + โ”‚ sendingMsgNumber = 6 sendingMsgNumber = 5 โ”‚ + โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ +``` + +### Edge Case 5: Sequential Blocking (Prevent State Corruption) + +``` + ALICE tries to send Msg A, then immediately Msg B + + โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” + โ”‚ PROBLEM WITHOUT BLOCKING โ”‚ + โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค + โ”‚ 1. Send Msg A: state 0 โ†’ 1, PendingA created โ”‚ + โ”‚ 2. Send Msg B: state 1 โ†’ 2, PendingB created โ”‚ + โ”‚ 3. TX A FAILS โ”‚ + โ”‚ 4. TX B SUCCEEDS (Bob receives it!) โ”‚ + โ”‚ โ”‚ + โ”‚ If we rollback to state 0: โ”‚ + โ”‚ - We've lost the keys for Msg B โ”‚ + โ”‚ - Bob has Msg B but we can't continue โ”‚ + โ”‚ - PERMANENT DESYNC โ”‚ + โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ + + โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” + โ”‚ SOLUTION: SEQUENTIAL BLOCKING โ”‚ + โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค + โ”‚ 1. Send Msg A: PendingA created โ”‚ + โ”‚ 2. Try to send Msg B: CHECK getPendingByConversation() โ”‚ + โ”‚ โ†’ PendingA exists! โ”‚ + โ”‚ โ†’ BLOCK: "Wait for previous message to confirm" โ”‚ + โ”‚ 3. TX A confirms (or fails) โ”‚ + โ”‚ 4. NOW Alice can send Msg B โ”‚ + โ”‚ โ”‚ + โ”‚ INVARIANT: At most ONE pending outbound per conversation โ”‚ + โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ +``` + +### Edge Case 6: Session Lost (Reset Required) + +``` + ALICE clears browser storage or switches device + + โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” + โ”‚ DETECTION โ”‚ + โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค + โ”‚ 1. Alice loads app, identity re-derived from wallet signature โ”‚ + โ”‚ 2. Check for RatchetSession with Bob: NOT FOUND โ”‚ + โ”‚ 3. Contact exists but no session โ†’ SESSION LOST โ”‚ + โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ + + โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” + โ”‚ RECOVERY: SESSION RESET PROTOCOL โ”‚ + โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค + โ”‚ 1. Alice sends NEW handshake to Bob โ”‚ + โ”‚ (marked as reset, not first contact) โ”‚ + โ”‚ โ”‚ + โ”‚ 2. Bob sees: "Alice requests new session" โ”‚ + โ”‚ - Warning: "Messages since [date] may be unreadable by Alice" โ”‚ + โ”‚ โ”‚ + โ”‚ 3. Bob accepts โ†’ NEW session with NEW topics โ”‚ + โ”‚ - Old session marked 'inactive_superseded' โ”‚ + โ”‚ - Old messages still viewable (if cached) โ”‚ + โ”‚ โ”‚ + โ”‚ 4. Both continue with fresh ratchet state โ”‚ + โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ + + โš ๏ธ TRADEOFF: Messages sent by Bob after Alice lost state and before + Alice reset are PERMANENTLY LOST from Alice's perspective. + This is inherent to forward secrecy. +``` + +--- + +## State Machine Summary + +``` + โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” + โ”‚ NO SESSION โ”‚ + โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ + โ”‚ Handshake accepted + โ–ผ + โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” + โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–บโ”‚ ACTIVE โ”‚โ—„โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” + โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ + โ”‚ โ”‚ โ”‚ + โ”‚ Send/Receive โ”‚ State lost โ”‚ + โ”‚ (normal ops) โ”‚ โ”‚ + โ”‚ โ–ผ โ”‚ + โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ + โ”‚ โ”‚ INACTIVE_RESET โ”‚ โ”‚ + โ”‚ โ”‚ (waiting peer) โ”‚ โ”‚ + โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ + โ”‚ โ”‚ Peer accepts โ”‚ + โ”‚ โ”‚ reset โ”‚ + โ”‚ โ–ผ โ”‚ + โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ + โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”‚ NEW SESSION โ”‚โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ + โ”‚ (new topics) โ”‚ + โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ + + Old session โ†’ INACTIVE_SUPERSEDED โ†’ FROZEN (archival) +``` + +--- + +## Key Invariants + +| Invariant | Description | +|-----------|-------------| +| **Auth First** | Always `verifyMessageSignature()` before `ratchetDecrypt()` | +| **Immutable Ops** | `ratchetEncrypt/Decrypt` return NEW session, never mutate | +| **Sequential Send** | Max 1 `PendingOutbound` per conversation | +| **Topics = Identity** | Session keyed by `conversationId` (from topics), not addresses | +| **Ephemeral Init** | Initial secret from ephemeral-only DH, no identity keys | +| **Skip Key TTL** | Skipped keys pruned after 24h | +| **Skip Key Cap** | Max 1000 stored skipped keys per session | \ No newline at end of file diff --git a/packages/sdk/src/client/VerbethClient.ts b/packages/sdk/src/client/VerbethClient.ts index 9373833..e3161eb 100644 --- a/packages/sdk/src/client/VerbethClient.ts +++ b/packages/sdk/src/client/VerbethClient.ts @@ -1,11 +1,22 @@ // packages/sdk/src/client/VerbethClient.ts +/** + * High-level client for Verbeth E2EE messaging. + * + * Handles handshake operations. Message encryption is done via + * the ratchet module at the application layer. + * + * NOTE: sendMessage() has been REMOVED. Use ratchet functions directly: + * - ratchetEncrypt() for encryption + * - packageRatchetPayload() for binary encoding + * - executor.sendMessage() for on-chain submission + */ + import nacl from 'tweetnacl'; -import { initiateHandshake, respondToHandshake, sendEncryptedMessage } from '../send.js'; +import { initiateHandshake, respondToHandshake } from '../send.js'; import { deriveDuplexTopics } from '../crypto.js'; -import type { VerbethClientConfig, HandshakeResult, HandshakeResponseResult } from './types.js'; import type { IExecutor } from '../executor.js'; -import type { IdentityKeyPair, IdentityProof } from '../types.js'; +import type { IdentityKeyPair, IdentityProof, DuplexTopics } from '../types.js'; import type { Signer } from 'ethers'; import * as crypto from '../crypto.js'; @@ -13,12 +24,52 @@ import * as payload from '../payload.js'; import * as verify from '../verify.js'; import * as utils from '../utils.js'; import * as identity from '../identity.js'; +import * as ratchet from '../ratchet/index.js'; + +// ============================================================================= +// Types +// ============================================================================= + +export interface VerbethClientConfig { + executor: IExecutor; + identityKeyPair: IdentityKeyPair; + identityProof: IdentityProof; + signer: Signer; + address: string; +} + +export interface HandshakeResult { + tx: any; + /** Ephemeral keypair - MUST persist secretKey for ratchet session init */ + ephemeralKeyPair: nacl.BoxKeyPair; +} + +export interface HandshakeResponseResult { + tx: any; + /** Derived duplex topics for the conversation */ + duplexTopics: DuplexTopics; + /** Tag used for inResponseTo field */ + tag: `0x${string}`; + /** Salt for topic derivation (= getBytes(tag)) */ + salt: Uint8Array; + /** + * Responder's DH ratchet secret - MUST persist as dhMySecretKey in ratchet. + * NOTE: This is DIFFERENT from the on-chain responderEphemeralR (which is the tag key). + */ + responderEphemeralSecret: Uint8Array; + /** + * Responder's DH ratchet public key (inside encrypted payload, NOT on-chain). + * NOTE: This is DIFFERENT from responderEphemeralR for unlinkability. + */ + responderEphemeralPublic: Uint8Array; +} + +// ============================================================================= +// Client +// ============================================================================= /** - * High-level client for Verbeth E2EE messaging - * - * VerbethClient provides a simplified API for common operations while - * maintaining access to all low-level functions. + * High-level client for Verbeth E2EE messaging. * * @example * ```typescript @@ -35,13 +86,15 @@ import * as identity from '../identity.js'; * '0xBob...', * 'Hello Bob!' * ); + * // MUST persist ephemeralKeyPair.secretKey for ratchet session init * - * // Send a message - * await client.sendMessage( - * contact.topicOutbound, - * contact.identityPubKey, - * 'Hello again!' + * // Accept a handshake + * const { duplexTopics, responderEphemeralSecret } = await client.acceptHandshake( + * handshake.ephemeralPubKey, + * handshake.identityPubKey, + * 'Hello Alice!' * ); + * // Use responderEphemeralSecret with initSessionAsResponder() * ``` */ export class VerbethClient { @@ -51,11 +104,6 @@ export class VerbethClient { private readonly signer: Signer; private readonly address: string; - /** - * creates a new VerbethClient instance - * - * @param config - Client configuration with session-level parameters - */ constructor(config: VerbethClientConfig) { this.executor = config.executor; this.identityKeyPair = config.identityKeyPair; @@ -65,41 +113,24 @@ export class VerbethClient { } /** - * Initiates a handshake with a recipient + * Initiates a handshake with a recipient. * - * generates an ephemeral keypair for this handshake. - * the ephemeralKeyPair must be stored to decrypt the response later. + * Generates an ephemeral keypair for this handshake. + * The ephemeralKeyPair.secretKey MUST be stored for ratchet session initialization + * when the response arrives. * * @param recipientAddress - Blockchain address of the recipient * @param message - Plaintext message to include in the handshake - * @returns Transaction response and the ephemeral keypair (must be stored!) - * - * @example - * ```typescript - * const { tx, ephemeralKeyPair } = await client.sendHandshake( - * '0xBob...', - * 'Hi Bob!' - * ); - * - * // Store ephemeralKeyPair.secretKey to decrypt Bob's response - * await storage.saveContact({ - * address: '0xBob...', - * ephemeralKey: ephemeralKeyPair.secretKey, - * // ... - * }); - * ``` + * @returns Transaction response and the ephemeral keypair */ async sendHandshake( recipientAddress: string, message: string ): Promise { - const ephemeralKeyPair = nacl.box.keyPair(); - - const tx = await initiateHandshake({ + const { tx, ephemeralKeyPair } = await initiateHandshake({ executor: this.executor, recipientAddress, identityKeyPair: this.identityKeyPair, - ephemeralPubKey: ephemeralKeyPair.publicKey, plaintextPayload: message, identityProof: this.identityProof, signer: this.signer, @@ -109,29 +140,33 @@ export class VerbethClient { } /** - * Accepts a handshake from an initiator + * Accepts a handshake from an initiator. * - * derives duplex topics for the conversation and returns them. + * Derives duplex topics for the conversation and returns ephemeral keys + * needed for ratchet session initialization. * - * @param initiatorEphemeralPubKey - initiator's ephemeral public key from handshake event - * @param initiatorIdentityPubKey - initiator's long-term X25519 identity key - * @param note - response message to send back - * @returns transaction, derived duplex topics, and response tag + * @param initiatorEphemeralPubKey - Initiator's ephemeral public key from handshake event + * @param initiatorIdentityPubKey - Initiator's long-term X25519 identity key + * @param note - Response message to send back + * @returns Transaction, derived duplex topics, and ephemeral keys for ratchet * * @example * ```typescript - * const { tx, duplexTopics } = await client.acceptHandshake( + * const result = await client.acceptHandshake( * handshake.ephemeralPubKey, * handshake.identityPubKey, * 'Hello Alice!' * ); * - * // Store the topics for future messaging - * await storage.saveContact({ - * address: handshake.sender, - * topicOutbound: duplexTopics.topicIn, // Responder writes to topicIn - * topicInbound: duplexTopics.topicOut, // Responder reads from topicOut - * // ... + * // Initialize ratchet session as responder + * const session = initSessionAsResponder({ + * myAddress: myAddress, + * contactAddress: handshake.sender, + * myResponderEphemeralSecret: result.responderEphemeralSecret, + * myResponderEphemeralPublic: result.responderEphemeralPublic, + * theirHandshakeEphemeralPubKey: handshake.ephemeralPubKey, + * topicOutbound: pickOutboundTopic(false, result.duplexTopics), + * topicInbound: pickOutboundTopic(true, result.duplexTopics), * }); * ``` */ @@ -140,9 +175,15 @@ export class VerbethClient { initiatorIdentityPubKey: Uint8Array, note: string ): Promise { - const { tx, salt, tag } = await respondToHandshake({ + const { + tx, + salt, + tag, + responderEphemeralSecret, + responderEphemeralPublic, + } = await respondToHandshake({ executor: this.executor, - initiatorPubKey: initiatorEphemeralPubKey, + initiatorEphemeralPubKey, responderIdentityKeyPair: this.identityKeyPair, note, identityProof: this.identityProof, @@ -156,83 +197,67 @@ export class VerbethClient { salt ); - return { tx, duplexTopics, tag }; - } - - /** - * Sends an encrypted message to a contact - * - * handles timestamp, signing keys, and sender address. - * - * @param topicOutbound - The outbound topic for this conversation - * @param recipientPubKey - Recipient's X25519 public key (from handshake) - * @param message - Plaintext message to encrypt and send - * @returns Transaction response - * - * @example - * ```typescript - * await client.sendMessage( - * contact.topicOutbound, - * contact.identityPubKey, - * 'Hello again!' - * ); - * ``` - */ - async sendMessage( - topicOutbound: string, - recipientPubKey: Uint8Array, - message: string - ): Promise { - const signingKeyPair = { - publicKey: this.identityKeyPair.signingPublicKey, - secretKey: this.identityKeyPair.signingSecretKey, + return { + tx, + duplexTopics, + tag, + salt, + responderEphemeralSecret, + responderEphemeralPublic, }; - - const timestamp = Math.floor(Date.now() / 1000); - - return sendEncryptedMessage({ - executor: this.executor, - topic: topicOutbound, - message, - recipientPubKey, - senderAddress: this.address, - senderSignKeyPair: signingKeyPair, - timestamp, - }); } - // ========== low-level API ========== + // =========================================================================== + // Low-level API access + // =========================================================================== + /** Crypto utilities */ get crypto() { return crypto; } + /** Payload encoding utilities */ get payload() { return payload; } + /** Verification utilities */ get verify() { return verify; } + /** General utilities */ get utils() { return utils; } + /** Identity derivation utilities */ get identity() { return identity; } + /** Double ratchet module */ + get ratchet() { + return ratchet; + } + + /** Executor instance for direct access */ get executorInstance(): IExecutor { return this.executor; } - + /** Identity keypair for direct access */ get identityKeyPairInstance(): IdentityKeyPair { return this.identityKeyPair; } + /** User's address */ get userAddress(): string { return this.address; } + + /** Identity proof for direct access */ + get identityProofInstance(): IdentityProof { + return this.identityProof; + } } \ No newline at end of file diff --git a/packages/sdk/src/client/types.ts b/packages/sdk/src/client/types.ts index 6c40758..fe4687d 100644 --- a/packages/sdk/src/client/types.ts +++ b/packages/sdk/src/client/types.ts @@ -30,5 +30,8 @@ export interface HandshakeResult { export interface HandshakeResponseResult { tx: any; duplexTopics: DuplexTopics; - tag: string; + tag: `0x${string}`; + salt: Uint8Array; + responderEphemeralSecret: Uint8Array; + responderEphemeralPublic: Uint8Array; } \ No newline at end of file diff --git a/packages/sdk/src/crypto.ts b/packages/sdk/src/crypto.ts index 2888a54..f1f5a7d 100644 --- a/packages/sdk/src/crypto.ts +++ b/packages/sdk/src/crypto.ts @@ -1,5 +1,17 @@ // packages/sdk/src/crypto.ts +/** + * Cryptographic utilities for Verbeth. + * + * This module handles: + * - Handshake encryption/decryption (NaCl box - one-time exchange) + * - Topic derivation (HKDF + Keccak) + * - Tag computation for handshake responses + * + * NOTE: Post-handshake message encryption uses the ratchet module. + * See `ratchet/encrypt.ts` and `ratchet/decrypt.ts` for Double Ratchet. + */ + import nacl from 'tweetnacl'; import { keccak256, toUtf8Bytes, dataSlice } from 'ethers'; import { sha256 } from '@noble/hashes/sha2'; @@ -15,8 +27,13 @@ import { } from './payload.js'; import { IdentityProof } from './types.js'; +// ============================================================================= +// Handshake Encryption (NaCl Box) +// ============================================================================= + /** - * Encrypts a structured payload (JSON-serializable objects) + * Encrypts a structured payload (JSON-serializable objects) using NaCl box. + * Used for handshake responses where ratchet is not yet established. */ export function encryptStructuredPayload( payload: T, @@ -42,7 +59,8 @@ export function encryptStructuredPayload( } /** - * Decrypts a structured payload with converter function + * Decrypts a structured payload with converter function. + * Used for handshake responses where ratchet is not yet established. */ export function decryptStructuredPayload( payloadJson: string, @@ -64,7 +82,16 @@ export function decryptStructuredPayload( return decodeStructuredContent(box, converter); } -// wrappers for encrypting and decrypting messages +// ============================================================================= +// Legacy Message Encryption (for backward compatibility / log decryption) +// ============================================================================= + +/** + * Encrypts a message using NaCl box. + * + * @deprecated For new messages, use ratchetEncrypt() from the ratchet module. + * This function is kept for backward compatibility with legacy logs. + */ export function encryptMessage( message: string, recipientPublicKey: Uint8Array, @@ -84,6 +111,12 @@ export function encryptMessage( ); } +/** + * Decrypts a message using NaCl box. + * + * @deprecated For new messages, use ratchetDecrypt() from the ratchet module. + * This function is kept for backward compatibility with legacy logs. + */ export function decryptMessage( payloadJson: string, recipientSecretKey: Uint8Array, @@ -98,17 +131,21 @@ export function decryptMessage( return result ? result.content : null; } +// ============================================================================= +// Handshake Response Decryption +// ============================================================================= + /** - * Decrypts handshake response and extracts individual keys from unified format + * Decrypts handshake response and extracts individual keys from unified format. */ export function decryptHandshakeResponse( payloadJson: string, initiatorEphemeralSecretKey: Uint8Array ): HandshakeResponseContent | null { - return decryptStructuredPayload( + return decryptStructuredPayload( payloadJson, initiatorEphemeralSecretKey, - (obj) => { + (obj: any): HandshakeResponseContent => { if (!obj.identityProof) { throw new Error("Invalid handshake response: missing identityProof"); } @@ -116,14 +153,19 @@ export function decryptHandshakeResponse( unifiedPubKeys: Uint8Array.from(Buffer.from(obj.unifiedPubKeys, 'base64')), ephemeralPubKey: Uint8Array.from(Buffer.from(obj.ephemeralPubKey, 'base64')), note: obj.note, - identityProof: obj.identityProof + identityProof: obj.identityProof, + topicInfo: obj.topicInfo ? { + out: obj.topicInfo.out, + in: obj.topicInfo.in, + chk: obj.topicInfo.chk + } : undefined }; } ); } /** - * helper to decrypt handshake response and extract individual keys + * Helper to decrypt handshake response and extract individual keys. */ export function decryptAndExtractHandshakeKeys( payloadJson: string, @@ -150,6 +192,9 @@ export function decryptAndExtractHandshakeKeys( }; } +// ============================================================================= +// Tag Computation (Handshake Response Linkage) +// ============================================================================= /** * HKDF(sha256) on shared secret, info="verbeth:hsr", then Keccak-256 -> bytes32 (0x...) @@ -181,6 +226,9 @@ export function computeTagFromInitiator( return finalizeHsrTag(shared); } +// ============================================================================= +// Topic Derivation +// ============================================================================= /** * Derives a bytes32 topic from the shared secret via HKDF(SHA256) + Keccak-256. @@ -196,7 +244,9 @@ function deriveTopic( return keccak256(okm) as `0x${string}`; } - +/** + * Derives long-term shared secret from identity keys. + */ export function deriveLongTermShared( myIdentitySecretKey: Uint8Array, theirIdentityPublicKey: Uint8Array @@ -225,6 +275,9 @@ export function deriveDuplexTopics( return { topicOut, topicIn, checksum }; } +/** + * Verifies duplex topics checksum. + */ export function verifyDuplexTopicsChecksum( topicOut: `0x${string}`, topicIn: `0x${string}`, @@ -236,4 +289,4 @@ export function verifyDuplexTopicsChecksum( Buffer.from(topicIn.slice(2), 'hex'), ])); return dataSlice(chkFull as `0x${string}`, 8) === checksum; -} +} \ No newline at end of file diff --git a/packages/sdk/src/index.ts b/packages/sdk/src/index.ts index 4cf134e..8bdcac9 100644 --- a/packages/sdk/src/index.ts +++ b/packages/sdk/src/index.ts @@ -55,4 +55,6 @@ export type { VerbethClientConfig, HandshakeResult, HandshakeResponseResult -} from './client/index.js'; \ No newline at end of file +} from './client/index.js'; + +export * from './ratchet/index.js'; \ No newline at end of file diff --git a/packages/sdk/src/ratchet/auth.ts b/packages/sdk/src/ratchet/auth.ts new file mode 100644 index 0000000..a28eab2 --- /dev/null +++ b/packages/sdk/src/ratchet/auth.ts @@ -0,0 +1,121 @@ +// packages/sdk/src/ratchet/auth.ts + +/** + * Message Authentication for Ratchet Protocol. + * + * Ed25519 signatures are mandatory on all ratchet messages. + * This provides DoS protection: unauthenticated messages are rejected in O(1) + * signature verification, preventing attackers from triggering expensive + * ratchet operations. + * + * CRITICAL: Always verify signature BEFORE any ratchet operations. + */ + +import nacl from 'tweetnacl'; +import { MessageHeader } from './types.js'; + +// ============================================================================= +// Signature Verification +// ============================================================================= + +/** + * Verify message signature BEFORE any ratchet operations. + * This is the primary DoS protection layer. + * + * The signature covers (header || ciphertext), where header is the 40-byte + * binary encoding of (dh, pn, n). + * + * @param signature - Ed25519 signature (64 bytes) + * @param header - Message header + * @param ciphertext - Encrypted payload + * @param signingPublicKey - Contact's Ed25519 public key (32 bytes) + * @returns true if signature is valid + */ +export function verifyMessageSignature( + signature: Uint8Array, + header: MessageHeader, + ciphertext: Uint8Array, + signingPublicKey: Uint8Array +): boolean { + if (signature.length !== 64) { + return false; + } + if (signingPublicKey.length !== 32) { + return false; + } + + // Reconstruct signed data: header || ciphertext + const headerBytes = encodeHeaderForSigning(header); + const dataToVerify = new Uint8Array(headerBytes.length + ciphertext.length); + dataToVerify.set(headerBytes, 0); + dataToVerify.set(ciphertext, headerBytes.length); + + try { + return nacl.sign.detached.verify(dataToVerify, signature, signingPublicKey); + } catch { + return false; + } +} + +/** + * Encode header as 40 bytes for signature verification. + * Must match the format used during signing in encrypt.ts. + */ +function encodeHeaderForSigning(header: MessageHeader): Uint8Array { + const buf = new Uint8Array(40); + buf.set(header.dh, 0); + new DataView(buf.buffer).setUint32(32, header.pn, false); // big-endian + new DataView(buf.buffer).setUint32(36, header.n, false); + return buf; +} + +// ============================================================================= +// Signature Creation (for completeness - also in encrypt.ts) +// ============================================================================= + +/** + * Create Ed25519 signature for a message. + * + * @param header - Message header + * @param ciphertext - Encrypted payload + * @param signingSecretKey - Ed25519 secret key (64 bytes) + * @returns Ed25519 signature (64 bytes) + */ +export function signMessage( + header: MessageHeader, + ciphertext: Uint8Array, + signingSecretKey: Uint8Array +): Uint8Array { + const headerBytes = encodeHeaderForSigning(header); + const dataToSign = new Uint8Array(headerBytes.length + ciphertext.length); + dataToSign.set(headerBytes, 0); + dataToSign.set(ciphertext, headerBytes.length); + + return nacl.sign.detached(dataToSign, signingSecretKey); +} + +// ============================================================================= +// Validation Helpers +// ============================================================================= + +/** + * Validate that a parsed payload has a well-formed signature and header. + * Does NOT verify the signature - just checks lengths and format. + * + * @param signature - Signature bytes + * @param header - Parsed header + * @returns true if format is valid + */ +export function isValidPayloadFormat( + signature: Uint8Array, + header: MessageHeader +): boolean { + return ( + signature.length === 64 && + header.dh.length === 32 && + header.pn >= 0 && + header.n >= 0 && + Number.isInteger(header.pn) && + Number.isInteger(header.n) + ); +} \ No newline at end of file diff --git a/packages/sdk/src/ratchet/codec.ts b/packages/sdk/src/ratchet/codec.ts new file mode 100644 index 0000000..88fb82a --- /dev/null +++ b/packages/sdk/src/ratchet/codec.ts @@ -0,0 +1,192 @@ +// packages/sdk/src/ratchet/codec.ts + +/** + * Binary Codec for Ratchet Messages. + * + * โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” + * โ”‚ Offset โ”‚ Size โ”‚ Field โ”‚ + * โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค + * โ”‚ 0 โ”‚ 1 โ”‚ Version (0x01) โ”‚ + * โ”‚ 1 โ”‚ 64 โ”‚ Ed25519 signature โ”‚ + * โ”‚ 65 โ”‚ 32 โ”‚ DH ratchet public key โ”‚ + * โ”‚ 97 โ”‚ 4 โ”‚ pn (uint32 BE) - previous chain length โ”‚ + * โ”‚ 101 โ”‚ 4 โ”‚ n (uint32 BE) - message number โ”‚ + * โ”‚ 105 โ”‚ var โ”‚ Ciphertext (nonce + AEAD output) โ”‚ + * โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ + */ + +import { MessageHeader, ParsedRatchetPayload, RATCHET_VERSION_V1 } from './types.js'; + +/** Minimum valid payload length: version + sig + header */ +const MIN_PAYLOAD_LENGTH = 1 + 64 + 32 + 4 + 4; // 105 bytes + +// ============================================================================= +// Encoding +// ============================================================================= + +/** + * Package a ratchet message into binary format. + * + * @param signature - Ed25519 signature (64 bytes) + * @param header - Message header (dh, pn, n) + * @param ciphertext - Encrypted payload (nonce + secretbox output) + * @returns Binary payload ready for on-chain submission + */ +export function packageRatchetPayload( + signature: Uint8Array, + header: MessageHeader, + ciphertext: Uint8Array +): Uint8Array { + if (signature.length !== 64) { + throw new Error(`Invalid signature length: ${signature.length}, expected 64`); + } + if (header.dh.length !== 32) { + throw new Error(`Invalid DH key length: ${header.dh.length}, expected 32`); + } + + // Total: 1 + 64 + 32 + 4 + 4 + ciphertext.length = 105 + ciphertext.length + const payload = new Uint8Array(MIN_PAYLOAD_LENGTH + ciphertext.length); + const view = new DataView(payload.buffer); + + let offset = 0; + + // Version byte + payload[offset++] = RATCHET_VERSION_V1; + + // Signature (64 bytes) + payload.set(signature, offset); + offset += 64; + + // DH public key (32 bytes) + payload.set(header.dh, offset); + offset += 32; + + // pn (uint32 big-endian) + view.setUint32(offset, header.pn, false); + offset += 4; + + // n (uint32 big-endian) + view.setUint32(offset, header.n, false); + offset += 4; + + // Ciphertext (variable length) + payload.set(ciphertext, offset); + + return payload; +} + +// ============================================================================= +// Decoding +// ============================================================================= + +/** + * Parse a binary ratchet payload. + * + * @param payload - Raw binary payload + * @returns Parsed components, or null if invalid format + */ +export function parseRatchetPayload(payload: Uint8Array): ParsedRatchetPayload | null { + if (payload.length < MIN_PAYLOAD_LENGTH) { + return null; // Too short + } + + const view = new DataView(payload.buffer, payload.byteOffset, payload.byteLength); + let offset = 0; + + // Version + const version = payload[offset++]; + if (version !== RATCHET_VERSION_V1) { + return null; // Unknown version + } + + // Signature (64 bytes) + const signature = payload.slice(offset, offset + 64); + offset += 64; + + // DH public key (32 bytes) + const dh = payload.slice(offset, offset + 32); + offset += 32; + + // pn (uint32 big-endian) + const pn = view.getUint32(offset, false); + offset += 4; + + // n (uint32 big-endian) + const n = view.getUint32(offset, false); + offset += 4; + + // Ciphertext (remaining bytes) + const ciphertext = payload.slice(offset); + + return { + version, + signature, + header: { dh, pn, n }, + ciphertext, + }; +} + +// ============================================================================= +// Detection +// ============================================================================= + +/** + * Check if payload is in ratchet binary format. + * Used to distinguish ratchet messages from legacy JSON format. + * + * @param payload - Raw payload bytes + * @returns true if payload starts with ratchet version byte + */ +export function isRatchetPayload(payload: Uint8Array): boolean { + return payload.length >= MIN_PAYLOAD_LENGTH && payload[0] === RATCHET_VERSION_V1; +} + +/** + * Check if hex string represents a ratchet payload. + * Convenience wrapper for hex-encoded payloads from chain. + * + * @param hexPayload - Hex string (with or without 0x prefix) + * @returns true if payload is ratchet format + */ +export function isRatchetPayloadHex(hexPayload: string): boolean { + const hex = hexPayload.startsWith('0x') ? hexPayload.slice(2) : hexPayload; + if (hex.length < MIN_PAYLOAD_LENGTH * 2) { + return false; + } + // Check first byte is version + const firstByte = parseInt(hex.slice(0, 2), 16); + return firstByte === RATCHET_VERSION_V1; +} + +// ============================================================================= +// Utilities +// ============================================================================= + +/** + * Convert hex string to Uint8Array. + * + * @param hex - Hex string (with or without 0x prefix) + * @returns Byte array + */ +export function hexToBytes(hex: string): Uint8Array { + const cleanHex = hex.startsWith('0x') ? hex.slice(2) : hex; + const bytes = new Uint8Array(cleanHex.length / 2); + for (let i = 0; i < bytes.length; i++) { + bytes[i] = parseInt(cleanHex.slice(i * 2, i * 2 + 2), 16); + } + return bytes; +} + +/** + * Convert Uint8Array to hex string. + * + * @param bytes - Byte array + * @param prefix - Whether to include 0x prefix (default: true) + * @returns Hex string + */ +export function bytesToHex(bytes: Uint8Array, prefix: boolean = true): string { + const hex = Array.from(bytes) + .map((b) => b.toString(16).padStart(2, '0')) + .join(''); + return prefix ? `0x${hex}` : hex; +} \ No newline at end of file diff --git a/packages/sdk/src/ratchet/decrypt.ts b/packages/sdk/src/ratchet/decrypt.ts new file mode 100644 index 0000000..23d6d61 --- /dev/null +++ b/packages/sdk/src/ratchet/decrypt.ts @@ -0,0 +1,325 @@ +// packages/sdk/src/ratchet/decrypt.ts + +/** + * Ratchet Decryption with Skip Key Handling. + * + * Handles: + * - Normal sequential message decryption + * - DH ratchet steps when sender's DH key changes + * - Out-of-order messages via skipped keys + * + * N.b: Caller must verify Ed25519 signature before calling this function. + * This function assumes the message is authenticated. + */ + +import nacl from 'tweetnacl'; +import { hexlify } from 'ethers'; +import { + RatchetSession, + MessageHeader, + DecryptResult, + SkippedKey, + MAX_SKIP_PER_MESSAGE, + MAX_STORED_SKIPPED_KEYS, +} from './types.js'; +import { kdfRootKey, kdfChainKey, dh, generateDHKeyPair } from './kdf.js'; + +// ============================================================================= +// Main Decrypt Function +// ============================================================================= + +/** + * Decrypt a message using the ratchet. + * + * Handles DH ratchet steps and out-of-order messages (skip keys). + * Returns updated session state and plaintext, or null if decryption fails. + * + * @param session - Current ratchet session state + * @param header - Parsed message header + * @param ciphertext - Encrypted payload (nonce + secretbox output) + * @returns Decrypt result with new session state and plaintext, or null on failure + */ +export function ratchetDecrypt( + session: RatchetSession, + header: MessageHeader, + ciphertext: Uint8Array +): DecryptResult | null { + // Sanity check: even authenticated messages shouldn't require insane skips + // This protects against malicious peers or corrupted state + const skipNeeded = Math.max(0, header.n - session.receivingMsgNumber); + if (skipNeeded > MAX_SKIP_PER_MESSAGE || header.pn > MAX_SKIP_PER_MESSAGE) { + console.error( + `Message requires ${skipNeeded} skips (pn=${header.pn}) โ€” likely corrupted or malicious peer` + ); + return null; + } + + const dhPubHex = hexlify(header.dh); + const currentTheirDHHex = session.dhTheirPublicKey + ? hexlify(session.dhTheirPublicKey) + : null; + + // 1. Try skipped keys first (handles out-of-order messages) + const skippedResult = trySkippedKeys(session, dhPubHex, header.n, ciphertext); + if (skippedResult) { + return skippedResult; + } + + // 2. Clone session for modifications + let newSession: RatchetSession = { ...session, skippedKeys: [...session.skippedKeys] }; + + // 3. Check if we need to perform a DH ratchet step + if (dhPubHex !== currentTheirDHHex) { + // Skip remaining messages on current receiving chain (if any) + if (newSession.receivingChainKey) { + newSession = skipMessages(newSession, newSession.receivingMsgNumber, header.pn); + } + + // Perform DH ratchet + newSession = dhRatchetStep(newSession, header.dh); + } + + // 4. Skip messages if n > receivingMsgNumber (within current epoch) + if (header.n > newSession.receivingMsgNumber) { + newSession = skipMessages(newSession, newSession.receivingMsgNumber, header.n); + } + + // 5. Derive message key + if (!newSession.receivingChainKey) { + console.error('No receiving chain key available'); + return null; + } + + const { chainKey: newReceivingChainKey, messageKey } = kdfChainKey( + newSession.receivingChainKey + ); + + // 6. Decrypt + const plaintext = decryptWithKey(ciphertext, messageKey); + + // 7. Wipe message key + try { + messageKey.fill(0); + } catch { + // Some environments may not allow filling typed arrays + } + + if (!plaintext) { + return null; + } + + // 8. Update session state + newSession = { + ...newSession, + receivingChainKey: newReceivingChainKey, + receivingMsgNumber: header.n + 1, + updatedAt: Date.now(), + }; + + return { + session: newSession, + plaintext, + }; +} + +// ============================================================================= +// DH Ratchet Step +// ============================================================================= + +/** + * Perform a DH ratchet step when receiving a message with a new DH public key. + * + * This advances both the receiving and sending chains: + * 1. Receiving DH: derive new receiving chain from DH(mySecret, theirNewPub) + * 2. Generate new DH keypair for sending + * 3. Sending DH: derive new sending chain from DH(newSecret, theirNewPub) + */ +function dhRatchetStep(session: RatchetSession, theirNewDHPub: Uint8Array): RatchetSession { + // Receiving DH: use our current secret with their new public + const dhReceive = dh(session.dhMySecretKey, theirNewDHPub); + const { rootKey: rootKey1, chainKey: receivingChainKey } = kdfRootKey( + session.rootKey, + dhReceive + ); + + // Generate new DH keypair for sending + const newDHKeyPair = generateDHKeyPair(); + + // Sending DH: use new secret with their new public + const dhSend = dh(newDHKeyPair.secretKey, theirNewDHPub); + const { rootKey: rootKey2, chainKey: sendingChainKey } = kdfRootKey(rootKey1, dhSend); + + return { + ...session, + rootKey: rootKey2, + dhMySecretKey: newDHKeyPair.secretKey, + dhMyPublicKey: newDHKeyPair.publicKey, + dhTheirPublicKey: theirNewDHPub, + receivingChainKey, + receivingMsgNumber: 0, + sendingChainKey, + sendingMsgNumber: 0, + previousChainLength: session.sendingMsgNumber, + }; +} + +// ============================================================================= +// Skip Key Management +// ============================================================================= + +/** + * Skip messages by deriving and storing their keys for later out-of-order decryption. + * + * Called when: + * - header.n > receivingMsgNumber (messages skipped in current epoch) + * - DH ratchet step with header.pn > 0 (messages from previous epoch) + */ +function skipMessages( + session: RatchetSession, + start: number, + until: number +): RatchetSession { + if (!session.receivingChainKey || until <= start) { + return session; + } + + const skippedKeys: SkippedKey[] = [...session.skippedKeys]; + let chainKey = session.receivingChainKey; + const dhPubHex = hexlify(session.dhTheirPublicKey); + const now = Date.now(); + + // Derive and store skipped keys + for (let i = start; i < until; i++) { + const { chainKey: newChainKey, messageKey } = kdfChainKey(chainKey); + skippedKeys.push({ + dhPubKeyHex: dhPubHex, + msgNumber: i, + messageKey: new Uint8Array(messageKey), // Copy to avoid reference issues + createdAt: now, + }); + chainKey = newChainKey; + } + + // Prune if exceeds storage limit (keep newest) + let prunedKeys = skippedKeys; + if (skippedKeys.length > MAX_STORED_SKIPPED_KEYS) { + // Sort by createdAt descending, keep newest + prunedKeys = skippedKeys + .sort((a, b) => b.createdAt - a.createdAt) + .slice(0, MAX_STORED_SKIPPED_KEYS); + } + + return { + ...session, + receivingChainKey: chainKey, + skippedKeys: prunedKeys, + }; +} + +/** + * Try to decrypt using stored skipped keys. + * Returns decrypt result if found, null otherwise. + */ +function trySkippedKeys( + session: RatchetSession, + dhPubHex: string, + msgNumber: number, + ciphertext: Uint8Array +): DecryptResult | null { + const idx = session.skippedKeys.findIndex( + (sk) => sk.dhPubKeyHex === dhPubHex && sk.msgNumber === msgNumber + ); + + if (idx === -1) { + return null; + } + + const skippedKey = session.skippedKeys[idx]; + const plaintext = decryptWithKey(ciphertext, skippedKey.messageKey); + + if (!plaintext) { + return null; + } + + // Remove used key from list + const newSkippedKeys = [...session.skippedKeys]; + newSkippedKeys.splice(idx, 1); + + // Wipe the key + try { + skippedKey.messageKey.fill(0); + } catch { + // Some environments may not allow filling typed arrays + } + + return { + session: { + ...session, + skippedKeys: newSkippedKeys, + updatedAt: Date.now(), + }, + plaintext, + }; +} + +// ============================================================================= +// Low-Level Decryption +// ============================================================================= + +/** + * Decrypt ciphertext with message key using XSalsa20-Poly1305. + * Ciphertext format: nonce (24 bytes) + secretbox output + */ +function decryptWithKey(ciphertext: Uint8Array, messageKey: Uint8Array): Uint8Array | null { + if (ciphertext.length < nacl.secretbox.nonceLength) { + return null; + } + + const nonce = ciphertext.slice(0, nacl.secretbox.nonceLength); + const box = ciphertext.slice(nacl.secretbox.nonceLength); + + const result = nacl.secretbox.open(box, nonce, messageKey); + return result || null; +} + +// ============================================================================= +// Utility: Prune Expired Skipped Keys +// ============================================================================= + +/** + * Remove skipped keys older than MAX_SKIPPED_KEYS_AGE_MS. + * Should be called periodically (e.g., on session load or after decrypt). + * + * @param session - Current session + * @param maxAgeMs - Maximum age in milliseconds (default: 24 hours) + * @returns Session with pruned skipped keys + */ +export function pruneExpiredSkippedKeys( + session: RatchetSession, + maxAgeMs: number = 24 * 60 * 60 * 1000 +): RatchetSession { + const now = Date.now(); + const cutoff = now - maxAgeMs; + + const prunedKeys = session.skippedKeys.filter((sk) => sk.createdAt > cutoff); + + for (const sk of session.skippedKeys) { + if (sk.createdAt <= cutoff) { + try { + sk.messageKey.fill(0); + } catch { + // typed array fill may not be supported + } + } + } + + if (prunedKeys.length === session.skippedKeys.length) { + return session; + } + + return { + ...session, + skippedKeys: prunedKeys, + updatedAt: now, + }; +} \ No newline at end of file diff --git a/packages/sdk/src/ratchet/encrypt.ts b/packages/sdk/src/ratchet/encrypt.ts new file mode 100644 index 0000000..35e5cc0 --- /dev/null +++ b/packages/sdk/src/ratchet/encrypt.ts @@ -0,0 +1,109 @@ +// packages/sdk/src/ratchet/encrypt.ts + +/** + * Ratchet Encryption. + * + * Encrypts plaintext using the current sending chain, advances chain state, + * and signs the message with Ed25519. + * + * IMPORTANT: Returns a NEW session object. Caller must NOT persist until + * the transaction is confirmed on-chain (two-phase commit pattern). + */ + +import nacl from 'tweetnacl'; +import { RatchetSession, MessageHeader, EncryptResult } from './types.js'; +import { kdfChainKey } from './kdf.js'; + +// ============================================================================= +// Header Encoding +// ============================================================================= + +/** + * Encode message header as 40 bytes for signing. + * Format: dh (32) + pn (4, BE) + n (4, BE) + */ +export function encodeHeader(header: MessageHeader): Uint8Array { + const buf = new Uint8Array(40); + buf.set(header.dh, 0); + new DataView(buf.buffer).setUint32(32, header.pn, false); // big-endian + new DataView(buf.buffer).setUint32(36, header.n, false); + return buf; +} + +// ============================================================================= +// Encryption +// ============================================================================= + +/** + * Encrypt a message using the ratchet. + * + * Returns updated session state (caller must persist after tx confirms) and + * encrypted payload with signature. + * + * Does NOT mutate the input session - returns a new session object. + * This enables two-phase commit: only persist if tx succeeds. + * + * @param session - Current ratchet session state + * @param plaintext - Message to encrypt + * @param signingSecretKey - Ed25519 secret key for signing (64 bytes) + * @returns Encrypt result with new session state, header, ciphertext, and signature + * @throws If session is not ready to send (no sending chain key) + */ +export function ratchetEncrypt( + session: RatchetSession, + plaintext: Uint8Array, + signingSecretKey: Uint8Array +): EncryptResult { + if (!session.sendingChainKey) { + throw new Error('Session not ready to send (no sending chain key)'); + } + + // 1. Advance sending chain to get message key + const { chainKey: newChainKey, messageKey } = kdfChainKey(session.sendingChainKey); + + // 2. Create header with current DH public key and message numbers + const header: MessageHeader = { + dh: session.dhMyPublicKey, + pn: session.previousChainLength, + n: session.sendingMsgNumber, + }; + + // 3. Encrypt with message key using XSalsa20-Poly1305 + const nonce = nacl.randomBytes(nacl.secretbox.nonceLength); // 24 bytes + const ciphertext = nacl.secretbox(plaintext, nonce, messageKey); + + // 4. Combine nonce + ciphertext + const encryptedPayload = new Uint8Array(nonce.length + ciphertext.length); + encryptedPayload.set(nonce, 0); + encryptedPayload.set(ciphertext, nonce.length); + + // 5. Sign (header || encryptedPayload) with Ed25519 + const headerBytes = encodeHeader(header); + const dataToSign = new Uint8Array(headerBytes.length + encryptedPayload.length); + dataToSign.set(headerBytes, 0); + dataToSign.set(encryptedPayload, headerBytes.length); + + const signature = nacl.sign.detached(dataToSign, signingSecretKey); + + // 6. Create new session state (don't mutate original) + const newSession: RatchetSession = { + ...session, + sendingChainKey: newChainKey, + sendingMsgNumber: session.sendingMsgNumber + 1, + updatedAt: Date.now(), + }; + + // 7. Wipe message key from memory (security hygiene) + try { + messageKey.fill(0); + } catch { + // Some environments may not allow filling typed arrays + } + + return { + session: newSession, + header, + ciphertext: encryptedPayload, + signature, + }; +} \ No newline at end of file diff --git a/packages/sdk/src/ratchet/index.ts b/packages/sdk/src/ratchet/index.ts new file mode 100644 index 0000000..6cd1d63 --- /dev/null +++ b/packages/sdk/src/ratchet/index.ts @@ -0,0 +1,113 @@ +// packages/sdk/src/ratchet/index.ts + +/** + * Double Ratchet Module for Verbeth E2EE Messaging. + * + * This module provides bilateral forward secrecy using a Signal-style + * Double Ratchet protocol adapted for on-chain messaging. + * + * Key Features: + * - Ephemeral-only initial secret (no identity keys in DH) + * - Ed25519 signatures for DoS protection + * - Binary encoding for gas efficiency + * - Two-phase commit support (immutable session operations) + * + * @example + * ```typescript + * import { + * initSessionAsResponder, + * initSessionAsInitiator, + * ratchetEncrypt, + * ratchetDecrypt, + * verifyMessageSignature, + * packageRatchetPayload, + * parseRatchetPayload, + * } from '@verbeth/sdk/ratchet'; + * + * // Bob accepts handshake and creates session + * const bobSession = initSessionAsResponder({ + * myAddress: bobAddress, + * contactAddress: aliceAddress, + * myResponderEphemeralSecret: ephemeralSecret, + * myResponderEphemeralPublic: ephemeralPublic, + * theirHandshakeEphemeralPubKey: aliceEphemeral, + * topicOutbound: topics.topicIn, + * topicInbound: topics.topicOut, + * }); + * + * // Bob encrypts a message + * const { session: newSession, header, ciphertext, signature } = ratchetEncrypt( + * bobSession, + * new TextEncoder().encode('Hello Alice!'), + * bobSigningSecretKey + * ); + * + * // Package for on-chain + * const payload = packageRatchetPayload(signature, header, ciphertext); + * ``` + */ + +export { + + MAX_SKIP_PER_MESSAGE, + MAX_STORED_SKIPPED_KEYS, + MAX_SKIPPED_KEYS_AGE_MS, + SYNC_BATCH_SIZE, + RATCHET_VERSION_V1, + + type RatchetSession, + type SkippedKey, + type SessionStatus, + type MessageHeader, + + type EncryptResult, + type DecryptResult, + type ParsedRatchetPayload, + + type InitResponderParams, + type InitInitiatorParams, +} from './types.js'; + +// KDF functions +export { + kdfRootKey, + kdfChainKey, + dh, + generateDHKeyPair, +} from './kdf.js'; + +// Session initialization +export { + initSessionAsResponder, + initSessionAsInitiator, + computeConversationId, +} from './session.js'; + +// Encryption +export { + ratchetEncrypt, + encodeHeader, +} from './encrypt.js'; + +// Decryption +export { + ratchetDecrypt, + pruneExpiredSkippedKeys, +} from './decrypt.js'; + +// Binary codec +export { + packageRatchetPayload, + parseRatchetPayload, + isRatchetPayload, + isRatchetPayloadHex, + hexToBytes, + bytesToHex, +} from './codec.js'; + +// Authentication +export { + verifyMessageSignature, + signMessage, + isValidPayloadFormat, +} from './auth.js'; \ No newline at end of file diff --git a/packages/sdk/src/ratchet/kdf.ts b/packages/sdk/src/ratchet/kdf.ts new file mode 100644 index 0000000..a5f81cb --- /dev/null +++ b/packages/sdk/src/ratchet/kdf.ts @@ -0,0 +1,95 @@ +// packages/sdk/src/ratchet/kdf.ts + +/** + * Key Derivation Functions for Double Ratchet. + * + * Uses HKDF-SHA256 for root key derivation and HMAC-SHA256 for chain key derivation, + * matching Signal protocol specifications. + */ + +import { hkdf } from '@noble/hashes/hkdf'; +import { sha256 } from '@noble/hashes/sha2'; +import { hmac } from '@noble/hashes/hmac'; +import nacl from 'tweetnacl'; + +// ============================================================================= +// Root Key Derivation +// ============================================================================= + +/** + * Derive new root key and chain key from DH output. + * Called on every DH ratchet step. + * + * KDF_RK(rk, dh_out) = HKDF(dh_out, rk, "VerbethRatchet", 64) + * โ†’ (new_rk[0:32], chain_key[32:64]) + * + * @param rootKey - Current root key (32 bytes) + * @param dhOutput - DH shared secret (32 bytes) + * @returns New root key and chain key + */ +export function kdfRootKey( + rootKey: Uint8Array, + dhOutput: Uint8Array +): { rootKey: Uint8Array; chainKey: Uint8Array } { + const output = hkdf(sha256, dhOutput, rootKey, 'VerbethRatchet', 64); + return { + rootKey: output.slice(0, 32), + chainKey: output.slice(32, 64), + }; +} + +// ============================================================================= +// Chain Key Derivation +// ============================================================================= + +/** + * Derive message key and advance chain key. + * Called for every message sent/received. + * + * KDF_CK(ck) = (HMAC(ck, 0x02), HMAC(ck, 0x01)) + * โ†’ (new_chain_key, message_key) + * + * @param chainKey - Current chain key (32 bytes) + * @returns New chain key and message key for encryption/decryption + */ +export function kdfChainKey( + chainKey: Uint8Array +): { chainKey: Uint8Array; messageKey: Uint8Array } { + // Message key derived with constant 0x01 + const messageKey = hmac(sha256, chainKey, new Uint8Array([0x01])); + // New chain key derived with constant 0x02 + const newChainKey = hmac(sha256, chainKey, new Uint8Array([0x02])); + + return { + chainKey: newChainKey, + messageKey: messageKey, + }; +} + +// ============================================================================= +// Diffie-Hellman Operations +// ============================================================================= + +/** + * Perform X25519 Diffie-Hellman key exchange. + * + * @param mySecretKey - My X25519 secret key (32 bytes) + * @param theirPublicKey - Their X25519 public key (32 bytes) + * @returns Shared secret (32 bytes) + */ +export function dh( + mySecretKey: Uint8Array, + theirPublicKey: Uint8Array +): Uint8Array { + return nacl.scalarMult(mySecretKey, theirPublicKey); +} + +/** + * Generate new X25519 keypair for DH ratchet step. + * + * @returns New keypair with secretKey and publicKey + */ +export function generateDHKeyPair(): { secretKey: Uint8Array; publicKey: Uint8Array } { + const kp = nacl.box.keyPair(); + return { secretKey: kp.secretKey, publicKey: kp.publicKey }; +} \ No newline at end of file diff --git a/packages/sdk/src/ratchet/session.ts b/packages/sdk/src/ratchet/session.ts new file mode 100644 index 0000000..d2ce68f --- /dev/null +++ b/packages/sdk/src/ratchet/session.ts @@ -0,0 +1,184 @@ +// packages/sdk/src/ratchet/session.ts + +/** + * Ratchet Session Initialization. + * + * CRITICAL DESIGN: Initial shared secret is derived from ephemeralโ†”ephemeral DH ONLY. + * NO identity keys are used in secret derivation. This ensures that compromise of + * identity keys NEVER allows decryption of past messages, not even the first one. + * + * Authentication is provided separately via Ed25519 signatures on every message. + */ + +import { keccak256, toUtf8Bytes } from 'ethers'; +import { + RatchetSession, + InitResponderParams, + InitInitiatorParams +} from './types.js'; +import { kdfRootKey, dh, generateDHKeyPair } from './kdf.js'; + +// ============================================================================= +// Helpers +// ============================================================================= + +/** + * Compute deterministic conversation ID from topics. + * Sorting ensures both parties derive the same ID regardless of perspective. + */ +export function computeConversationId(topicA: string, topicB: string): string { + const sorted = [topicA.toLowerCase(), topicB.toLowerCase()].sort(); + return keccak256(toUtf8Bytes(sorted.join(':'))); +} + +// ============================================================================= +// Session Initialization +// ============================================================================= + +/** + * Initialize session as RESPONDER (Bob). + * Called after receiving handshake, before/during sending response. + * + * Bob reuses his HandshakeResponse ephemeral key (responderEphemeralR) as his + * first DH ratchet key. This avoids adding new fields to the on-chain format. + * + * โš ๏ธ CRITICAL: The responder MUST persist myResponderEphemeralSecret immediately. + * This becomes dhMySecretKey and is required for all future ratchet operations. + * + * @param params - Initialization parameters + * @returns Initialized ratchet session + */ +export function initSessionAsResponder(params: InitResponderParams): RatchetSession { + const { + myAddress, + contactAddress, + myResponderEphemeralSecret, + myResponderEphemeralPublic, + theirHandshakeEphemeralPubKey, + topicOutbound, + topicInbound, + } = params; + + // Initial shared secret: DH(myEphemeral, theirEphemeral) ONLY + // NO identity keys โ†’ true forward secrecy from message 0 + const sharedSecret = dh(myResponderEphemeralSecret, theirHandshakeEphemeralPubKey); + + // Derive initial root key and sending chain key + const { rootKey, chainKey: sendingChainKey } = kdfRootKey( + new Uint8Array(32), // Initial salt (zeros) + sharedSecret + ); + + const now = Date.now(); + + return { + conversationId: computeConversationId(topicOutbound, topicInbound), + topicOutbound, + topicInbound, + myAddress, + contactAddress, + + rootKey, + + // Reuse responder ephemeral as first DH ratchet key + // This is already on-chain as responderEphemeralR + dhMySecretKey: myResponderEphemeralSecret, + dhMyPublicKey: myResponderEphemeralPublic, + dhTheirPublicKey: theirHandshakeEphemeralPubKey, + + // Bob can send immediately using sendingChainKey + sendingChainKey, + sendingMsgNumber: 0, + + // Receiving chain not yet established (Alice hasn't sent with her new DH key) + receivingChainKey: null, + receivingMsgNumber: 0, + + previousChainLength: 0, + skippedKeys: [], + + createdAt: now, + updatedAt: now, + epoch: 0, + status: 'active', + }; +} + +/** + * Initialize session as INITIATOR (Alice). + * Called after receiving and validating handshake response. + * + * Alice performs an immediate DH ratchet step upon initialization because + * Bob's ratchet ephemeral (from inside the decrypted payload) is his first DH public key. + * + * IMPORTANT: theirResponderEphemeralPubKey comes from INSIDE the decrypted + * HandshakeResponse payload, NOT from the on-chain responderEphemeralR field. + * The on-chain R is only used for tag verification and is different for unlinkability. + * + * @param params - Initialization parameters + * @returns Initialized ratchet session + */ +export function initSessionAsInitiator(params: InitInitiatorParams): RatchetSession { + const { + myAddress, + contactAddress, + myHandshakeEphemeralSecret, + theirResponderEphemeralPubKey, + topicOutbound, + topicInbound, + } = params; + + // Initial shared secret: DH(myEphemeral, theirEphemeral) ONLY + // This matches what Bob computed: DH(bobEphemeral, aliceEphemeral) + const sharedSecret = dh(myHandshakeEphemeralSecret, theirResponderEphemeralPubKey); + + // Derive same initial root key as Bob + const { rootKey: initialRootKey, chainKey: bobsSendingChain } = kdfRootKey( + new Uint8Array(32), // Same initial salt + sharedSecret + ); + // Note: bobsSendingChain is Bob's sending chain = Alice's receiving chain + + // Generate Alice's first DH keypair for sending + const myDHKeyPair = generateDHKeyPair(); + + // Perform sending ratchet step (Alice does this immediately) + const dhSend = dh(myDHKeyPair.secretKey, theirResponderEphemeralPubKey); + const { rootKey: finalRootKey, chainKey: sendingChainKey } = kdfRootKey( + initialRootKey, + dhSend + ); + + const now = Date.now(); + + return { + conversationId: computeConversationId(topicOutbound, topicInbound), + topicOutbound, + topicInbound, + myAddress, + contactAddress, + + rootKey: finalRootKey, + + // Alice's newly generated DH keypair + dhMySecretKey: myDHKeyPair.secretKey, + dhMyPublicKey: myDHKeyPair.publicKey, + // Bob's responder ephemeral is his first DH public key + dhTheirPublicKey: theirResponderEphemeralPubKey, + + sendingChainKey, + sendingMsgNumber: 0, + + // Alice's receiving chain = Bob's sending chain (from initial secret) + receivingChainKey: bobsSendingChain, + receivingMsgNumber: 0, + + previousChainLength: 0, + skippedKeys: [], + + createdAt: now, + updatedAt: now, + epoch: 0, + status: 'active', + }; +} \ No newline at end of file diff --git a/packages/sdk/src/ratchet/types.ts b/packages/sdk/src/ratchet/types.ts new file mode 100644 index 0000000..d40be7b --- /dev/null +++ b/packages/sdk/src/ratchet/types.ts @@ -0,0 +1,225 @@ +// packages/sdk/src/ratchet/types.ts + +/** + * Double Ratchet types and constants for Verbeth E2EE messaging. + * + * Key design decisions: + * - Sessions keyed by conversationId (derived from topics), NOT addresses + * - Initial secret from ephemeral-only DH (no identity keys) for true forward secrecy + * - Ed25519 signatures mandatory on all messages (DoS protection) + */ + +// ============================================================================= +// Constants +// ============================================================================= + +/** + * Sanity cap per ratchet step - protects against malicious peers or corrupted state. + * Auth-before-ratchet prevents external attackers; this caps internal state issues. + */ +export const MAX_SKIP_PER_MESSAGE = 100_000; + +/** + * Maximum stored skipped keys (memory/storage bound). + * When exceeded, oldest keys are pruned. + */ +export const MAX_STORED_SKIPPED_KEYS = 1000; + +/** + * Skipped keys TTL - 24 hours is sufficient for reorg tolerance. + * This is NOT message expiry; sequential messages don't use skipped keys. + */ +export const MAX_SKIPPED_KEYS_AGE_MS = 24 * 60 * 60 * 1000; + +/** + * Yield to UI every N derivations during large backlog processing. + */ +export const SYNC_BATCH_SIZE = 10_000; + +/** + * Binary payload version byte. + */ +export const RATCHET_VERSION_V1 = 0x01; + +// ============================================================================= +// Core Types +// ============================================================================= + +/** + * Ratchet session state. + * + * CRITICAL: This is stateful - must be persisted after every encrypt/decrypt. + * Session is identified by conversationId (derived from topics), enabling + * correct handling of Safe addresses vs EOAs. + */ +export interface RatchetSession { + // === Conversation Identity === + /** Primary key: keccak256(sort([topicOut, topicIn])) */ + conversationId: string; + /** My sending topic (bytes32 hex) */ + topicOutbound: `0x${string}`; + /** My receiving topic (bytes32 hex) */ + topicInbound: `0x${string}`; + /** My EOA address (for convenience/lookup) */ + myAddress: string; + /** Their EOA address (for convenience/lookup) */ + contactAddress: string; + + // === Root Ratchet === + /** Current root key (32 bytes) */ + rootKey: Uint8Array; + + // === DH Ratchet Keys === + /** My current DH secret key (32 bytes) */ + dhMySecretKey: Uint8Array; + /** My current DH public key (32 bytes) */ + dhMyPublicKey: Uint8Array; + /** Their last received DH public key (32 bytes) */ + dhTheirPublicKey: Uint8Array; + + // === Sending Chain === + /** Current sending chain key (null until first DH ratchet as sender) */ + sendingChainKey: Uint8Array | null; + /** Next sending message number (Ns) */ + sendingMsgNumber: number; + + // === Receiving Chain === + /** Current receiving chain key (null until first message received) */ + receivingChainKey: Uint8Array | null; + /** Next expected receiving message number (Nr) */ + receivingMsgNumber: number; + + // === Skip Handling === + /** Message count in previous sending chain (PN header field) */ + previousChainLength: number; + /** Stored keys for out-of-order messages */ + skippedKeys: SkippedKey[]; + + // === Metadata === + /** Session creation timestamp */ + createdAt: number; + /** Last state update timestamp */ + updatedAt: number; + + // === Recovery === + /** Increments on session reset (internal bookkeeping only) */ + epoch: number; + + // === Status === + /** Session lifecycle status */ + status: SessionStatus; +} + +/** + * Stored key for out-of-order message decryption. + */ +export interface SkippedKey { + /** DH epoch identifier (hex of their DH pubkey) */ + dhPubKeyHex: string; + /** Message number in that epoch */ + msgNumber: number; + /** Derived message key (32 bytes) */ + messageKey: Uint8Array; + /** Creation timestamp for TTL pruning */ + createdAt: number; +} + +/** + * Session lifecycle status. + */ +export type SessionStatus = + | 'active' // Normal operating state + | 'inactive_reset' // I initiated reset, waiting for peer + | 'inactive_superseded' // Peer initiated reset, I accepted + | 'frozen'; // Read-only archive + +/** + * Message header (40 bytes when encoded). + */ +export interface MessageHeader { + /** Sender's current DH ratchet public key (32 bytes) */ + dh: Uint8Array; + /** Previous chain length - messages in sender's previous sending chain */ + pn: number; + /** Message number in current sending chain */ + n: number; +} + +// ============================================================================= +// Result Types +// ============================================================================= + +/** + * Result of ratchetEncrypt - includes new session state for two-phase commit. + */ +export interface EncryptResult { + /** Updated session state (caller must persist after tx confirms) */ + session: RatchetSession; + /** Message header */ + header: MessageHeader; + /** Encrypted payload (nonce + ciphertext) */ + ciphertext: Uint8Array; + /** Ed25519 signature over (header || ciphertext) */ + signature: Uint8Array; +} + +/** + * Result of ratchetDecrypt. + */ +export interface DecryptResult { + /** Updated session state (caller must persist) */ + session: RatchetSession; + /** Decrypted plaintext */ + plaintext: Uint8Array; +} + +/** + * Parsed binary ratchet payload. + */ +export interface ParsedRatchetPayload { + /** Protocol version */ + version: number; + /** Ed25519 signature (64 bytes) */ + signature: Uint8Array; + /** Message header */ + header: MessageHeader; + /** Encrypted payload */ + ciphertext: Uint8Array; +} + +// ============================================================================= +// Initialization Parameters +// ============================================================================= + +/** + * Parameters for initializing session as responder (Bob). + */ +export interface InitResponderParams { + myAddress: string; + contactAddress: string; + /** Ephemeral secret used in HandshakeResponse (becomes dhMySecretKey) */ + myResponderEphemeralSecret: Uint8Array; + /** = responderEphemeralR on-chain */ + myResponderEphemeralPublic: Uint8Array; + /** Alice's ephemeral from Handshake event */ + theirHandshakeEphemeralPubKey: Uint8Array; + topicOutbound: `0x${string}`; + topicInbound: `0x${string}`; +} + +/** + * Parameters for initializing session as initiator (Alice). + */ +export interface InitInitiatorParams { + myAddress: string; + contactAddress: string; + /** Handshake ephemeral secret (must persist until response arrives) */ + myHandshakeEphemeralSecret: Uint8Array; + /** + * Bob's ratchet ephemeral from INSIDE the decrypted HandshakeResponse payload. + * NOTE: This is DIFFERENT from the on-chain responderEphemeralR (which is only for tag). + */ + theirResponderEphemeralPubKey: Uint8Array; + topicOutbound: `0x${string}`; + topicInbound: `0x${string}`; +} \ No newline at end of file diff --git a/packages/sdk/src/send.ts b/packages/sdk/src/send.ts index c9ea51d..942b691 100644 --- a/packages/sdk/src/send.ts +++ b/packages/sdk/src/send.ts @@ -1,5 +1,12 @@ // packages/sdk/src/send.ts +/** + * Handshake and message sending functions. + * + * NOTE: sendEncryptedMessage is REMOVED - use ratchet for established sessions. + * Only handshake functions remain here. + */ + import { keccak256, toUtf8Bytes, @@ -8,71 +15,27 @@ import { getBytes } from "ethers"; import nacl from 'tweetnacl'; -import { getNextNonce } from './utils/nonce.js'; -import { encryptMessage, encryptStructuredPayload, deriveDuplexTopics } from './crypto.js'; +import { encryptStructuredPayload, deriveDuplexTopics } from './crypto.js'; import { HandshakeContent, serializeHandshakeContent, encodeUnifiedPubKeys, createHandshakeResponseContent, - decodeUnifiedPubKeys, } from './payload.js'; import { IdentityKeyPair, IdentityProof, TopicInfoWire } from './types.js'; import { IExecutor } from './executor.js'; -import { computeTagFromResponder } from './crypto.js' - - - -/** - * Sends an encrypted message assuming recipient's keys were already obtained via handshake. - * Executor-agnostic: works with EOA, UserOp, and Direct EntryPoint (for tests) - */ -export async function sendEncryptedMessage({ - executor, - topic, - message, - recipientPubKey, - senderAddress, - senderSignKeyPair, - timestamp -}: { - executor: IExecutor; - topic: string; - message: string; - recipientPubKey: Uint8Array; // X25519 key for encryption - senderAddress: string; - senderSignKeyPair: nacl.SignKeyPair; // Ed25519 keys for signing - timestamp: number; -}) { - if (!executor) { - throw new Error("Executor must be provided"); - } - - const ephemeralKeyPair = nacl.box.keyPair(); - - const ciphertext = encryptMessage( - message, - recipientPubKey, // X25519 for encryption - ephemeralKeyPair.secretKey, - ephemeralKeyPair.publicKey, - senderSignKeyPair.secretKey, // Ed25519 for signing - senderSignKeyPair.publicKey - ); - - const nonce = getNextNonce(senderAddress, topic); - - return executor.sendMessage(toUtf8Bytes(ciphertext), topic, timestamp, nonce); -} +import { computeTagFromResponder } from './crypto.js'; /** * Initiates an on-chain handshake with unified keys and mandatory identity proof. * Executor-agnostic: works with EOA, UserOp, and Direct EntryPoint (for tests) + * + * @returns Transaction and ephemeral keypair (MUST be persisted for session init) */ export async function initiateHandshake({ executor, recipientAddress, identityKeyPair, - ephemeralPubKey, plaintextPayload, identityProof, signer @@ -80,15 +43,20 @@ export async function initiateHandshake({ executor: IExecutor; recipientAddress: string; identityKeyPair: IdentityKeyPair; - ephemeralPubKey: Uint8Array; plaintextPayload: string; identityProof: IdentityProof; signer: Signer; -}) { +}): Promise<{ + tx: any; + ephemeralKeyPair: nacl.BoxKeyPair; +}> { if (!executor) { throw new Error("Executor must be provided"); } + // Generate ephemeral keypair for this handshake + const ephemeralKeyPair = nacl.box.keyPair(); + const recipientHash = keccak256( toUtf8Bytes('contact:' + recipientAddress.toLowerCase()) ); @@ -106,50 +74,83 @@ export async function initiateHandshake({ identityKeyPair.signingPublicKey // Ed25519 for signing ); - return await executor.initiateHandshake( + const tx = await executor.initiateHandshake( recipientHash, hexlify(unifiedPubKeys), - hexlify(ephemeralPubKey), + hexlify(ephemeralKeyPair.publicKey), toUtf8Bytes(serializedPayload) ); + + return { + tx, + ephemeralKeyPair, // Caller MUST persist secretKey for ratchet session init + }; } /** * Responds to a handshake with unified keys and mandatory identity proof. * Executor-agnostic: works with EOA, UserOp, and Direct EntryPoint (for tests) + * + * @returns Transaction, tag, salt, AND ephemeral keys (MUST be persisted for ratchet session) */ export async function respondToHandshake({ executor, - initiatorPubKey, // X25519 key from initiator (ephemeral) + initiatorEphemeralPubKey, responderIdentityKeyPair, - responderEphemeralKeyPair, note, identityProof, signer, initiatorIdentityPubKey, }: { executor: IExecutor; - initiatorPubKey: Uint8Array; + initiatorEphemeralPubKey: Uint8Array; responderIdentityKeyPair: IdentityKeyPair; - responderEphemeralKeyPair?: nacl.BoxKeyPair; note?: string; identityProof: IdentityProof; signer: Signer; initiatorIdentityPubKey?: Uint8Array; -}) { +}): Promise<{ + tx: any; + salt: Uint8Array; + tag: `0x${string}`; + /** Responder's DH ratchet secret - MUST persist as dhMySecretKey in ratchet session */ + responderEphemeralSecret: Uint8Array; + /** Responder's DH ratchet public - inside encrypted payload, NOT on-chain */ + responderEphemeralPublic: Uint8Array; +}> { if (!executor) { throw new Error("Executor must be provided"); } - const ephemeralKeyPair = responderEphemeralKeyPair || nacl.box.keyPair(); - - // Generate a separate ephemeral key (R,r) just for the tag - const tagKeyPair = nacl.box.keyPair(); + // ========================================================================= + // TWO SEPARATE KEYPAIRS for unlinkability: + // + // 1. tagKeyPair (R, r): ONLY for tag computation + // - R goes on-chain as responderEphemeralR + // - Used by Alice to verify the tag + // - NOT used for ratchet + // + // 2. ratchetKeyPair: For post-handshake encryption and first DH ratchet key + // - Public key goes INSIDE encrypted payload (not on-chain) + // - Becomes dhMySecretKey/dhMyPublicKey in ratchet session + // + // Why this matters: With a single keypair, the on-chain R would equal the + // first message's DH header, allowing observers to link HandshakeResponse + // to subsequent conversation. With two keypairs, there's no on-chain link. + // ========================================================================= + + // Keypair for tag computation - R goes on-chain + const tagKeyPair = nacl.box.keyPair(); + + // Keypair for ratchet - public key is HIDDEN inside encrypted payload + const ratchetKeyPair = nacl.box.keyPair(); + + // Tag is derived from tagKeyPair, not ratchetKeyPair const inResponseTo = computeTagFromResponder( tagKeyPair.secretKey, - initiatorPubKey + initiatorEphemeralPubKey ); - const salt: Uint8Array = getBytes(inResponseTo); // for topics HKDF + const salt: Uint8Array = getBytes(inResponseTo); let topicInfo: TopicInfoWire | undefined = undefined; if (initiatorIdentityPubKey) { @@ -161,34 +162,38 @@ export async function respondToHandshake({ topicInfo = { out: topicOut, in: topicIn, chk: checksum }; } - + // Response content includes ratchetKeyPair.publicKey (hidden inside encrypted payload) const responseContent = createHandshakeResponseContent( - responderIdentityKeyPair.publicKey, // X25519 - responderIdentityKeyPair.signingPublicKey, // Ed25519 - ephemeralKeyPair.publicKey, + responderIdentityKeyPair.publicKey, // X25519 identity + responderIdentityKeyPair.signingPublicKey, // Ed25519 signing + ratchetKeyPair.publicKey, // First DH ratchet key (INSIDE payload) note, identityProof, topicInfo ); - // Encrypt the response for the initiator + // Encrypt using ratchetKeyPair (the epk in encrypted payload = ratchetKeyPair.publicKey) const payload = encryptStructuredPayload( responseContent, - initiatorPubKey, // Encrypt to initiator's X25519 (ephemeral) key - ephemeralKeyPair.secretKey, - ephemeralKeyPair.publicKey + initiatorEphemeralPubKey, + ratchetKeyPair.secretKey, + ratchetKeyPair.publicKey ); - // Execute the transaction + // Execute transaction - tagKeyPair.publicKey goes on-chain (NOT ratchetKeyPair) const tx = await executor.respondToHandshake( inResponseTo, - hexlify(tagKeyPair.publicKey), + hexlify(tagKeyPair.publicKey), // Tag key on-chain for tag verification toUtf8Bytes(payload) ); return { tx, salt, - tag: inResponseTo + tag: inResponseTo, + // Return RATCHET keys (not tag keys) for session initialization + // These are DIFFERENT from the on-chain responderEphemeralR + responderEphemeralSecret: ratchetKeyPair.secretKey, + responderEphemeralPublic: ratchetKeyPair.publicKey, }; } \ No newline at end of file diff --git a/packages/sdk/test/executor.test.ts b/packages/sdk/test/executor.test.ts index 741ab5d..ccf3ee7 100644 --- a/packages/sdk/test/executor.test.ts +++ b/packages/sdk/test/executor.test.ts @@ -6,7 +6,6 @@ import { EOAExecutor, UserOpExecutor, DirectEntryPointExecutor, - sendEncryptedMessage, initiateHandshake, respondToHandshake, } from "../src/index.js"; @@ -95,115 +94,6 @@ describe("ExecutorFactory", () => { }); }); -describe("sendEncryptedMessage with Executors", () => { - beforeEach(() => { - vi.clearAllMocks(); - }); - - it("works with EOA executor", async () => { - const executor = ExecutorFactory.createEOA(fakeContract); - - await sendEncryptedMessage({ - executor, - topic: "0x" + "ab".repeat(32), - message: "Hello from EOA", - recipientPubKey: testRecipientKey.publicKey, - senderAddress: "0xAlice", - senderSignKeyPair: testSenderSignKey, - timestamp: 42, - }); - - expect(mockSendMessage).toHaveBeenCalledTimes(1); - - const callArgs = mockSendMessage.mock.calls[0]; - expect(callArgs).toHaveLength(4); // ciphertext, topic, timestamp, nonce - expect(typeof callArgs[1]).toBe("string"); // topic - expect(typeof callArgs[2]).toBe("number"); // timestamp - expect(typeof callArgs[3]).toBe("bigint"); // nonce - }); - - it("works with UserOp executor", async () => { - const executor = ExecutorFactory.createUserOp( - TEST_SMART_ACCOUNT_ADDRESS, - TEST_ENTRYPOINT_ADDRESS, - TEST_LOGCHAIN_ADDRESS, - mockBundler, - mockSmartAccount - ); - - await sendEncryptedMessage({ - executor, - topic: "0x" + "cd".repeat(32), - message: "Hello from UserOp", - recipientPubKey: testRecipientKey.publicKey, - senderAddress: TEST_SMART_ACCOUNT_ADDRESS, - senderSignKeyPair: testSenderSignKey, - timestamp: 43, - }); - - expect(mockSmartAccount.getNonce).toHaveBeenCalled(); - expect(mockSmartAccount.signUserOperation).toHaveBeenCalled(); - expect(mockBundler.sendUserOperation).toHaveBeenCalled(); - expect(mockBundler.waitForUserOperationReceipt).toHaveBeenCalled(); - }); - - it("works with DirectEntryPoint executor", async () => { - const executor = ExecutorFactory.createDirectEntryPoint( - TEST_SMART_ACCOUNT_ADDRESS, - mockEntryPoint, - TEST_LOGCHAIN_ADDRESS, - mockSmartAccount, - mockSigner - ); - - await sendEncryptedMessage({ - executor, - topic: "0x" + "ef".repeat(32), - message: "Hello from DirectEntryPoint", - recipientPubKey: testRecipientKey.publicKey, - senderAddress: TEST_SMART_ACCOUNT_ADDRESS, - senderSignKeyPair: testSenderSignKey, - timestamp: 44, - }); - - expect(mockSmartAccount.getNonce).toHaveBeenCalled(); - expect(mockSmartAccount.signUserOperation).toHaveBeenCalled(); - expect(mockEntryPoint.handleOps).toHaveBeenCalled(); - expect(mockSigner.getAddress).toHaveBeenCalled(); - }); - - it("generates different nonces for different calls with same executor", async () => { - const executor = ExecutorFactory.createEOA(fakeContract); - - // First message - await sendEncryptedMessage({ - executor, - topic: "0x" + "aa".repeat(32), - message: "Message 1", - recipientPubKey: testRecipientKey.publicKey, - senderAddress: "0xAlice", - senderSignKeyPair: testSenderSignKey, - timestamp: 100, - }); - - // Second message - await sendEncryptedMessage({ - executor, - topic: "0x" + "aa".repeat(32), - message: "Message 2", - recipientPubKey: testRecipientKey.publicKey, - senderAddress: "0xAlice", - senderSignKeyPair: testSenderSignKey, - timestamp: 101, - }); - - expect(mockSendMessage).toHaveBeenCalledTimes(2); - - const firstNonce = mockSendMessage.mock.calls[0][3]; - const secondNonce = mockSendMessage.mock.calls[1][3]; - expect(secondNonce).toBe(firstNonce + 1n); - }); -}); describe("initiateHandshake with Executors", () => { beforeEach(() => { @@ -217,7 +107,6 @@ describe("initiateHandshake with Executors", () => { executor, recipientAddress: "0xBob", identityKeyPair: testIdentityKeyPair, - ephemeralPubKey: nacl.box.keyPair().publicKey, plaintextPayload: "Hello Bob from EOA", identityProof: testIdentityProof, signer: mockSigner, @@ -245,7 +134,6 @@ describe("initiateHandshake with Executors", () => { executor, recipientAddress: "0xBob", identityKeyPair: testIdentityKeyPair, - ephemeralPubKey: nacl.box.keyPair().publicKey, plaintextPayload: "Hello Bob from UserOp", identityProof: testIdentityProof, signer: mockSigner, @@ -269,7 +157,6 @@ describe("initiateHandshake with Executors", () => { executor, recipientAddress: "0xBob", identityKeyPair: testIdentityKeyPair, - ephemeralPubKey: nacl.box.keyPair().publicKey, plaintextPayload: "Hello Bob from DirectEntryPoint", identityProof: testIdentityProof, signer: mockSigner, @@ -291,7 +178,7 @@ describe("respondToHandshake with Executors", () => { await respondToHandshake({ executor, - initiatorPubKey: testRecipientKey.publicKey, + initiatorEphemeralPubKey: testRecipientKey.publicKey, responderIdentityKeyPair: testIdentityKeyPair, note: "Response from EOA", identityProof: testIdentityProof, @@ -322,7 +209,7 @@ describe("respondToHandshake with Executors", () => { await respondToHandshake({ executor, - initiatorPubKey: testRecipientKey.publicKey, + initiatorEphemeralPubKey: testRecipientKey.publicKey, responderIdentityKeyPair: testIdentityKeyPair, note: "Response from UserOp", identityProof: testIdentityProof, @@ -345,7 +232,7 @@ describe("respondToHandshake with Executors", () => { await respondToHandshake({ executor, - initiatorPubKey: testRecipientKey.publicKey, + initiatorEphemeralPubKey: testRecipientKey.publicKey, responderIdentityKeyPair: testIdentityKeyPair, note: "Response from DirectEntryPoint", identityProof: testIdentityProof, @@ -362,7 +249,7 @@ describe("respondToHandshake with Executors", () => { await respondToHandshake({ executor, - initiatorPubKey: testRecipientKey.publicKey, + initiatorEphemeralPubKey: testRecipientKey.publicKey, responderIdentityKeyPair: testIdentityKeyPair, // No responderEphemeralKeyPair provided note: "Auto-generated ephemeral key", diff --git a/packages/sdk/test/ratchet.test.ts b/packages/sdk/test/ratchet.test.ts new file mode 100644 index 0000000..c1477a5 --- /dev/null +++ b/packages/sdk/test/ratchet.test.ts @@ -0,0 +1,445 @@ +// packages/sdk/test/ratchet.test.ts + +import { describe, it, expect, beforeEach } from "vitest"; +import nacl from "tweetnacl"; +import { + // Session + initSessionAsResponder, + initSessionAsInitiator, + computeConversationId, + // Encrypt/Decrypt + ratchetEncrypt, + ratchetDecrypt, + pruneExpiredSkippedKeys, + // Codec + packageRatchetPayload, + parseRatchetPayload, + isRatchetPayload, + hexToBytes, + bytesToHex, + // Auth + verifyMessageSignature, + // KDF + generateDHKeyPair, + // Types + RatchetSession, +} from "../src/ratchet/index.js"; + +// ============================================================================= +// Test Helpers +// ============================================================================= + +function createTestTopics(): { topicOut: `0x${string}`; topicIn: `0x${string}` } { + const randomBytes = nacl.randomBytes(32); + const topicOut = bytesToHex(randomBytes) as `0x${string}`; + const topicIn = bytesToHex(nacl.randomBytes(32)) as `0x${string}`; + return { topicOut, topicIn }; +} + +function createSigningKeyPair() { + return nacl.sign.keyPair(); +} + +// ============================================================================= +// Tests +// ============================================================================= + +describe("Double Ratchet", () => { + describe("Session Initialization", () => { + it("should create matching sessions for responder and initiator", () => { + // Simulate handshake ephemeral keys + const aliceEphemeral = generateDHKeyPair(); + const bobEphemeral = generateDHKeyPair(); + const topics = createTestTopics(); + + // Bob (responder) creates session first + const bobSession = initSessionAsResponder({ + myAddress: "0xBob", + contactAddress: "0xAlice", + myResponderEphemeralSecret: bobEphemeral.secretKey, + myResponderEphemeralPublic: bobEphemeral.publicKey, + theirHandshakeEphemeralPubKey: aliceEphemeral.publicKey, + topicOutbound: topics.topicIn, // Bob's outbound = Alice's inbound + topicInbound: topics.topicOut, // Bob's inbound = Alice's outbound + }); + + // Alice (initiator) creates session after receiving response + const aliceSession = initSessionAsInitiator({ + myAddress: "0xAlice", + contactAddress: "0xBob", + myHandshakeEphemeralSecret: aliceEphemeral.secretKey, + theirResponderEphemeralPubKey: bobEphemeral.publicKey, + topicOutbound: topics.topicOut, + topicInbound: topics.topicIn, + }); + + // Verify conversation IDs match + expect(bobSession.conversationId).toBe(aliceSession.conversationId); + + // Verify both have sending chain keys (can send immediately) + expect(bobSession.sendingChainKey).not.toBeNull(); + expect(aliceSession.sendingChainKey).not.toBeNull(); + + // Verify Alice has receiving chain (for Bob's messages) + expect(aliceSession.receivingChainKey).not.toBeNull(); + }); + + it("should compute deterministic conversation ID", () => { + const topicA = "0xaaaa" as const; + const topicB = "0xbbbb" as const; + + const id1 = computeConversationId(topicA, topicB); + const id2 = computeConversationId(topicB, topicA); + + expect(id1).toBe(id2); // Order shouldn't matter + }); + }); + + describe("Encrypt/Decrypt Round-Trip", () => { + let aliceSession: RatchetSession; + let bobSession: RatchetSession; + let aliceSigning: nacl.SignKeyPair; + let bobSigning: nacl.SignKeyPair; + + beforeEach(() => { + // Setup sessions + const aliceEphemeral = generateDHKeyPair(); + const bobEphemeral = generateDHKeyPair(); + const topics = createTestTopics(); + + bobSession = initSessionAsResponder({ + myAddress: "0xBob", + contactAddress: "0xAlice", + myResponderEphemeralSecret: bobEphemeral.secretKey, + myResponderEphemeralPublic: bobEphemeral.publicKey, + theirHandshakeEphemeralPubKey: aliceEphemeral.publicKey, + topicOutbound: topics.topicIn, + topicInbound: topics.topicOut, + }); + + aliceSession = initSessionAsInitiator({ + myAddress: "0xAlice", + contactAddress: "0xBob", + myHandshakeEphemeralSecret: aliceEphemeral.secretKey, + theirResponderEphemeralPubKey: bobEphemeral.publicKey, + topicOutbound: topics.topicOut, + topicInbound: topics.topicIn, + }); + + aliceSigning = createSigningKeyPair(); + bobSigning = createSigningKeyPair(); + }); + + it("should encrypt and decrypt a message (Bob to Alice)", () => { + const plaintext = new TextEncoder().encode("Hello Alice!"); + + // Bob encrypts + const { session: bobAfter, header, ciphertext, signature } = ratchetEncrypt( + bobSession, + plaintext, + bobSigning.secretKey + ); + + // Verify signature + const sigValid = verifyMessageSignature( + signature, + header, + ciphertext, + bobSigning.publicKey + ); + expect(sigValid).toBe(true); + + // Alice decrypts + const result = ratchetDecrypt(aliceSession, header, ciphertext); + + expect(result).not.toBeNull(); + expect(new TextDecoder().decode(result!.plaintext)).toBe("Hello Alice!"); + + // Verify session states advanced + expect(bobAfter.sendingMsgNumber).toBe(1); + expect(result!.session.receivingMsgNumber).toBe(1); + }); + + it("should encrypt and decrypt a message (Alice to Bob)", () => { + const plaintext = new TextEncoder().encode("Hello Bob!"); + + // Alice encrypts + const { session: aliceAfter, header, ciphertext, signature } = ratchetEncrypt( + aliceSession, + plaintext, + aliceSigning.secretKey + ); + + // Verify signature + const sigValid = verifyMessageSignature( + signature, + header, + ciphertext, + aliceSigning.publicKey + ); + expect(sigValid).toBe(true); + + // Bob decrypts (triggers DH ratchet since Alice has new DH key) + const result = ratchetDecrypt(bobSession, header, ciphertext); + + expect(result).not.toBeNull(); + expect(new TextDecoder().decode(result!.plaintext)).toBe("Hello Bob!"); + }); + + it("should handle alternating messages (ping-pong)", () => { + // Bob -> Alice + const msg1 = new TextEncoder().encode("Message 1 from Bob"); + const enc1 = ratchetEncrypt(bobSession, msg1, bobSigning.secretKey); + const dec1 = ratchetDecrypt(aliceSession, enc1.header, enc1.ciphertext); + expect(dec1).not.toBeNull(); + + // Update sessions + bobSession = enc1.session; + aliceSession = dec1!.session; + + // Alice -> Bob + const msg2 = new TextEncoder().encode("Message 2 from Alice"); + const enc2 = ratchetEncrypt(aliceSession, msg2, aliceSigning.secretKey); + const dec2 = ratchetDecrypt(bobSession, enc2.header, enc2.ciphertext); + expect(dec2).not.toBeNull(); + + // Update sessions + aliceSession = enc2.session; + bobSession = dec2!.session; + + // Bob -> Alice again + const msg3 = new TextEncoder().encode("Message 3 from Bob"); + const enc3 = ratchetEncrypt(bobSession, msg3, bobSigning.secretKey); + const dec3 = ratchetDecrypt(aliceSession, enc3.header, enc3.ciphertext); + expect(dec3).not.toBeNull(); + + expect(new TextDecoder().decode(dec3!.plaintext)).toBe("Message 3 from Bob"); + }); + + it("should handle multiple sequential messages from same sender", () => { + const messages = ["First", "Second", "Third"]; + let currentBobSession = bobSession; + let currentAliceSession = aliceSession; + + // Bob sends multiple messages + for (const msg of messages) { + const plaintext = new TextEncoder().encode(msg); + const encrypted = ratchetEncrypt(currentBobSession, plaintext, bobSigning.secretKey); + currentBobSession = encrypted.session; + + const decrypted = ratchetDecrypt(currentAliceSession, encrypted.header, encrypted.ciphertext); + expect(decrypted).not.toBeNull(); + expect(new TextDecoder().decode(decrypted!.plaintext)).toBe(msg); + currentAliceSession = decrypted!.session; + } + + expect(currentBobSession.sendingMsgNumber).toBe(3); + expect(currentAliceSession.receivingMsgNumber).toBe(3); + }); + }); + + describe("Binary Codec", () => { + it("should encode and decode payload correctly", () => { + const signature = nacl.randomBytes(64); + const header = { + dh: nacl.randomBytes(32), + pn: 42, + n: 123, + }; + const ciphertext = nacl.randomBytes(100); + + const payload = packageRatchetPayload(signature, header, ciphertext); + const parsed = parseRatchetPayload(payload); + + expect(parsed).not.toBeNull(); + expect(parsed!.version).toBe(0x01); + expect(Buffer.from(parsed!.signature)).toEqual(Buffer.from(signature)); + expect(Buffer.from(parsed!.header.dh)).toEqual(Buffer.from(header.dh)); + expect(parsed!.header.pn).toBe(42); + expect(parsed!.header.n).toBe(123); + expect(Buffer.from(parsed!.ciphertext)).toEqual(Buffer.from(ciphertext)); + }); + + it("should detect ratchet payload format", () => { + const validPayload = new Uint8Array(110); + validPayload[0] = 0x01; // Version byte + + expect(isRatchetPayload(validPayload)).toBe(true); + + // Legacy JSON would start with { (0x7b) + const jsonPayload = new TextEncoder().encode('{"v":1}'); + expect(isRatchetPayload(jsonPayload)).toBe(false); + }); + + it("should reject truncated payloads", () => { + const truncated = new Uint8Array(50); // Less than minimum 105 bytes + truncated[0] = 0x01; + + expect(parseRatchetPayload(truncated)).toBeNull(); + }); + }); + + describe("Authentication", () => { + it("should reject invalid signatures", () => { + const header = { + dh: nacl.randomBytes(32), + pn: 0, + n: 0, + }; + const ciphertext = nacl.randomBytes(50); + const wrongSignature = nacl.randomBytes(64); + const signingKey = createSigningKeyPair(); + + const result = verifyMessageSignature( + wrongSignature, + header, + ciphertext, + signingKey.publicKey + ); + + expect(result).toBe(false); + }); + + it("should reject signatures from wrong key", () => { + const header = { + dh: nacl.randomBytes(32), + pn: 0, + n: 0, + }; + const ciphertext = nacl.randomBytes(50); + const realSigner = createSigningKeyPair(); + const wrongSigner = createSigningKeyPair(); + + // Sign with real key + const headerBytes = new Uint8Array(40); + headerBytes.set(header.dh, 0); + new DataView(headerBytes.buffer).setUint32(32, header.pn, false); + new DataView(headerBytes.buffer).setUint32(36, header.n, false); + + const dataToSign = new Uint8Array(headerBytes.length + ciphertext.length); + dataToSign.set(headerBytes, 0); + dataToSign.set(ciphertext, headerBytes.length); + + const signature = nacl.sign.detached(dataToSign, realSigner.secretKey); + + // Verify with wrong key + const result = verifyMessageSignature( + signature, + header, + ciphertext, + wrongSigner.publicKey // Wrong key! + ); + + expect(result).toBe(false); + }); + }); + + describe("Skip Key Handling", () => { + it("should handle out-of-order messages", () => { + // Setup sessions + const aliceEphemeral = generateDHKeyPair(); + const bobEphemeral = generateDHKeyPair(); + const topics = createTestTopics(); + + let bobSession = initSessionAsResponder({ + myAddress: "0xBob", + contactAddress: "0xAlice", + myResponderEphemeralSecret: bobEphemeral.secretKey, + myResponderEphemeralPublic: bobEphemeral.publicKey, + theirHandshakeEphemeralPubKey: aliceEphemeral.publicKey, + topicOutbound: topics.topicIn, + topicInbound: topics.topicOut, + }); + + let aliceSession = initSessionAsInitiator({ + myAddress: "0xAlice", + contactAddress: "0xBob", + myHandshakeEphemeralSecret: aliceEphemeral.secretKey, + theirResponderEphemeralPubKey: bobEphemeral.publicKey, + topicOutbound: topics.topicOut, + topicInbound: topics.topicIn, + }); + + const bobSigning = createSigningKeyPair(); + + // Bob sends 3 messages + const enc1 = ratchetEncrypt(bobSession, new TextEncoder().encode("Msg 1"), bobSigning.secretKey); + bobSession = enc1.session; + + const enc2 = ratchetEncrypt(bobSession, new TextEncoder().encode("Msg 2"), bobSigning.secretKey); + bobSession = enc2.session; + + const enc3 = ratchetEncrypt(bobSession, new TextEncoder().encode("Msg 3"), bobSigning.secretKey); + bobSession = enc3.session; + + // Alice receives msg 3 first (out of order) + const dec3 = ratchetDecrypt(aliceSession, enc3.header, enc3.ciphertext); + expect(dec3).not.toBeNull(); + expect(new TextDecoder().decode(dec3!.plaintext)).toBe("Msg 3"); + aliceSession = dec3!.session; + + // Verify skip keys were created for msg 1 and 2 + expect(aliceSession.skippedKeys.length).toBe(2); + + // Alice receives msg 1 (using skip key) + const dec1 = ratchetDecrypt(aliceSession, enc1.header, enc1.ciphertext); + expect(dec1).not.toBeNull(); + expect(new TextDecoder().decode(dec1!.plaintext)).toBe("Msg 1"); + aliceSession = dec1!.session; + + // One skip key used + expect(aliceSession.skippedKeys.length).toBe(1); + + // Alice receives msg 2 (using skip key) + const dec2 = ratchetDecrypt(aliceSession, enc2.header, enc2.ciphertext); + expect(dec2).not.toBeNull(); + expect(new TextDecoder().decode(dec2!.plaintext)).toBe("Msg 2"); + aliceSession = dec2!.session; + + // All skip keys used + expect(aliceSession.skippedKeys.length).toBe(0); + }); + }); + + describe("Utility Functions", () => { + it("should prune expired skipped keys", () => { + const session: RatchetSession = { + conversationId: "test", + topicOutbound: "0xabc" as `0x${string}`, + topicInbound: "0xdef" as `0x${string}`, + myAddress: "0x1", + contactAddress: "0x2", + rootKey: new Uint8Array(32), + dhMySecretKey: new Uint8Array(32), + dhMyPublicKey: new Uint8Array(32), + dhTheirPublicKey: new Uint8Array(32), + sendingChainKey: new Uint8Array(32), + sendingMsgNumber: 0, + receivingChainKey: new Uint8Array(32), + receivingMsgNumber: 0, + previousChainLength: 0, + skippedKeys: [ + { dhPubKeyHex: "0x1", msgNumber: 0, messageKey: new Uint8Array(32), createdAt: Date.now() - 1000 }, // Fresh + { dhPubKeyHex: "0x1", msgNumber: 1, messageKey: new Uint8Array(32), createdAt: Date.now() - 100000000 }, // Expired + ], + createdAt: Date.now(), + updatedAt: Date.now(), + epoch: 0, + status: "active", + }; + + const pruned = pruneExpiredSkippedKeys(session, 50000); // 50 second TTL for test + + expect(pruned.skippedKeys.length).toBe(1); + expect(pruned.skippedKeys[0].msgNumber).toBe(0); // Fresh one remains + }); + + it("should convert hex to bytes and back", () => { + const original = nacl.randomBytes(32); + const hex = bytesToHex(original); + const restored = hexToBytes(hex); + + expect(Buffer.from(restored)).toEqual(Buffer.from(original)); + }); + }); +}); \ No newline at end of file diff --git a/packages/sdk/test/utils.test.ts b/packages/sdk/test/utils.test.ts index 3fa6990..1625299 100644 --- a/packages/sdk/test/utils.test.ts +++ b/packages/sdk/test/utils.test.ts @@ -2,7 +2,6 @@ import { describe, it, expect, vi } from "vitest"; import nacl from "tweetnacl"; import { JsonRpcProvider } from "ethers"; -import { sendEncryptedMessage } from "../src/index.js"; import { getNextNonce } from "../src/utils/nonce.js"; import { convertPublicKeyToX25519 } from "../src/utils/x25519.js"; import { isSmartContract1271, parseBindingMessage } from "../src/utils.js"; @@ -45,79 +44,10 @@ describe("Utils Functions", () => { }); }); -describe("sendEncryptedMessage", () => { - it("calls contract.sendMessage with expected parameters", async () => { - const mockSendMessage = vi.fn().mockResolvedValue("txHash"); - const fakeContract = { - sendMessage: mockSendMessage, - } as unknown as LogChainV1; - - const executor = ExecutorFactory.createEOA(fakeContract); - const recipientKey = nacl.box.keyPair(); - const senderSign = nacl.sign.keyPair(); - - await sendEncryptedMessage({ - executor: executor, - topic: "0x" + "ab".repeat(32), - message: "hi", - recipientPubKey: recipientKey.publicKey, - senderAddress: "0xAlice", - senderSignKeyPair: senderSign, - timestamp: 42, - }); - - expect(mockSendMessage).toHaveBeenCalledTimes(1); - - const callArgs = mockSendMessage.mock.calls[0]; - expect(callArgs).toHaveLength(4); // ciphertext, topic, timestamp, nonce - expect(typeof callArgs[1]).toBe("string"); - expect(typeof callArgs[2]).toBe("number"); - expect(typeof callArgs[3]).toBe("bigint"); - }); - - it("generates different nonces for different calls", async () => { - const mockSendMessage = vi.fn().mockResolvedValue("txHash"); - const fakeContract = { - sendMessage: mockSendMessage, - } as unknown as LogChainV1; - - const executor = ExecutorFactory.createEOA(fakeContract); - const recipientKey = nacl.box.keyPair(); - const senderSign = nacl.sign.keyPair(); - - // send two messages from same sender - await sendEncryptedMessage({ - executor: executor, - topic: "0x" + "ab".repeat(32), - message: "message 1", - recipientPubKey: recipientKey.publicKey, - senderAddress: "0xAlice", - senderSignKeyPair: senderSign, - timestamp: 42, - }); - - await sendEncryptedMessage({ - executor: executor, - topic: "0x" + "ab".repeat(32), - message: "message 2", - recipientPubKey: recipientKey.publicKey, - senderAddress: "0xAlice", - senderSignKeyPair: senderSign, - timestamp: 43, - }); - - expect(mockSendMessage).toHaveBeenCalledTimes(2); - - const firstNonce = mockSendMessage.mock.calls[0][3]; - const secondNonce = mockSendMessage.mock.calls[1][3]; - expect(secondNonce).toBe(firstNonce + 1n); - }); -}); describe("Unified Keys Utilities", () => { it("should handle unified key operations", () => { expect(typeof isSmartContract1271).toBe("function"); - expect(typeof sendEncryptedMessage).toBe("function"); }); }); diff --git a/plan.md b/plan.md new file mode 100644 index 0000000..6c55dc3 --- /dev/null +++ b/plan.md @@ -0,0 +1,205 @@ +# Verbeth SDK: Double Ratchet Implementation Plan + +## Overview + +This plan implements Signal-style Double Ratchet for bilateral forward secrecy. Compromising identity keys never allows decrypting past messagesโ€”not even message 0. + +**Scope**: Core Double Ratchet only. Topic ratcheting and post-quantum are separate future phases. + +--- + +## 1. Key Design Decisions + +### 1.1 Ephemeral-Only Initial Secret + +**Traditional Signal**: Initial secret includes identity keys โ†’ identity compromise exposes message 0. + +**Verbeth**: Initial secret is `DH(AliceEphemeral, BobRatchetEphemeral)` ONLY. +- No identity keys in initial secret +- Authentication via Ed25519 signatures on every message +- Identity compromise never decrypts any messages + +### 1.2 Two-Keypair Handshake (Unlinkability) + +Bob's `respondToHandshake` generates TWO separate keypairs: + +| Keypair | Purpose | Location | +|---------|---------|----------| +| `tagKeyPair (R, r)` | Compute `inResponseTo` tag | `R` on-chain as `responderEphemeralR` | +| `ratchetKeyPair` | First DH ratchet key | Public key inside encrypted payload | + +**Why**: Single keypair would let observers link `HandshakeResponse.R` to first message's DH header. With separation, no on-chain link exists between handshake and conversation. + +### 1.3 Session Keyed by Topics + +Sessions keyed by `conversationId = keccak256(sort([topicOut, topicIn]))`, not addresses. + +```typescript +interface RatchetSession { + conversationId: string; + topicOutbound: `0x${string}`; + topicInbound: `0x${string}`; + // ... ratchet state +} +``` + +Lookup: `session where topicInbound === event.topic` + +### 1.4 Two-Phase Commit (Sequential Blocking) + +**Problem**: Advancing ratchet state before tx confirms risks permanent desync on failure. + +**Solution**: Immutable operations + pending state with sequential blocking. + +``` +1. Check: pending outbound exists? โ†’ Block send +2. Load session +3. Compute (nextState, header, ciphertext) โ€” DON'T save +4. Create PendingOutbound { prevState, nextState, txHash } +5. Send transaction +6. On SUCCESS: commit nextState, delete pending +7. On FAILURE: discard pending, session unchanged +``` + +**Constraint**: User cannot send message N+1 until transaction N confirms. This prevents dependent pending states. + +### 1.5 Auth-Before-Ratchet (DoS Protection) + +**Attack**: Malicious `pn=999999, n=999999` forces millions of key derivations. + +**Defense**: Verify Ed25519 signature BEFORE any ratchet work. + +``` +1. Parse sig + header + ciphertext +2. Verify Ed25519(sig, header || ct, contact.signingPubKey) +3. IF invalid: reject (O(1) cost) +4. THEN attempt ratchet decrypt +``` + +### 1.6 Binary Encoding + +``` +Offset โ”‚ Size โ”‚ Field +โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ +0 โ”‚ 1 โ”‚ Version (0x01) +1 โ”‚ 64 โ”‚ Ed25519 signature +65 โ”‚ 32 โ”‚ DH ratchet public key +97 โ”‚ 4 โ”‚ pn (uint32 BE) +101 โ”‚ 4 โ”‚ n (uint32 BE) +105 โ”‚ var โ”‚ Ciphertext (nonce + AEAD) +``` + +Fixed overhead: ~105 bytes (vs ~200+ for JSON+base64). + +### 1.7 Skipped Keys: Reorg Tolerance, Not Offline Catch-Up + +**Common misconception**: Skipped keys handle offline periods. + +**Reality**: +- **Offline catch-up**: Process chain logs in order โ†’ chain key advances sequentially โ†’ no skipped keys +- **Skipped keys**: Handle block reorgs and out-of-order RPC responses + +| Concept | Purpose | +|---------|---------| +| Chain key derivation | Sequential catch-up after offline | +| Skipped keys | Out-of-order delivery tolerance | + +Bounds: +- `MAX_STORED_SKIPPED_KEYS = 1000` (memory limit) +- `MAX_SKIPPED_KEYS_AGE_MS = 24h` (TTL) + +--- + +## 2. State Loss & Session Reset + +**Tradeoff**: Forward secrecy means lost local state = lost messages. + +**Solution**: Session Reset Protocol +- User initiates new handshake to existing contact +- Creates new session with new topics +- Old session becomes `inactive_reset` (frozen, not deleted) +- Peer sees "Alice requests new session" notification + +**UX**: "Session recovered - messages before [date] unavailable" + +--- + +## 3. Implementation Milestones + +No need to provide migration or backward compatibility. + +### Milestone 1: SDK Ratchet Core โœ… +Pure crypto module, fully testable without blockchain/DB. + +**Files**: `ratchet/{types,kdf,session,encrypt,decrypt,codec,auth}.ts` + +**Functions**: +- `initSessionAsResponder()`, `initSessionAsInitiator()` +- `ratchetEncrypt()`, `ratchetDecrypt()` +- `packageRatchetPayload()`, `parseRatchetPayload()`, `isRatchetPayload()` +- `verifyMessageSignature()` + +### Milestone 2: Handshake + Persistence +Wire ratchet into handshake; sessions persist to IndexedDB. + +**SDK Changes**: +- `send.ts`: Return two keypairs (tag + ratchet) from `respondToHandshake()` +- `VerbethClient.tsacceptHandshake()` returns ephemeral keys; `sendMessage()` REMOVED +- `crypto.ts` Mark `encryptMessage`/`decryptMessage` as `@deprecated` + +**App Changes**: +- `types.ts`: Add `StoredRatchetSession`, `PendingOutbound` +- `schema.ts`: Add `ratchetSessions`, `pendingOutbound` tables +- `DbService.ts`: Add ~8 ratchet methods +- `useChatActions.ts`: Create session on `acceptHandshake` +- `useMessageProcessor.ts`: Create session on `HandshakeResponse` + +**Key**: Ratchet key comes from decrypted payload, NOT on-chain `responderEphemeralR`. + +### Milestone 3: Encrypted Messaging +Full send/receive with two-phase commit. + +**App Changes**: +- `useChatActions.ts`: Rewrite `sendMessageToContact()` with sequential blocking +- `useMessageProcessor.ts`: Auth-first ratchet decrypt for incoming + +**Test Cases**: +- Send โ†’ pending created โ†’ confirmed โ†’ session committed +- Send failure โ†’ session unchanged +- Sequential blocking โ†’ 2nd message blocked while 1st pending +- Invalid signature โ†’ rejected, no ratchet work + +### Post-M3: Session Reset Protocol +Separate PR for recovery flow. + +--- + +## 4. Success Criteria + +**Cryptographic**: +- [ ] Identity key compromise never decrypts past messages (including message 0) +- [ ] Post-compromise security: session recovers after key compromise +- [ ] DoS resistance: unauthenticated messages rejected in O(1) +- [ ] Unlinkability: on-chain R โ‰  message DH headers + +**State Management**: +- [ ] Two-phase commit prevents desync on tx failure +- [ ] Sequential blocking: max one pending per conversation +- [ ] Session keyed by topics (not addresses) +- [ ] Confirmation matching by txHash + +**Resilience**: +- [ ] Long offline periods: process in order, no skipped keys needed +- [ ] Skipped keys only for reorg tolerance (24h TTL) +- [ ] Session reset creates new topics (doesn't reuse old) + +--- + +## 5. What's NOT in Scope + +| Feature | Phase | +|---------|-------| +| Topic ratcheting | Phase 2 | +| Post-quantum (ML-KEM) | Phase 3 | +| Cloud sync | Future | +| Export/import | Future | \ No newline at end of file From 5e2bf3b90f220965542851307e4156c8c98be615 Mon Sep 17 00:00:00 2001 From: Marco Esposito Date: Sun, 11 Jan 2026 20:03:42 +0100 Subject: [PATCH 09/51] handle queuing + simulation tests --- apps/demo/src/App.tsx | 173 +++- apps/demo/src/components/InitialForm.tsx | 2 +- apps/demo/src/hooks/useChatActions.ts | 238 ++--- apps/demo/src/hooks/useMessageProcessor.ts | 928 +++--------------- apps/demo/src/hooks/useMessageQueue.ts | 217 ++-- apps/demo/src/services/DbService.ts | 26 +- .../src/services/EventProcessorService.ts | 653 ++++++++++++ apps/demo/src/types.ts | 8 +- apps/docs/double-ratchet.md | 735 +++++--------- packages/sdk/test/executor.test.ts | 1 - packages/sdk/test/ratchet.test.ts | 17 +- packages/sdk/test/simulation.test.ts | 709 +++++++++++++ plan.md | 297 ++++-- 13 files changed, 2378 insertions(+), 1626 deletions(-) create mode 100644 apps/demo/src/services/EventProcessorService.ts create mode 100644 packages/sdk/test/simulation.test.ts diff --git a/apps/demo/src/App.tsx b/apps/demo/src/App.tsx index cddb6f1..609b1e5 100644 --- a/apps/demo/src/App.tsx +++ b/apps/demo/src/App.tsx @@ -1,5 +1,5 @@ import { useEffect, useRef, useState, useCallback } from "react"; -import { Fingerprint } from "lucide-react"; +import { Fingerprint, RotateCcw, X } from "lucide-react"; import { ConnectButton } from '@rainbow-me/rainbowkit'; import { useAccount, useWalletClient } from 'wagmi'; import { useRpcClients } from './rpc.js'; @@ -12,6 +12,7 @@ import { LOGCHAIN_SINGLETON_ADDR, CONTRACT_CREATION_BLOCK, Contact, + Message, } from './types.js'; import { InitialForm } from './components/InitialForm.js'; import { SideToastNotifications } from './components/SideToastNotification.js'; @@ -123,6 +124,8 @@ export default function App() { pendingHandshakes, contacts, addMessage, + updateMessageStatus, + removeMessage, removePendingHandshake, updateContact, processEvents @@ -152,12 +155,17 @@ export default function App() { const { sendHandshake, acceptHandshake, - sendMessageToContact + sendMessageToContact, + retryFailedMessage, // NEW: Retry action + cancelQueuedMessage, // NEW: Cancel action + getContactQueueStatus, // NEW: Queue status } = useChatActions({ verbethClient, addLog, updateContact: async (contact: Contact) => { await updateContact(contact); }, addMessage: async (message: any) => { await addMessage(message); }, + updateMessageStatus, // NEW: Pass to useChatActions + removeMessage, // NEW: Pass to useChatActions removePendingHandshake: async (id: string) => { await removePendingHandshake(id); }, setSelectedContact, setLoading, @@ -219,6 +227,98 @@ export default function App() { setShowHandshakeForm(!ready || !currentlyConnected || contacts.length === 0 || needsIdentityCreation); }, [ready, isConnected, contacts.length, needsIdentityCreation]); + // Helper to render message with status and retry/cancel actions + const renderMessage = (msg: Message) => { + const isOutgoing = msg.direction === 'outgoing'; + const isFailed = msg.status === 'failed'; + const isPending = msg.status === 'pending'; + + return ( +
+
+

+ {msg.type === "system" && msg.verified !== undefined && ( + msg.verified ? ( + + + + Identity proof verified + + + ) : ( + + + + Identity proof not verified + + + ) + )} + + {msg.type === "system" && msg.decrypted ? ( + <> + {msg.decrypted.split(":")[0]}: + {msg.decrypted.split(":").slice(1).join(":")} + + ) : ( + msg.decrypted || msg.ciphertext + )} +

+ +
+ + {new Date(msg.timestamp).toLocaleTimeString()} + + {isOutgoing && ( + + {msg.status === 'confirmed' ? 'โœ“โœ“' : + msg.status === 'failed' ? 'โœ—' : + msg.status === 'pending' ? 'โœ“' : '?'} + + )} +
+
+ + {/* Failed message actions */} + {isFailed && isOutgoing && ( +
+ Failed to send + + +
+ )} +
+ ); + }; + + // Get queue status for selected contact + const queueStatus = selectedContact ? getContactQueueStatus(selectedContact) : null; return (
@@ -409,57 +509,7 @@ export default function App() { ); }) .sort((a, b) => a.timestamp - b.timestamp) - .map((msg) => ( -
-

- {msg.type === "system" && msg.verified !== undefined && ( - msg.verified ? ( - - - - Identity proof verified - - - ) : ( - - - - Identity proof not verified - - - ) - )} - - {msg.type === "system" && msg.decrypted ? ( - <> - {msg.decrypted.split(":")[0]}: - {msg.decrypted.split(":").slice(1).join(":")} - - ) : ( - msg.decrypted || msg.ciphertext - )} -

- -
- - {new Date(msg.timestamp).toLocaleTimeString()} - - {msg.direction === 'outgoing' && ( - - {msg.status === 'confirmed' ? 'โœ“โœ“' : - msg.status === 'failed' ? 'โœ—' : - msg.status === 'pending' ? 'โœ“' : '?'} - - )} -
-
- ))} + .map(renderMessage)} {messages.filter(m => { const currentAddress = address; if (!currentAddress || !selectedContact?.address) return false; @@ -476,6 +526,23 @@ export default function App() { )}
+ {/* Queue Status Indicator */} + {queueStatus && queueStatus.queueLength > 0 && ( +
+ {queueStatus.isProcessing ? ( + <> + + Sending {queueStatus.queueLength} message{queueStatus.queueLength > 1 ? 's' : ''}... + + ) : ( + <> + ๐Ÿ“จ + {queueStatus.queueLength} message{queueStatus.queueLength > 1 ? 's' : ''} queued + + )} +
+ )} + {/* Message Input */} {selectedContact.status === 'established' && selectedContact.identityPubKey && (
diff --git a/apps/demo/src/components/InitialForm.tsx b/apps/demo/src/components/InitialForm.tsx index 7d32a1f..f61800d 100644 --- a/apps/demo/src/components/InitialForm.tsx +++ b/apps/demo/src/components/InitialForm.tsx @@ -72,7 +72,7 @@ export function InitialForm({ onClick={onBackToChats} className="text-sm text-gray-400 hover:text-white flex items-center gap-1 transition-colors" > - โ† Back to chats + Go to chats ) : ( diff --git a/apps/demo/src/hooks/useChatActions.ts b/apps/demo/src/hooks/useChatActions.ts index 1571224..77d77a8 100644 --- a/apps/demo/src/hooks/useChatActions.ts +++ b/apps/demo/src/hooks/useChatActions.ts @@ -1,12 +1,9 @@ // src/hooks/useChatActions.ts /** - * Chat actions hook with Double Ratchet integration. + * Chat actions hook with Double Ratchet integration and Message Queue. * - * Key changes from legacy: - * - acceptHandshake now creates ratchet session - * - sendMessageToContact uses ratchet encryption with two-phase commit - * - Sequential blocking: only one pending message per conversation + * UPDATED: Added session cache invalidation for when sessions are reset externally. */ import { useCallback } from "react"; @@ -14,24 +11,22 @@ import { hexlify } from "ethers"; import { pickOutboundTopic, VerbethClient, - // Ratchet imports initSessionAsResponder, - ratchetEncrypt, - packageRatchetPayload, } from "@verbeth/sdk"; import { dbService } from "../services/DbService.js"; import { Contact, - PendingOutbound, generateTempMessageId, - serializeRatchetSession, } from "../types.js"; +import { useMessageQueue } from "./useMessageQueue.js"; interface UseChatActionsProps { verbethClient: VerbethClient | null; addLog: (message: string) => void; updateContact: (contact: Contact) => Promise; addMessage: (message: any) => Promise; + updateMessageStatus: (id: string, status: "pending" | "confirmed" | "failed", error?: string) => Promise; + removeMessage: (id: string) => Promise; removePendingHandshake: (id: string) => Promise; setSelectedContact: (contact: Contact | null) => void; setLoading: (loading: boolean) => void; @@ -44,6 +39,8 @@ export const useChatActions = ({ addLog, updateContact, addMessage, + updateMessageStatus, + removeMessage, removePendingHandshake, setSelectedContact, setLoading, @@ -51,6 +48,22 @@ export const useChatActions = ({ setRecipientAddress, }: UseChatActionsProps) => { + const { + queueMessage, + retryMessage, + cancelMessage, + getQueueStatus, + invalidateSessionCache, + clearAllQueues, + } = useMessageQueue({ + verbethClient, + addLog, + addMessage, + updateMessageStatus, + removeMessage, + updateContact, + }); + /** * Send a handshake to initiate contact. * Stores ephemeral secret for ratchet session init when response arrives. @@ -74,12 +87,10 @@ export const useChatActions = ({ message ); - // Store ephemeral secret for ratchet session init when response arrives const newContact: Contact = { address: recipientAddress, ownerAddress: verbethClient.userAddress, status: "handshake_sent", - // Store ephemeral secret (hex) for later use in initSessionAsInitiator handshakeEphemeralSecret: hexlify(ephemeralKeyPair.secretKey), lastMessage: message, lastTimestamp: Date.now(), @@ -137,10 +148,7 @@ export const useChatActions = ({ ] ); - /** - * Accept a handshake and create ratchet session. - * This is where the responder's ratchet session is initialized. - */ + const acceptHandshake = useCallback( async (handshake: any, responseMessage: string) => { if (!verbethClient) { @@ -149,7 +157,6 @@ export const useChatActions = ({ } try { - // Accept handshake - now returns ephemeral keys for ratchet const { tx, duplexTopics, @@ -161,11 +168,9 @@ export const useChatActions = ({ responseMessage ); - // Determine topics from responder's perspective - const topicOutbound = pickOutboundTopic(false, duplexTopics); // Responder - const topicInbound = pickOutboundTopic(true, duplexTopics); // Responder + const topicOutbound = pickOutboundTopic(false, duplexTopics); + const topicInbound = pickOutboundTopic(true, duplexTopics); - // Initialize ratchet session as responder const ratchetSession = initSessionAsResponder({ myAddress: verbethClient.userAddress, contactAddress: handshake.sender, @@ -176,10 +181,8 @@ export const useChatActions = ({ topicInbound, }); - // Save ratchet session await dbService.saveRatchetSession(ratchetSession); - // Update contact with session info const newContact: Contact = { address: handshake.sender, ownerAddress: verbethClient.userAddress, @@ -240,10 +243,6 @@ export const useChatActions = ({ ] ); - /** - * Send an encrypted message using Double Ratchet. - * Implements two-phase commit with sequential blocking. - */ const sendMessageToContact = useCallback( async (contact: Contact, messageText: string) => { if (!verbethClient) { @@ -256,146 +255,77 @@ export const useChatActions = ({ return; } - // 1. SEQUENTIAL BLOCKING: Check for existing pending outbound - const existingPending = await dbService.getPendingOutboundByConversation( - contact.conversationId - ); - if (existingPending.length > 0) { - addLog("โณ Please wait for previous message to confirm before sending another"); - return; + const messageId = await queueMessage(contact, messageText); + + if (messageId) { + setMessage(""); } + }, + [verbethClient, addLog, queueMessage, setMessage] + ); - setLoading(true); - const pendingId = generateTempMessageId(); - - try { - // 2. Load ratchet session - const session = await dbService.getRatchetSessionByConversation( - contact.conversationId - ); - if (!session) { - addLog("โœ— No ratchet session for this contact"); - setLoading(false); - return; - } - - // 3. Encrypt with ratchet (returns new session state, doesn't mutate) - const plaintext = new TextEncoder().encode(messageText); - const { session: nextSession, header, ciphertext, signature } = ratchetEncrypt( - session, - plaintext, - verbethClient.identityKeyPairInstance.signingSecretKey - ); - - // 4. Package binary payload - const payload = packageRatchetPayload(signature, header, ciphertext); - const payloadHex = hexlify(payload); - - // 5. Create pending record (two-phase commit) - const pending: PendingOutbound = { - id: pendingId, - conversationId: session.conversationId, - topic: session.topicOutbound, - payloadHex, - plaintext: messageText, - sessionStateBefore: JSON.stringify(serializeRatchetSession(session)), - sessionStateAfter: JSON.stringify(serializeRatchetSession(nextSession)), - createdAt: Date.now(), - txHash: null, - status: "preparing", - }; - await dbService.savePendingOutbound(pending); - - // 6. Add optimistic UI message - await addMessage({ - id: pendingId, - topic: session.topicOutbound, - sender: verbethClient.userAddress, - recipient: contact.address, - ciphertext: "", - timestamp: Date.now(), - blockTimestamp: Date.now(), - blockNumber: 0, - direction: "outgoing" as const, - decrypted: messageText, - read: true, - nonce: nextSession.sendingMsgNumber - 1, - dedupKey: `pending-${pendingId}`, - type: "text" as const, - ownerAddress: verbethClient.userAddress, - status: "pending" as const, - }); - - // 7. Send transaction - const timestamp = Math.floor(Date.now() / 1000); - const nonce = nextSession.sendingMsgNumber - 1; - - await dbService.updatePendingOutboundStatus(pendingId, "submitted"); - - // Send the binary payload as bytes - // The executor.sendMessage expects: (payload: Uint8Array | bytes, topic, timestamp, nonce) - const tx = await verbethClient.executorInstance.sendMessage( - payload, // Raw binary payload - session.topicOutbound, // Topic (bytes32 hex) - timestamp, // Unix timestamp - BigInt(nonce) // Convert to bigint - ); - - // Update with txHash for confirmation matching - await dbService.updatePendingOutboundStatus(pendingId, "submitted", tx.hash); - - addLog( - `Message sent to ${contact.address.slice(0, 8)}...: "${messageText}" (tx: ${tx.hash})` - ); - // Update contact last message - const updatedContact: Contact = { - ...contact, - lastMessage: messageText, - lastTimestamp: Date.now(), - }; - await updateContact(updatedContact); + // here the message number will be different from the original attempt. + const retryFailedMessage = useCallback( + async (messageId: string) => { + const success = await retryMessage(messageId); + if (!success) { + addLog(`โœ— Could not retry message`); + } + }, + [retryMessage, addLog] + ); - // Note: Actual session state commit happens in useMessageProcessor - // when we see the on-chain confirmation + /** + * Cancel a queued message. + */ + const cancelQueuedMessage = useCallback( + async (messageId: string) => { + const success = await cancelMessage(messageId); + if (!success) { + addLog(`โœ— Could not cancel message`); + } + }, + [cancelMessage, addLog] + ); - } catch (error) { - console.error("Failed to send message:", error); - - // Rollback: delete pending record, keep old session state - try { - await dbService.deletePendingOutbound(pendingId); - } catch (cleanupError) { - console.error("Failed to cleanup pending outbound:", cleanupError); - } - - try { - await dbService.updateMessage(pendingId, { status: "failed" }); - } catch (updateError) { - console.error("Failed to mark message as failed:", updateError); - } + /** + * Get the queue status for a contact. + */ + const getContactQueueStatus = useCallback( + (contact: Contact) => { + if (!contact.conversationId) { + return { queueLength: 0, isProcessing: false, pendingMessages: [] }; + } + return getQueueStatus(contact.conversationId); + }, + [getQueueStatus] + ); - addLog( - `โœ— Failed to send message: ${ - error instanceof Error ? error.message : "Unknown error" - }` - ); - } finally { - setLoading(false); + /** + * Invalidate session cache for a contact. + * Call this when a session is reset or updated externally. + */ + const invalidateContactSessionCache = useCallback( + (contact: Contact) => { + if (contact.conversationId) { + invalidateSessionCache(contact.conversationId); } }, - [ - verbethClient, - addLog, - addMessage, - updateContact, - setLoading, - ] + [invalidateSessionCache] ); return { + // Existing actions sendHandshake, acceptHandshake, sendMessageToContact, + + // Queue-related actions + retryFailedMessage, + cancelQueuedMessage, + getContactQueueStatus, + invalidateContactSessionCache, + clearAllQueues, }; }; \ No newline at end of file diff --git a/apps/demo/src/hooks/useMessageProcessor.ts b/apps/demo/src/hooks/useMessageProcessor.ts index 35c615c..fb150af 100644 --- a/apps/demo/src/hooks/useMessageProcessor.ts +++ b/apps/demo/src/hooks/useMessageProcessor.ts @@ -1,38 +1,31 @@ -// apps/demo/src/hooks/useMessageProcessor.ts +// src/hooks/useMessageProcessor.ts -import { useState, useEffect, useCallback, useRef } from "react"; -import { AbiCoder, getBytes } from "ethers"; -import { - type IdentityContext, - parseHandshakePayload, - parseBindingMessage, - verifyHandshakeIdentity, - IdentityKeyPair, - decodeUnifiedPubKeys, - verifyAndExtractHandshakeResponseKeys, - deriveDuplexTopics, - verifyDerivedDuplexTopics, - computeTagFromInitiator, - pickOutboundTopic, - // Ratchet imports - initSessionAsInitiator, - ratchetDecrypt, - parseRatchetPayload, - isRatchetPayload, - verifyMessageSignature, -} from "@verbeth/sdk"; +/** + * Message Processor Hook. + * + * Manages messaging state (messages, contacts, pendingHandshakes) and + * orchestrates event processing via EventProcessorService. + * + * The service handles decoding, verification, decryption, and persistence. + * This hook just applies the results to React state. + */ + +import { useState, useEffect, useCallback } from "react"; +import { type IdentityContext, type IdentityKeyPair, type RatchetSession } from "@verbeth/sdk"; import { dbService } from "../services/DbService.js"; +import { + processHandshakeEvent, + processHandshakeResponseEvent, + processMessageEvent, + persistSessionCache, +} from "../services/EventProcessorService.js"; import { Contact, Message, PendingHandshake, ProcessedEvent, MessageProcessorResult, - MessageDirection, - MessageType, - ContactStatus, - generateTempMessageId, } from "../types.js"; interface UseMessageProcessorProps { @@ -45,22 +38,6 @@ interface UseMessageProcessorProps { onLog: (message: string) => void; } -/** - * useMessageProcessor - * - * - Maintains a FIFO of pending outgoing messages per topic in-memory. - * - Enqueue on send (and on DB restore), dequeue on on-chain confirmation. - * - This guarantees correct matching when multiple messages are sent before the first confirms. - * - * - On confirmation: - * 1) Prefer the in-memory FIFO (topic -> queue.shift()). - * 2) If missing (refresh / multi-tab / race), fallback to DB.findPendingMessage(...). - * 3) If still missing, synthesize a confirmed outgoing from the log (id = txHash-logIndex). - * - * - Dedup logic lives in DbService (skip dedup for pending; dedup confirmed by sender:topic:nonce). - * - NB: listener should query only inbound topics; confirmations are filtered by sender=me. - */ - export const useMessageProcessor = ({ readProvider, address, @@ -69,35 +46,11 @@ export const useMessageProcessor = ({ identityContext, onLog, }: UseMessageProcessorProps): MessageProcessorResult => { + const [messages, setMessages] = useState([]); - const [pendingHandshakes, setPendingHandshakes] = useState< - PendingHandshake[] - >([]); + const [pendingHandshakes, setPendingHandshakes] = useState([]); const [contacts, setContacts] = useState([]); - // Track pending outgoing per topic in-memory (FIFO queues) - const pendingMessagesRef = useRef>(new Map()); - - const hexToUint8Array = (hex: string): Uint8Array => { - const cleanHex = hex.replace("0x", ""); - return new Uint8Array( - cleanHex.match(/.{1,2}/g)?.map((byte) => parseInt(byte, 16)) || [] - ); - }; - - const generateMessageId = ( - txHash: string, - log: { logIndex?: number; index?: number } - ): string => { - const idx = - typeof log.logIndex !== "undefined" - ? log.logIndex - : typeof log.index !== "undefined" - ? log.index - : 0; - return `${txHash}-${idx}`; - }; - const loadFromDatabase = useCallback(async () => { if (!address) return; @@ -112,755 +65,176 @@ export const useMessageProcessor = ({ setMessages(dbMessages); setPendingHandshakes(dbPendingHandshakes); - // Restore pending outgoing messages into the in-memory Map - pendingMessagesRef.current.clear(); - dbMessages - .filter( - (msg) => - msg.status === "pending" && - msg.direction === "outgoing" && - msg.type === "text" && - msg.topic - ) - .forEach((msg) => { - const q = pendingMessagesRef.current.get(msg.topic) ?? []; - q.push(msg); - pendingMessagesRef.current.set(msg.topic, q); - onLog( - `Restored pending message for topic ${msg.topic.slice( - 0, - 10 - )}...: "${msg.decrypted?.slice(0, 30)}..."` - ); - }); - onLog( - `Loaded from DB for ${address.slice(0, 8)}...: ${ - dbContacts.length - } contacts, ${dbMessages.length} messages (${ - pendingMessagesRef.current.size - } pending), ${dbPendingHandshakes.length} pending handshakes` + `Loaded from DB for ${address.slice(0, 8)}...: ${dbContacts.length} contacts, ${dbMessages.length} messages, ${dbPendingHandshakes.length} pending handshakes` ); } catch (error) { onLog(`โœ— Failed to load from database: ${error}`); } }, [address, onLog]); - const processHandshakeLog = useCallback( - async (event: ProcessedEvent): Promise => { - if (!address || !readProvider) return; - - try { - const log = event.rawLog; - const abiCoder = new AbiCoder(); - const decoded = abiCoder.decode(["bytes", "bytes", "bytes"], log.data); - const [ - identityPubKeyBytes, - ephemeralPubKeyBytes, - plaintextPayloadBytes, - ] = decoded; - - const unifiedPubKeys = hexToUint8Array(identityPubKeyBytes); - const decodedKeys = decodeUnifiedPubKeys(unifiedPubKeys); - - if (!decodedKeys) { - onLog("โœ— Failed to decode unified public keys"); - return; - } - - const identityPubKey = decodedKeys.identityPubKey; - const signingPubKey = decodedKeys.signingPubKey; - const ephemeralPubKey = hexToUint8Array(ephemeralPubKeyBytes); - const plaintextPayload = new TextDecoder().decode( - hexToUint8Array(plaintextPayloadBytes) - ); - - const cleanSenderAddress = "0x" + log.topics[2].slice(-40); - const recipientHash = log.topics[1]; - - let handshakeContent; - let hasValidIdentityProof = false; - - try { - handshakeContent = parseHandshakePayload(plaintextPayload); - hasValidIdentityProof = true; - } catch (error) { - handshakeContent = { - plaintextPayload: plaintextPayload, - identityProof: null, - }; - hasValidIdentityProof = false; - } - - let isVerified = false; - if (hasValidIdentityProof) { - try { - const handshakeEvent = { - recipientHash, - sender: cleanSenderAddress, - pubKeys: identityPubKeyBytes, - ephemeralPubKey: ephemeralPubKeyBytes, - plaintextPayload: plaintextPayload, - }; - - // Pass identityContext for domain & chain bound verification - isVerified = await verifyHandshakeIdentity( - handshakeEvent, - readProvider, - identityContext - ); - } catch (error) { - onLog(`Failed to verify handshake identity: ${error}`); - } - } - - // Extract EOA (identity) from binding message - let identityAddress = cleanSenderAddress; // fallback to event sender - if (hasValidIdentityProof && handshakeContent.identityProof?.message) { - try { - const parsed = parseBindingMessage( - handshakeContent.identityProof.message - ); - if (parsed.address) { - identityAddress = parsed.address; - } - } catch (e) {} - } - - const pendingHandshake: PendingHandshake = { - id: log.transactionHash, - ownerAddress: address, - sender: identityAddress, // EOA (identity) - emitterAddress: cleanSenderAddress, // Safe or EOA (event sender) - identityPubKey, - signingPubKey, - ephemeralPubKey, - message: handshakeContent.plaintextPayload, - timestamp: Date.now(), - blockNumber: log.blockNumber, - verified: isVerified, - }; - - await dbService.savePendingHandshake(pendingHandshake); - - setPendingHandshakes((prev) => { - const existing = prev.find((h) => h.id === pendingHandshake.id); - if (existing) return prev; - return [...prev, pendingHandshake]; - }); - - const handshakeMessage: Message = { - id: generateTempMessageId(), - topic: "", - sender: identityAddress, - recipient: address, - ciphertext: "", - timestamp: Date.now(), - blockTimestamp: Date.now(), - blockNumber: log.blockNumber, - direction: "incoming" as const, - decrypted: `Request received: "${handshakeContent.plaintextPayload}"`, - read: true, - nonce: 0, - dedupKey: `handshake-received-${log.transactionHash}`, - type: "system" as const, - ownerAddress: address, - status: "confirmed" as const, - verified: isVerified, - }; - - await dbService.saveMessage(handshakeMessage); - setMessages((prev) => [...prev, handshakeMessage]); - - onLog( - `๐Ÿ“จ Handshake received from ${identityAddress.slice(0, 8)}... ${ - isVerified ? "โœ…" : "โš ๏ธ" - }: "${handshakeContent.plaintextPayload}"` - ); - } catch (error) { - onLog(`โœ— Failed to process handshake log: ${error}`); - } - }, - [address, readProvider, identityContext, onLog] - ); - - const processHandshakeResponseLog = useCallback( - async (event: ProcessedEvent): Promise => { - if (!address || !readProvider) return; - - try { - const log = event.rawLog; - const abiCoder = new AbiCoder(); - const [responderEphemeralRBytes, ciphertextBytes] = abiCoder.decode( - ["bytes32", "bytes"], - log.data - ); - - const ciphertextJson = new TextDecoder().decode( - hexToUint8Array(ciphertextBytes) - ); - - const responder = "0x" + log.topics[2].slice(-40); - const inResponseTo = log.topics[1]; - - const currentContacts = await dbService.getAllContacts(address); - - onLog( - `๐Ÿ” Debug: Loaded ${currentContacts.length} contacts from DB for handshake response` - ); - - // Use matchedContactAddress from listener (tag-based matching) - // This works regardless of whether responder is EOA or Safe - const contact = currentContacts.find( - (c) => - c.address.toLowerCase() === - event.matchedContactAddress?.toLowerCase() && - c.status === "handshake_sent" - ); - - if (!contact || !contact.handshakeEphemeralSecret) { - onLog( - `โ“ Received handshake response but no matching pending contact found (responder: ${responder.slice( - 0, - 8 - )}...)` - ); - return; - } - - const responseEvent = { - inResponseTo, - responder, - responderEphemeralR: responderEphemeralRBytes, - ciphertext: ciphertextJson, - }; - - // Pass identityContext for domain & chain bound verification - const result = await verifyAndExtractHandshakeResponseKeys( - responseEvent, - getBytes(contact.handshakeEphemeralSecret!), - readProvider, - identityContext - ); - - if (!result.isValid || !result.keys) { - onLog( - `โŒ Failed to verify handshake response from ${contact.address.slice( - 0, - 8 - )}... - invalid signature or tag mismatch` - ); - return; - } - - const { identityPubKey, signingPubKey, ephemeralPubKey, note } = - result.keys; - - if (!identityKeyPair) { - onLog(`โŒ Cannot verify duplex topics: identityKeyPair is null`); - return; - } + // =========================================================================== + // Event Processing Orchestration + // =========================================================================== + const processEvents = useCallback( + async (events: ProcessedEvent[]) => { + if (!address) return; - const saltHex = computeTagFromInitiator( - getBytes(contact.handshakeEphemeralSecret!), // Alice's ephemeral secret (hex โ†’ Uint8Array) - hexToUint8Array(responderEphemeralRBytes) // Bob's public R from the response event - ); - const salt = Uint8Array.from(Buffer.from(saltHex.slice(2), "hex")); - - const duplexTopics = deriveDuplexTopics( - identityKeyPair.secretKey, // Alice's identity secret key - identityPubKey, // Bob's identity public key (from response) - salt - ); - const isValidTopics = verifyDerivedDuplexTopics({ - myIdentitySecretKey: identityKeyPair.secretKey, - theirIdentityPubKey: identityPubKey, - topicInfo: { - out: duplexTopics.topicOut, - in: duplexTopics.topicIn, - chk: duplexTopics.checksum, - }, - salt, - }); - if (!isValidTopics) { - onLog( - `โŒ Invalid duplex topics checksum for ${contact.address.slice( - 0, - 8 - )}...` - ); - return; - } + // Session cache for batch processing + const batchSessionCache = new Map(); - onLog( - `โœ… Handshake response verified from ${contact.address.slice( - 0, - 8 - )}...` - ); - - // Determine topics from initiator's perspective - const topicOutbound = pickOutboundTopic(true, duplexTopics); // Alice is initiator - const topicInbound = pickOutboundTopic(false, duplexTopics); // Bob is responder - - // ===================================================================== - // RATCHET: Initialize session as INITIATOR - // CRITICAL: Use ephemeralPubKey from INSIDE the decrypted payload, - // NOT the on-chain responderEphemeralR (which is only for tag verification). - // This separation provides unlinkability between handshake and conversation. - // ===================================================================== - const ratchetSession = initSessionAsInitiator({ - myAddress: address, - contactAddress: contact.address, - myHandshakeEphemeralSecret: getBytes(contact.handshakeEphemeralSecret!), - theirResponderEphemeralPubKey: ephemeralPubKey, // From decrypted payload! - topicOutbound, - topicInbound, - }); - - // Save ratchet session - await dbService.saveRatchetSession(ratchetSession); - - const updatedContact: Contact = { - ...contact, - status: "established" as ContactStatus, - identityPubKey, - signingPubKey, - handshakeEphemeralSecret: undefined, // Clear ephemeral secret (no longer needed) - topicOutbound, - topicInbound, - conversationId: ratchetSession.conversationId, - lastMessage: note || "Handshake accepted", - lastTimestamp: Date.now(), - }; - - await dbService.saveContact(updatedContact); - - // Use contact.address (the EOA we initiated to), not responder (could be Safe) - setContacts((prev) => - prev.map((c) => - c.address.toLowerCase() === contact.address.toLowerCase() - ? updatedContact - : c - ) - ); - - onLog( - `๐Ÿค Handshake completed with ${contact.address.slice(0, 8)}... : "${ - note || "No message" - }"` - ); - - const responseMessage: Message = { - id: generateTempMessageId(), - topic: updatedContact.topicInbound || "", - sender: contact.address, // Use contact address, not responder - recipient: address, - ciphertext: "", - timestamp: Date.now(), - blockTimestamp: Date.now(), - blockNumber: 0, - direction: "incoming" as const, - decrypted: `Request accepted: "${note || "No message"}"`, - read: true, - nonce: 0, - dedupKey: `handshake-response-${inResponseTo}`, - type: "system" as const, - ownerAddress: address, - status: "confirmed" as const, - verified: true, - }; - - await dbService.saveMessage(responseMessage); - setMessages((prev) => [...prev, responseMessage]); - } catch (error) { - onLog(`โœ— Failed to process handshake response log: ${error}`); + // Log batch info + const messageEvents = events.filter((e) => e.eventType === "message"); + if (messageEvents.length > 1) { + onLog(`๐Ÿ“จ Processing batch of ${messageEvents.length} messages...`); } - }, - [address, readProvider, identityKeyPair, identityContext, onLog] - ); - const processMessageLog = useCallback( - async (event: ProcessedEvent): Promise => { - if (!address || !identityKeyPair) return; - - try { - const log = event.rawLog; - const abiCoder = new AbiCoder(); - const decoded = abiCoder.decode( - ["bytes", "uint256", "uint256"], - log.data - ); - const [ciphertextBytes, timestamp, nonce] = decoded; - const topic = log.topics[2]; - const sender = "0x" + log.topics[1].slice(-40); - const key = `${address.toLowerCase()}:${generateMessageId( - log.transactionHash, - log - )}`; - - // Raw ciphertext bytes (could be ratchet binary or legacy JSON) - const ciphertextHex = ciphertextBytes as string; - const ciphertextRaw = hexToUint8Array(ciphertextHex); - // Use emitterAddress (Safe in fast mode) for outbound detection - const emitter = emitterAddress || address; - const isOurMessage = - emitter && sender.toLowerCase() === emitter.toLowerCase(); - - if (!isOurMessage) { - const already = await dbService.getByDedupKey(key); - if (already) return; - } - - onLog( - `๐Ÿ” Processing message log: sender=${sender.slice( - 0, - 8 - )}..., isOurMessage=${isOurMessage}, topic=${topic.slice( - 0, - 10 - )}..., nonce=${Number(nonce)}` - ); - - // OUTGOING MESSAGE CONFIRMATION - if (isOurMessage) { - onLog( - `๐Ÿ”„ Confirming our outgoing message: topic=${topic.slice( - 0, - 10 - )}..., nonce=${Number(nonce)}` - ); - - // ===================================================================== - // RATCHET TWO-PHASE COMMIT: Match by txHash (primary method) - // ===================================================================== - const pending = await dbService.getPendingOutboundByTxHash(log.transactionHash); - - if (pending && pending.status === "submitted") { - // Commit the session state (applies sessionStateAfter) - await dbService.commitPendingOutbound(pending.id); - - // Update message status from pending to confirmed - const newId = generateMessageId(log.transactionHash, log); - await dbService.updateMessage(pending.id, { - id: newId, - status: "confirmed", - blockNumber: log.blockNumber, - blockTimestamp: Date.now(), - ciphertext: ciphertextHex, - nonce: Number(nonce), - dedupKey: key, - }); - - await dbService.upsertDedup({ - key, - messageId: newId, - txHash: log.transactionHash, - blockNumber: log.blockNumber, - }); - - setMessages((prev) => - prev.map((m) => - m.id === pending.id - ? { ...m, id: newId, status: "confirmed", blockNumber: log.blockNumber } - : m - ) + for (const event of events) { + switch (event.eventType) { + // ----------------------------------------------------------------- + // HANDSHAKE + // ----------------------------------------------------------------- + case "handshake": { + const result = await processHandshakeEvent( + event, + address, + readProvider, + identityContext, + onLog ); - onLog( - `โœ… Message confirmed: "${pending.plaintext.slice(0, 30)}..." (${pending.id.slice(0, 8)} โ†’ ${newId.slice(0, 8)})` - ); - return; + if (result) { + // Update React state + setPendingHandshakes((prev) => { + const existing = prev.find((h) => h.id === result.pendingHandshake.id); + if (existing) return prev; + return [...prev, result.pendingHandshake]; + }); + setMessages((prev) => [...prev, result.systemMessage]); + } + break; } - // ===================================================================== - // LEGACY FALLBACK: In-memory FIFO matching (for non-ratchet messages) - // ===================================================================== - const q = pendingMessagesRef.current.get(topic) ?? []; - const pendingMessage = q.shift(); - pendingMessagesRef.current.set(topic, q); - - if (pendingMessage) { - onLog( - `Matched pending by topic (legacy). Content preview: "${pendingMessage.decrypted?.slice( - 0, - 100 - )}..."` - ); - - const newId = generateMessageId(log.transactionHash, log); - const confirmedMessage: Message = { - ...pendingMessage, - id: newId, - blockNumber: log.blockNumber, - blockTimestamp: Date.now(), - ciphertext: ciphertextHex, - nonce: Number(nonce), - dedupKey: key, - status: "confirmed", - }; - - if (q.length === 0) { - pendingMessagesRef.current.delete(topic); + // ----------------------------------------------------------------- + // HANDSHAKE RESPONSE + // ----------------------------------------------------------------- + case "handshake_response": { + if (!identityKeyPair) { + onLog(`โŒ Cannot process handshake response: identityKeyPair is null`); + break; } - await dbService.updateMessage(pendingMessage.id, confirmedMessage); - await dbService.upsertDedup({ - key, - messageId: newId, - txHash: log.transactionHash, - blockNumber: log.blockNumber, - }); - - setMessages((prev) => - prev.map((m) => - m.id === pendingMessage.id ? confirmedMessage : m - ) - ); - - onLog( - `โœ… Outgoing message confirmed: "${pendingMessage.decrypted?.slice( - 0, - 30 - )}..." (${pendingMessage.id} โ†’ ${newId})` - ); - } else { - // DB fallback for multi-tab / refresh scenarios - const dbFallback = await dbService.findPendingMessage( + const result = await processHandshakeResponseEvent( + event, address, - topic, - Number(nonce), - address + readProvider, + identityKeyPair, + identityContext, + onLog ); - const allContacts = await dbService.getAllContacts(address); - const byTopic = allContacts.find((c) => c.topicOutbound === topic); - - const newId = generateMessageId(log.transactionHash, log); - const confirmed: Message = { - id: newId, - topic, - sender: address, - recipient: byTopic?.address, - ciphertext: ciphertextHex, - timestamp: Number(timestamp) * 1000, - blockTimestamp: Date.now(), - blockNumber: log.blockNumber, - direction: "outgoing", - read: true, - decrypted: dbFallback?.decrypted, - type: "text", - nonce: Number(nonce), - dedupKey: key, - ownerAddress: address, - status: "confirmed", - }; - - if (dbFallback) { - await dbService.updateMessage(dbFallback.id, confirmed); - await dbService.upsertDedup({ - key, - messageId: newId, - txHash: log.transactionHash, - blockNumber: log.blockNumber, - }); - setMessages((prev) => - prev.map((m) => (m.id === dbFallback.id ? confirmed : m)) - ); - onLog( - `โœ… Outgoing message confirmed (fallback): "${ - confirmed.decrypted?.slice(0, 30) ?? "" - }" (${dbFallback.id} โ†’ ${newId})` + if (result) { + // Update React state + setContacts((prev) => + prev.map((c) => + c.address.toLowerCase() === result.updatedContact.address.toLowerCase() + ? result.updatedContact + : c + ) ); - } else { - await dbService.saveMessage(confirmed); - await dbService.upsertDedup({ - key, - messageId: newId, - txHash: log.transactionHash, - blockNumber: log.blockNumber, - }); - setMessages((prev) => [...prev, confirmed]); - onLog(`โœ… Outgoing message confirmed (synthesized): ${newId}`); + setMessages((prev) => [...prev, result.systemMessage]); } + break; } - return; - } - -// ===================================================================== - // INCOMING MESSAGE - Use ratchet session for decryption - // ===================================================================== - - // Try to find ratchet session by inbound topic - const session = await dbService.getRatchetSessionByTopic(topic); - - if (!session) { - onLog( - `โ“ Received message on unknown topic: ${topic.slice(0, 10)}... from ${sender.slice(0, 8)}...` - ); - return; - } - - // Find contact for signing key verification - const contact = await dbService.getContact(session.contactAddress, address); - if (!contact?.signingPubKey) { - onLog(`โœ— No signing key for contact ${session.contactAddress.slice(0, 8)}...`); - return; - } - - // Check if ratchet format - if (!isRatchetPayload(ciphertextRaw)) { - onLog(`โœ— Message not in ratchet format from ${contact.address.slice(0, 8)}...`); - return; - } - - const parsed = parseRatchetPayload(ciphertextRaw); - if (!parsed) { - onLog(`โœ— Failed to parse ratchet payload from ${contact.address.slice(0, 8)}...`); - return; - } - - // ===================================================================== - // AUTH-FIRST: Verify signature BEFORE any ratchet operations (DoS protection) - // ===================================================================== - const sigValid = verifyMessageSignature( - parsed.signature, - parsed.header, - parsed.ciphertext, - contact.signingPubKey - ); - - if (!sigValid) { - onLog(`โœ— Invalid signature on message from ${contact.address.slice(0, 8)}..., ignoring`); - return; - } - - // ===================================================================== - // DECRYPT with ratchet (signature verified, safe to proceed) - // ===================================================================== - const decryptResult = ratchetDecrypt(session, parsed.header, parsed.ciphertext); - - if (!decryptResult) { - onLog(`โœ— Ratchet decryption failed from ${contact.address.slice(0, 8)}...`); - return; - } - - // Commit new session state immediately (receiving is safe to commit) - await dbService.saveRatchetSession(decryptResult.session); - - // Decode plaintext - const decryptedText = new TextDecoder().decode(decryptResult.plaintext); - - const message: Message = { - id: generateMessageId(log.transactionHash, log), - topic: topic, - sender: contact.address, // Use contact address, not on-chain sender - recipient: address, - ciphertext: ciphertextHex, - timestamp: Number(timestamp) * 1000, - blockTimestamp: Date.now(), - blockNumber: log.blockNumber, - direction: "incoming" as MessageDirection, - decrypted: decryptedText, - read: false, - nonce: Number(nonce), - dedupKey: key, - type: "text" as MessageType, - ownerAddress: address, - status: "confirmed", - }; - - const saved = await dbService.saveMessage(message); - - if (saved) { - await dbService.upsertDedup({ - key, - messageId: message.id, - txHash: log.transactionHash, - blockNumber: log.blockNumber, - }); - setMessages((prev) => { - const existing = prev.find((m) => m.id === message.id); - if (existing) return prev; - return [...prev, message]; - }); - - const updatedContact: Contact = { - ...contact, - lastMessage: decryptedText, - lastTimestamp: Date.now(), - }; - - await dbService.saveContact(updatedContact); - - setContacts((prev) => - prev.map((c) => - c.address.toLowerCase() === contact.address.toLowerCase() - ? updatedContact - : c - ) - ); - - onLog(`๐Ÿ“ฉ Message from ${contact.address.slice(0, 8)}...: "${decryptedText}"`); - } - } catch (error) { - onLog(`โœ— Failed to process message log: ${error}`); - } - }, - [address, emitterAddress, identityKeyPair, onLog] - ); + // ----------------------------------------------------------------- + // MESSAGE + // ----------------------------------------------------------------- + case "message": { + const result = await processMessageEvent( + event, + address, + emitterAddress, + batchSessionCache, + onLog + ); - const processEvents = useCallback( - async (events: ProcessedEvent[]) => { - for (const event of events) { - switch (event.eventType) { - case "handshake": - await processHandshakeLog(event); - break; - case "handshake_response": - await processHandshakeResponseLog(event); - break; - case "message": - await processMessageLog(event); + if (result) { + // Apply state updates + if (result.newMessage) { + setMessages((prev) => { + const existing = prev.find((m) => m.id === result.newMessage!.id); + if (existing) return prev; + return [...prev, result.newMessage!]; + }); + } + + if (result.messageUpdate) { + const [originalId, updates] = result.messageUpdate; + setMessages((prev) => + prev.map((m) => (m.id === originalId ? { ...m, ...updates } : m)) + ); + } + + if (result.contactUpdate) { + setContacts((prev) => + prev.map((c) => + c.address.toLowerCase() === result.contactUpdate!.address.toLowerCase() + ? result.contactUpdate! + : c + ) + ); + } + } break; + } } } + + // Persist all updated sessions to DB after batch completes + await persistSessionCache(batchSessionCache, onLog); }, - [processHandshakeLog, processHandshakeResponseLog, processMessageLog] + [address, readProvider, identityKeyPair, identityContext, emitterAddress, onLog] ); + // =========================================================================== + // CRUD Operations + // =========================================================================== + const addMessage = useCallback( async (message: Message) => { if (!address) return; const messageWithOwner = { ...message, ownerAddress: address }; - // Track pending outgoing in the in-memory Map - if ( - messageWithOwner.status === "pending" && - messageWithOwner.direction === "outgoing" && - messageWithOwner.type === "text" && - messageWithOwner.topic - ) { - const q = pendingMessagesRef.current.get(messageWithOwner.topic) ?? []; - q.push(messageWithOwner); - pendingMessagesRef.current.set(messageWithOwner.topic, q); - onLog( - `Registered pending message for topic ${messageWithOwner.topic.slice( - 0, - 10 - )}...` - ); - } - const saved = await dbService.saveMessage(messageWithOwner); if (saved) { setMessages((prev) => [...prev, messageWithOwner]); } }, - [address, onLog] + [address] + ); + + const updateMessageStatus = useCallback( + async (messageId: string, status: Message["status"], error?: string) => { + const updates: Partial = { status }; + await dbService.updateMessage(messageId, updates); + + setMessages((prev) => + prev.map((m) => (m.id === messageId ? { ...m, status } : m)) + ); + + if (status === "failed" && error) { + onLog(`โœ— Message ${messageId.slice(0, 8)}... failed: ${error}`); + } + }, + [onLog] ); + const removeMessage = useCallback(async (messageId: string) => { + await dbService.deleteMessage(messageId); + setMessages((prev) => prev.filter((m) => m.id !== messageId)); + }, []); + const removePendingHandshake = useCallback(async (id: string) => { await dbService.deletePendingHandshake(id); setPendingHandshakes((prev) => prev.filter((h) => h.id !== id)); @@ -878,10 +252,8 @@ export const useMessageProcessor = ({ [address] ); - // cleanup and reload when address changes useEffect(() => { if (address) { - pendingMessagesRef.current.clear(); setMessages([]); setContacts([]); setPendingHandshakes([]); @@ -894,8 +266,10 @@ export const useMessageProcessor = ({ pendingHandshakes, contacts, addMessage, + updateMessageStatus, + removeMessage, removePendingHandshake, updateContact, processEvents, }; -}; +}; \ No newline at end of file diff --git a/apps/demo/src/hooks/useMessageQueue.ts b/apps/demo/src/hooks/useMessageQueue.ts index 2644cca..86580af 100644 --- a/apps/demo/src/hooks/useMessageQueue.ts +++ b/apps/demo/src/hooks/useMessageQueue.ts @@ -3,11 +3,11 @@ /** * Message Queue Hook for Sequential Processing with Optimistic UI. * - * Solves the race condition problem by: - * 1. Immediately showing messages in UI (optimistic) - * 2. Queuing messages per conversation - * 3. Processing queue sequentially in background - * 4. Handling failures with retry capability + * 1. Session state is cached per conversation and persists across processQueue calls + * 2. After encryption, session state is immediately saved to DB (not waiting for confirmation) + * 3. Failed messages don't corrupt session state - the ratchet slot is "burned" + * 4. Confirmations now just clean up pending records, not commit session state + * */ import { useCallback, useRef, useEffect } from "react"; @@ -27,9 +27,6 @@ import { serializeRatchetSession, } from "../types.js"; -// ============================================================================= -// Types -// ============================================================================= export type QueuedMessageStatus = | "queued" // In queue, waiting for previous to complete @@ -47,9 +44,6 @@ export interface QueuedMessage { error?: string; txHash?: string; createdAt: number; - // Pre-computed encryption (computed when message reaches front of queue) - encryptedPayload?: Uint8Array; - sessionStateAfter?: string; } interface ConversationQueue { @@ -62,23 +56,27 @@ interface UseMessageQueueProps { addLog: (message: string) => void; addMessage: (message: Message) => Promise; updateMessageStatus: (id: string, status: Message["status"], error?: string) => Promise; + removeMessage: (id: string) => Promise; updateContact: (contact: Contact) => Promise; } -// ============================================================================= -// Hook -// ============================================================================= export const useMessageQueue = ({ verbethClient, addLog, addMessage, updateMessageStatus, + removeMessage, updateContact, }: UseMessageQueueProps) => { - // Queue per conversation + const queuesRef = useRef>(new Map()); + // persistent session cache across processQueue invocations + // This ensures we never lose track of the latest session state + const sessionCacheRef = useRef>(new Map()); + + const failedMessagesRef = useRef>(new Map()); // Track mounted state to prevent updates after unmount const mountedRef = useRef(true); @@ -99,19 +97,40 @@ export const useMessageQueue = ({ const queue = queuesRef.current.get(conversationId); if (!queue || queue.isProcessing || queue.messages.length === 0) return; - // Mark as processing queue.isProcessing = true; + // Check session cache first, only fall back to DB if not cached + // This ensures we always use the most recently advanced session state + let currentSession: RatchetSession | null = sessionCacheRef.current.get(conversationId) ?? null; + + if (!currentSession) { + try { + currentSession = await dbService.getRatchetSessionByConversation(conversationId); + if (currentSession) { + sessionCacheRef.current.set(conversationId, currentSession); + addLog(`๐Ÿ“‚ Loaded session from DB for ${conversationId.slice(0, 10)}...`); + } + } catch (error) { + addLog(`โœ— Failed to load ratchet session for ${conversationId.slice(0, 10)}...`); + queue.isProcessing = false; + return; + } + } + + if (!currentSession) { + addLog(`โœ— No ratchet session found for ${conversationId.slice(0, 10)}...`); + queue.isProcessing = false; + return; + } + while (queue.messages.length > 0 && mountedRef.current) { const message = queue.messages[0]; - // Skip already processed messages if (message.status === "confirmed" || message.status === "pending") { queue.messages.shift(); continue; } - // Skip failed messages (user must explicitly retry) if (message.status === "failed") { queue.messages.shift(); continue; @@ -120,32 +139,44 @@ export const useMessageQueue = ({ try { message.status = "sending"; - // 1. Load current session state - const session = await dbService.getRatchetSessionByConversation(conversationId); - if (!session) { - throw new Error("No ratchet session found"); - } + // use the cached in-memory session state + const sessionBefore = currentSession; - // 2. Encrypt with ratchet const plaintext = new TextEncoder().encode(message.plaintext); const { session: nextSession, header, ciphertext, signature } = ratchetEncrypt( - session, + sessionBefore, plaintext, verbethClient.identityKeyPairInstance.signingSecretKey ); - // 3. Package binary payload + // ===================================================================== + // Update BOTH in-memory cache AND DB immediately after encryption + // I.e., we commit the session state BEFORE sending the tx + // + // Why this is safe: + // 1. If tx succeeds: receiver gets message, session states are in sync + // 2. If tx fails: the ratchet "slot" is burned, but receiver's skip-key + // mechanism will handle the gap when they receive subsequent messages + // 3. This matches how Signal handles message failures + // ===================================================================== + currentSession = nextSession; + sessionCacheRef.current.set(conversationId, nextSession); + + await dbService.saveRatchetSession(nextSession); + addLog(`๐Ÿ’พ Session state committed (sendingMsgNumber=${nextSession.sendingMsgNumber})`); + + // Package binary payload const payload = packageRatchetPayload(signature, header, ciphertext); const payloadHex = hexlify(payload); - // 4. Create pending record (two-phase commit) + // Create pending record for confirmation matching (simplified - no session state) const pending: PendingOutbound = { id: message.id, conversationId, - topic: session.topicOutbound, + topic: sessionBefore.topicOutbound, payloadHex, plaintext: message.plaintext, - sessionStateBefore: JSON.stringify(serializeRatchetSession(session)), + sessionStateBefore: JSON.stringify(serializeRatchetSession(sessionBefore)), sessionStateAfter: JSON.stringify(serializeRatchetSession(nextSession)), createdAt: message.createdAt, txHash: null, @@ -153,25 +184,25 @@ export const useMessageQueue = ({ }; await dbService.savePendingOutbound(pending); - // 5. Send transaction + // Send transaction const timestamp = Math.floor(Date.now() / 1000); - const nonce = nextSession.sendingMsgNumber - 1; + const nonce = nextSession.sendingMsgNumber - 1; // The message number we just used await dbService.updatePendingOutboundStatus(message.id, "submitted"); const tx = await verbethClient.executorInstance.sendMessage( payload, - session.topicOutbound, + sessionBefore.topicOutbound, timestamp, BigInt(nonce) ); - // 6. Update with txHash + // Update with txHash message.txHash = tx.hash; message.status = "pending"; await dbService.updatePendingOutboundStatus(message.id, "submitted", tx.hash); - addLog(`๐Ÿ“ค Message sent: "${message.plaintext.slice(0, 30)}..." (tx: ${tx.hash.slice(0, 10)}...)`); + addLog(`๐Ÿ“ค Message sent: "${message.plaintext.slice(0, 30)}..." (tx: ${tx.hash.slice(0, 10)}..., n=${nonce})`); // Update contact const updatedContact: Contact = { @@ -191,23 +222,34 @@ export const useMessageQueue = ({ message.status = "failed"; message.error = errorMessage; - // Rollback: delete pending record if it was created + // ===================================================================== + // On failure, we do NOT roll back session state + // The ratchet slot is "burned" - the encryption already advanced the + // chain. If we rolled back, we'd reuse the same key which is a security + // violation. Instead, we let the slot be skipped - the receiver will + // handle this via their skip-key mechanism. + // + // This is intentional and matches Signal's behavior. + // ===================================================================== + + try { await dbService.deletePendingOutbound(message.id); } catch { - // Ignore cleanup errors } - // Update UI message status await updateMessageStatus(message.id, "failed", errorMessage); - addLog(`โœ— Failed to send: "${message.plaintext.slice(0, 20)}..." - ${errorMessage}`); + addLog(`โœ— Failed to send (slot burned): "${message.plaintext.slice(0, 20)}..." - ${errorMessage}`); + + // Store failed message for retry/cancel + failedMessagesRef.current.set(message.id, { ...message }); - // Remove failed message from queue (user can retry via UI) + // Remove from active queue queue.messages.shift(); - // Don't break - continue processing remaining messages - // (they might succeed if the failure was transient) + // Continue processing remaining messages with the advanced session state + // (currentSession is already updated, which is correct) } } @@ -239,7 +281,7 @@ export const useMessageQueue = ({ const messageId = generateTempMessageId(); const conversationId = contact.conversationId; - // 1. Create queued message + // Create queued message const queuedMessage: QueuedMessage = { id: messageId, conversationId, @@ -249,17 +291,17 @@ export const useMessageQueue = ({ createdAt: Date.now(), }; - // 2. Get or create queue for this conversation + // Get or create queue for this conversation let queue = queuesRef.current.get(conversationId); if (!queue) { queue = { messages: [], isProcessing: false }; queuesRef.current.set(conversationId, queue); } - // 3. Add to queue + // Add to queue queue.messages.push(queuedMessage); - // 4. Show optimistic UI message immediately + // Show optimistic UI message immediately const optimisticMessage: Message = { id: messageId, topic: contact.topicOutbound || "", @@ -283,8 +325,7 @@ export const useMessageQueue = ({ addLog(`๐Ÿ“ Message queued: "${messageText.slice(0, 30)}..."`); - // 5. Trigger queue processing (non-blocking) - // Use setTimeout to ensure this runs after current execution + // Trigger queue processing (non-blocking) setTimeout(() => processQueue(conversationId), 0); return messageId; @@ -292,9 +333,48 @@ export const useMessageQueue = ({ /** * Retry a failed message. + * + * IMPORTANT: The original ratchet slot was burned. Retry creates a NEW + * encryption with the current (advanced) session state. This means the + * message number will be different from the original attempt. */ const retryMessage = useCallback(async (messageId: string): Promise => { - // Find the message in any queue + // Check the failed messages map first + const failedMessage = failedMessagesRef.current.get(messageId); + + if (failedMessage) { + const conversationId = failedMessage.conversationId; + + // Remove from failed messages map + failedMessagesRef.current.delete(messageId); + + // Reset status for retry + failedMessage.status = "queued"; + failedMessage.error = undefined; + failedMessage.createdAt = Date.now(); + + // Get or create queue + let queue = queuesRef.current.get(conversationId); + if (!queue) { + queue = { messages: [], isProcessing: false }; + queuesRef.current.set(conversationId, queue); + } + + // Add to end of queue + queue.messages.push(failedMessage); + + // Update UI status back to pending + await updateMessageStatus(messageId, "pending"); + + addLog(`๐Ÿ”„ Retrying message (new slot): "${failedMessage.plaintext.slice(0, 30)}..."`); + + // Trigger processing + setTimeout(() => processQueue(conversationId), 0); + + return true; + } + + // Fallback: check if still in active queue (shouldn't happen normally) for (const [conversationId, queue] of queuesRef.current.entries()) { const messageIndex = queue.messages.findIndex( m => m.id === messageId && m.status === "failed" @@ -303,7 +383,6 @@ export const useMessageQueue = ({ if (messageIndex !== -1) { const message = queue.messages[messageIndex]; - // Reset status and re-add to queue message.status = "queued"; message.error = undefined; message.createdAt = Date.now(); @@ -312,28 +391,38 @@ export const useMessageQueue = ({ queue.messages.splice(messageIndex, 1); queue.messages.push(message); - // Update UI await updateMessageStatus(messageId, "pending"); addLog(`๐Ÿ”„ Retrying message: "${message.plaintext.slice(0, 30)}..."`); - // Trigger processing setTimeout(() => processQueue(conversationId), 0); return true; } } - // Message not in queue - might need to reload from DB - // For now, return false addLog(`โœ— Could not find message ${messageId} to retry`); return false; }, [addLog, updateMessageStatus, processQueue]); /** - * Cancel a queued (not yet sent) message. + * Cancel/delete a failed or queued message. */ const cancelMessage = useCallback(async (messageId: string): Promise => { + // Check failed messages map first + const failedMessage = failedMessagesRef.current.get(messageId); + + if (failedMessage) { + failedMessagesRef.current.delete(messageId); + + // Remove from DB and UI + await removeMessage(messageId); + + addLog(`๐Ÿ—‘๏ธ Deleted message: "${failedMessage.plaintext.slice(0, 30)}..."`); + return true; + } + + // Fallback: check active queues for (const [, queue] of queuesRef.current.entries()) { const messageIndex = queue.messages.findIndex( m => m.id === messageId && (m.status === "queued" || m.status === "failed") @@ -343,16 +432,16 @@ export const useMessageQueue = ({ const message = queue.messages[messageIndex]; queue.messages.splice(messageIndex, 1); - // Remove from DB/UI - await dbService.deleteMessage(messageId); + await removeMessage(messageId); - addLog(`๐Ÿ—‘๏ธ Cancelled message: "${message.plaintext.slice(0, 30)}..."`); + addLog(`๐Ÿ—‘๏ธ Deleted message: "${message.plaintext.slice(0, 30)}..."`); return true; } } + addLog(`โœ— Could not find message ${messageId} to delete`); return false; - }, [addLog]); + }, [addLog, removeMessage]); /** * Get queue status for a conversation. @@ -373,11 +462,22 @@ export const useMessageQueue = ({ }; }, []); + /** + * Invalidate cached session for a conversation. + * Call this when session is reset or updated externally. + */ + const invalidateSessionCache = useCallback((conversationId: string) => { + sessionCacheRef.current.delete(conversationId); + addLog(`๐Ÿ”„ Session cache invalidated for ${conversationId.slice(0, 10)}...`); + }, [addLog]); + /** * Clear all queues (e.g., on logout). */ const clearAllQueues = useCallback(() => { queuesRef.current.clear(); + failedMessagesRef.current.clear(); + sessionCacheRef.current.clear(); }, []); return { @@ -385,6 +485,7 @@ export const useMessageQueue = ({ retryMessage, cancelMessage, getQueueStatus, + invalidateSessionCache, clearAllQueues, }; }; \ No newline at end of file diff --git a/apps/demo/src/services/DbService.ts b/apps/demo/src/services/DbService.ts index 13641dc..416d0fa 100644 --- a/apps/demo/src/services/DbService.ts +++ b/apps/demo/src/services/DbService.ts @@ -1,3 +1,5 @@ +// src/services/DbService.ts + import { VerbEthDatabase } from "./schema.js"; import type { StoredIdentity, @@ -414,7 +416,7 @@ export class DbService { */ async saveRatchetSession(session: RatchetSession): Promise { const stored = serializeRatchetSession(session); - console.log(`๐Ÿ’พ Saving ratchet session: ${stored.conversationId.slice(0, 10)}...`); + console.log(`๐Ÿ’พ Saving ratchet session: ${stored.conversationId.slice(0, 10)}... (sendingMsgNumber=${stored.sendingMsgNumber})`); await this.db.ratchetSessions.put(stored); } @@ -535,24 +537,24 @@ export class DbService { } /** - * Commit pending outbound: apply sessionStateAfter and delete pending record. + * Finalize pending outbound: just delete the pending record. * Called when on-chain confirmation is received. + * + * With the new architecture, session state is committed immediately during + * encryption, so confirmation just needs to clean up the pending record. */ - async commitPendingOutbound(id: string): Promise { + async finalizePendingOutbound(id: string): Promise<{ plaintext: string } | null> { const pending = await this.db.pendingOutbound.get(id); if (!pending) { - console.warn(`โš ๏ธ Pending outbound ${id} not found for commit`); - return; + console.warn(`โš ๏ธ Pending outbound ${id} not found for finalization`); + return null; } - // Parse and save the committed session state - const sessionAfter: StoredRatchetSession = JSON.parse(pending.sessionStateAfter); - await this.db.ratchetSessions.put(sessionAfter); - - // Delete the pending record + // Just delete the pending record - session state was already committed await this.db.pendingOutbound.delete(id); - console.log(`โœ… Committed pending outbound ${id.slice(0, 10)}... - session state updated`); + console.log(`โœ… Finalized pending outbound ${id.slice(0, 10)}...`); + return { plaintext: pending.plaintext }; } /** @@ -824,4 +826,4 @@ export class DbService { } } -export const dbService = new DbService(); +export const dbService = new DbService(); \ No newline at end of file diff --git a/apps/demo/src/services/EventProcessorService.ts b/apps/demo/src/services/EventProcessorService.ts new file mode 100644 index 0000000..049fec9 --- /dev/null +++ b/apps/demo/src/services/EventProcessorService.ts @@ -0,0 +1,653 @@ +// src/services/EventProcessorService.ts + +/** + * Event Processing Service. + * + * Handles decoding, verification, decryption, and persistence of blockchain events. + * Returns only what's needed for React state updates. + */ + +import { AbiCoder, getBytes } from "ethers"; +import { + type IdentityContext, + type IdentityKeyPair, + type RatchetSession, + parseHandshakePayload, + parseBindingMessage, + verifyHandshakeIdentity, + decodeUnifiedPubKeys, + verifyAndExtractHandshakeResponseKeys, + deriveDuplexTopics, + verifyDerivedDuplexTopics, + computeTagFromInitiator, + pickOutboundTopic, + initSessionAsInitiator, + ratchetDecrypt, + parseRatchetPayload, + isRatchetPayload, + verifyMessageSignature, +} from "@verbeth/sdk"; + +import { dbService } from "./DbService.js"; +import { + Contact, + Message, + PendingHandshake, + ProcessedEvent, + MessageDirection, + MessageType, + ContactStatus, + generateTempMessageId, +} from "../types.js"; + +export function hexToUint8Array(hex: string): Uint8Array { + const cleanHex = hex.replace("0x", ""); + return new Uint8Array( + cleanHex.match(/.{1,2}/g)?.map((byte) => parseInt(byte, 16)) || [] + ); +} + +export function generateMessageId( + txHash: string, + log: { logIndex?: number; index?: number } +): string { + const idx = + typeof log.logIndex !== "undefined" + ? log.logIndex + : typeof log.index !== "undefined" + ? log.index + : 0; + return `${txHash}-${idx}`; +} + +export interface HandshakeResult { + pendingHandshake: PendingHandshake; + systemMessage: Message; +} + +export interface HandshakeResponseResult { + updatedContact: Contact; + systemMessage: Message; +} + +export interface MessageResult { + /** New message to add */ + newMessage?: Message; + /** Message update: [originalId, partialUpdates] - will be merged with existing message */ + messageUpdate?: [string, Partial]; + /** Contact to update */ + contactUpdate?: Contact; +} + +// ============================================================================= +// Handshake Processing +// ============================================================================= + +export async function processHandshakeEvent( + event: ProcessedEvent, + address: string, + readProvider: any, + identityContext: IdentityContext, + onLog: (msg: string) => void +): Promise { + try { + const log = event.rawLog; + const abiCoder = new AbiCoder(); + const decoded = abiCoder.decode(["bytes", "bytes", "bytes"], log.data); + const [identityPubKeyBytes, ephemeralPubKeyBytes, plaintextPayloadBytes] = + decoded; + + const unifiedPubKeys = hexToUint8Array(identityPubKeyBytes); + const decodedKeys = decodeUnifiedPubKeys(unifiedPubKeys); + + if (!decodedKeys) { + onLog("โœ— Failed to decode unified public keys"); + return null; + } + + const identityPubKey = decodedKeys.identityPubKey; + const signingPubKey = decodedKeys.signingPubKey; + const ephemeralPubKey = hexToUint8Array(ephemeralPubKeyBytes); + const plaintextPayload = new TextDecoder().decode( + hexToUint8Array(plaintextPayloadBytes) + ); + + const cleanSenderAddress = "0x" + log.topics[2].slice(-40); + const recipientHash = log.topics[1]; + + let handshakeContent; + let hasValidIdentityProof = false; + + try { + handshakeContent = parseHandshakePayload(plaintextPayload); + hasValidIdentityProof = true; + } catch (error) { + handshakeContent = { + plaintextPayload: plaintextPayload, + identityProof: null, + }; + hasValidIdentityProof = false; + } + + let isVerified = false; + if (hasValidIdentityProof) { + try { + const handshakeEvent = { + recipientHash, + sender: cleanSenderAddress, + pubKeys: identityPubKeyBytes, + ephemeralPubKey: ephemeralPubKeyBytes, + plaintextPayload: plaintextPayload, + }; + + isVerified = await verifyHandshakeIdentity( + handshakeEvent, + readProvider, + identityContext + ); + } catch (error) { + onLog(`Failed to verify handshake identity: ${error}`); + } + } + + let identityAddress = cleanSenderAddress; + if (hasValidIdentityProof && handshakeContent.identityProof?.message) { + try { + const parsed = parseBindingMessage( + handshakeContent.identityProof.message + ); + if (parsed.address) { + identityAddress = parsed.address; + } + } catch (e) {} + } + + const pendingHandshake: PendingHandshake = { + id: log.transactionHash, + ownerAddress: address, + sender: identityAddress, + emitterAddress: cleanSenderAddress, + identityPubKey, + signingPubKey, + ephemeralPubKey, + message: handshakeContent.plaintextPayload, + timestamp: Date.now(), + blockNumber: log.blockNumber, + verified: isVerified, + }; + + const systemMessage: Message = { + id: generateTempMessageId(), + topic: "", + sender: identityAddress, + recipient: address, + ciphertext: "", + timestamp: Date.now(), + blockTimestamp: Date.now(), + blockNumber: log.blockNumber, + direction: "incoming" as const, + decrypted: `Request received: "${handshakeContent.plaintextPayload}"`, + read: true, + nonce: 0, + dedupKey: `handshake-received-${log.transactionHash}`, + type: "system" as const, + ownerAddress: address, + status: "confirmed" as const, + verified: isVerified, + }; + + // Persist to DB + await dbService.savePendingHandshake(pendingHandshake); + await dbService.saveMessage(systemMessage); + + onLog( + `๐Ÿ“จ Handshake received from ${identityAddress.slice(0, 8)}... ${ + isVerified ? "โœ…" : "โš ๏ธ" + }: "${handshakeContent.plaintextPayload}"` + ); + + return { pendingHandshake, systemMessage }; + } catch (error) { + onLog(`โœ— Failed to process handshake log: ${error}`); + return null; + } +} + +// ============================================================================= +// Handshake Response Processing +// ============================================================================= + +export async function processHandshakeResponseEvent( + event: ProcessedEvent, + address: string, + readProvider: any, + identityKeyPair: IdentityKeyPair, + identityContext: IdentityContext, + onLog: (msg: string) => void +): Promise { + try { + const log = event.rawLog; + const abiCoder = new AbiCoder(); + const [responderEphemeralRBytes, ciphertextBytes] = abiCoder.decode( + ["bytes32", "bytes"], + log.data + ); + + const ciphertextJson = new TextDecoder().decode( + hexToUint8Array(ciphertextBytes) + ); + + const responder = "0x" + log.topics[2].slice(-40); + const inResponseTo = log.topics[1]; + + const currentContacts = await dbService.getAllContacts(address); + + onLog( + `๐Ÿ” Debug: Loaded ${currentContacts.length} contacts from DB for handshake response` + ); + + const contact = currentContacts.find( + (c) => + c.address.toLowerCase() === + event.matchedContactAddress?.toLowerCase() && + c.status === "handshake_sent" + ); + + if (!contact || !contact.handshakeEphemeralSecret) { + onLog( + `โ“ Received handshake response but no matching pending contact found (responder: ${responder.slice( + 0, + 8 + )}...)` + ); + return null; + } + + const responseEvent = { + inResponseTo, + responder, + responderEphemeralR: responderEphemeralRBytes, + ciphertext: ciphertextJson, + }; + + const result = await verifyAndExtractHandshakeResponseKeys( + responseEvent, + getBytes(contact.handshakeEphemeralSecret!), + readProvider, + identityContext + ); + + if (!result.isValid || !result.keys) { + onLog( + `โŒ Failed to verify handshake response from ${contact.address.slice( + 0, + 8 + )}... - invalid signature or tag mismatch` + ); + return null; + } + + const { identityPubKey, signingPubKey, ephemeralPubKey, note } = + result.keys; + + const saltHex = computeTagFromInitiator( + getBytes(contact.handshakeEphemeralSecret!), + hexToUint8Array(responderEphemeralRBytes) + ); + const salt = Uint8Array.from(Buffer.from(saltHex.slice(2), "hex")); + + const duplexTopics = deriveDuplexTopics( + identityKeyPair.secretKey, + identityPubKey, + salt + ); + + const isValidTopics = verifyDerivedDuplexTopics({ + myIdentitySecretKey: identityKeyPair.secretKey, + theirIdentityPubKey: identityPubKey, + topicInfo: { + out: duplexTopics.topicOut, + in: duplexTopics.topicIn, + chk: duplexTopics.checksum, + }, + salt, + }); + + if (!isValidTopics) { + onLog( + `โŒ Invalid duplex topics checksum for ${contact.address.slice(0, 8)}...` + ); + return null; + } + + onLog( + `โœ… Handshake response verified from ${contact.address.slice(0, 8)}...` + ); + + const topicOutbound = pickOutboundTopic(true, duplexTopics); + const topicInbound = pickOutboundTopic(false, duplexTopics); + + const ratchetSession = initSessionAsInitiator({ + myAddress: address, + contactAddress: contact.address, + myHandshakeEphemeralSecret: getBytes(contact.handshakeEphemeralSecret!), + theirResponderEphemeralPubKey: ephemeralPubKey, + topicOutbound, + topicInbound, + }); + + const updatedContact: Contact = { + ...contact, + status: "established" as ContactStatus, + identityPubKey, + signingPubKey, + handshakeEphemeralSecret: undefined, + topicOutbound, + topicInbound, + conversationId: ratchetSession.conversationId, + lastMessage: note || "Handshake accepted", + lastTimestamp: Date.now(), + }; + + const systemMessage: Message = { + id: generateTempMessageId(), + topic: updatedContact.topicInbound || "", + sender: contact.address, + recipient: address, + ciphertext: "", + timestamp: Date.now(), + blockTimestamp: Date.now(), + blockNumber: 0, + direction: "incoming" as const, + decrypted: `Request accepted: "${note || "No message"}"`, + read: true, + nonce: 0, + dedupKey: `handshake-response-${inResponseTo}`, + type: "system" as const, + ownerAddress: address, + status: "confirmed" as const, + verified: true, + }; + + // Persist to DB + await dbService.saveRatchetSession(ratchetSession); + await dbService.saveContact(updatedContact); + await dbService.saveMessage(systemMessage); + + onLog( + `๐Ÿค Handshake completed with ${contact.address.slice(0, 8)}... : "${ + note || "No message" + }"` + ); + + return { updatedContact, systemMessage }; + } catch (error) { + onLog(`โœ— Failed to process handshake response log: ${error}`); + return null; + } +} + +// ============================================================================= +// Message Processing (Outgoing Confirmation + Incoming Decryption) +// ============================================================================= + +export async function processMessageEvent( + event: ProcessedEvent, + address: string, + emitterAddress: string | undefined, + sessionCache: Map, + onLog: (msg: string) => void +): Promise { + try { + const log = event.rawLog; + const abiCoder = new AbiCoder(); + const decoded = abiCoder.decode(["bytes", "uint256", "uint256"], log.data); + const [ciphertextBytes, timestamp, nonce] = decoded; + const topic = log.topics[2]; + const sender = "0x" + log.topics[1].slice(-40); + const dedupKey = `${address.toLowerCase()}:${generateMessageId( + log.transactionHash, + log + )}`; + + const ciphertextHex = ciphertextBytes as string; + const ciphertextRaw = hexToUint8Array(ciphertextHex); + const emitter = emitterAddress || address; + const isOurMessage = emitter && sender.toLowerCase() === emitter.toLowerCase(); + + if (!isOurMessage) { + const already = await dbService.getByDedupKey(dedupKey); + if (already) return null; + } + + onLog( + `๐Ÿ” Processing message log: sender=${sender.slice( + 0, + 8 + )}..., isOurMessage=${isOurMessage}, topic=${topic.slice( + 0, + 10 + )}..., nonce=${Number(nonce)}` + ); + + // ========================================================================= + // OUTGOING MESSAGE CONFIRMATION (Ratchet two-phase commit) + // ========================================================================= + if (isOurMessage) { + onLog( + `๐Ÿ”„ Confirming our outgoing message: topic=${topic.slice( + 0, + 10 + )}..., nonce=${Number(nonce)}` + ); + + // Match by txHash + const pending = await dbService.getPendingOutboundByTxHash( + log.transactionHash + ); + + if (pending && pending.status === "submitted") { + // Finalize: clean up the pending record (session already committed during encryption) + const finalized = await dbService.finalizePendingOutbound(pending.id); + + if (!finalized) { + onLog(`โš ๏ธ Failed to finalize pending outbound ${pending.id.slice(0, 8)}...`); + return null; + } + + const newId = generateMessageId(log.transactionHash, log); + const updates: Partial = { + id: newId, + status: "confirmed", + blockNumber: log.blockNumber, + blockTimestamp: Date.now(), + ciphertext: ciphertextHex, + nonce: Number(nonce), + dedupKey, + }; + + await dbService.updateMessage(pending.id, updates); + await dbService.upsertDedup({ + key: dedupKey, + messageId: newId, + txHash: log.transactionHash, + blockNumber: log.blockNumber, + }); + + onLog( + `โœ… Message confirmed: "${finalized.plaintext.slice( + 0, + 30 + )}..." (${pending.id.slice(0, 8)} โ†’ ${newId.slice(0, 8)})` + ); + + return { + messageUpdate: [pending.id, updates], + }; + } + + // No matching pending record - this shouldn't happen in normal flow + onLog( + `โš ๏ธ Outgoing message on-chain but no pending record found (tx: ${log.transactionHash.slice(0, 10)}...)` + ); + return null; + } + + // ========================================================================= + // INCOMING MESSAGE - Use ratchet session for decryption + // ========================================================================= + + // Check session cache FIRST, then fall back to DB + let session = sessionCache.get(topic); + + if (!session) { + session = + (await dbService.getRatchetSessionByTopic(topic)) || undefined; + + if (session) { + sessionCache.set(topic, session); + } + } + + if (!session) { + onLog( + `โ“ Received message on unknown topic: ${topic.slice( + 0, + 10 + )}... from ${sender.slice(0, 8)}...` + ); + return null; + } + + // Find contact for signing key verification + const contact = await dbService.getContact(session.contactAddress, address); + if (!contact?.signingPubKey) { + onLog( + `โœ— No signing key for contact ${session.contactAddress.slice(0, 8)}...` + ); + return null; + } + + // Check if ratchet format + if (!isRatchetPayload(ciphertextRaw)) { + onLog( + `โœ— Message not in ratchet format from ${contact.address.slice(0, 8)}...` + ); + return null; + } + + const parsed = parseRatchetPayload(ciphertextRaw); + if (!parsed) { + onLog( + `โœ— Failed to parse ratchet payload from ${contact.address.slice( + 0, + 8 + )}...` + ); + return null; + } + + // AUTH-FIRST: Verify signature BEFORE any ratchet operations (DoS protection) + const sigValid = verifyMessageSignature( + parsed.signature, + parsed.header, + parsed.ciphertext, + contact.signingPubKey + ); + + if (!sigValid) { + onLog( + `โœ— Invalid signature on message from ${contact.address.slice( + 0, + 8 + )}..., ignoring` + ); + return null; + } + + // decrypt with ratchet (signature verified) + const decryptResult = ratchetDecrypt( + session, + parsed.header, + parsed.ciphertext + ); + + if (!decryptResult) { + onLog( + `โœ— Ratchet decryption failed from ${contact.address.slice(0, 8)}...` + ); + return null; + } + + // Update session cache IMMEDIATELY + sessionCache.set(topic, decryptResult.session); + + const decryptedText = new TextDecoder().decode(decryptResult.plaintext); + + const message: Message = { + id: generateMessageId(log.transactionHash, log), + topic: topic, + sender: contact.address, + recipient: address, + ciphertext: ciphertextHex, + timestamp: Number(timestamp) * 1000, + blockTimestamp: Date.now(), + blockNumber: log.blockNumber, + direction: "incoming" as MessageDirection, + decrypted: decryptedText, + read: false, + nonce: Number(nonce), + dedupKey, + type: "text" as MessageType, + ownerAddress: address, + status: "confirmed", + }; + + const updatedContact: Contact = { + ...contact, + lastMessage: decryptedText, + lastTimestamp: Date.now(), + }; + + // Persist to DB + const saved = await dbService.saveMessage(message); + if (saved) { + await dbService.upsertDedup({ + key: dedupKey, + messageId: message.id, + txHash: log.transactionHash, + blockNumber: log.blockNumber, + }); + await dbService.saveContact(updatedContact); + } + + onLog( + `๐Ÿ“ฉ Message from ${contact.address.slice(0, 8)}...: "${decryptedText}"` + ); + + return saved + ? { newMessage: message, contactUpdate: updatedContact } + : null; + } catch (error) { + onLog(`โœ— Failed to process message log: ${error}`); + return null; + } +} + +export async function persistSessionCache( + sessionCache: Map, + onLog: (msg: string) => void +): Promise { + if (sessionCache.size === 0) return; + + for (const [topic, session] of sessionCache) { + try { + await dbService.saveRatchetSession(session); + onLog(`๐Ÿ’พ Persisted session state for topic ${topic.slice(0, 10)}...`); + } catch (error) { + onLog( + `โœ— Failed to persist session for topic ${topic.slice(0, 10)}...: ${error}` + ); + } + } +} \ No newline at end of file diff --git a/apps/demo/src/types.ts b/apps/demo/src/types.ts index 8c7eb27..a1b763c 100644 --- a/apps/demo/src/types.ts +++ b/apps/demo/src/types.ts @@ -122,10 +122,7 @@ export interface StoredIdentity { emitterAddress?: string; // EOA for classic, Safe for fast/custom } -// ** -// * Stored ratchet session in IndexedDB. -// * Extends SDK RatchetSession with serialization-friendly format. -// */ +// Extends SDK RatchetSession with serialization-friendly format. export interface StoredRatchetSession { conversationId: string; topicOutbound: string; @@ -225,11 +222,14 @@ export interface MessageProcessorResult { pendingHandshakes: PendingHandshake[]; contacts: Contact[]; addMessage: (message: Message) => void; + updateMessageStatus: (id: string, status: Message["status"], error?: string) => Promise; + removeMessage: (id: string) => Promise; removePendingHandshake: (id: string) => void; updateContact: (contact: Contact) => void; processEvents: (events: ProcessedEvent[]) => Promise; } + export const generateTempMessageId = () => `temp-${Date.now()}-${Math.random()}`; // ============================================================================= diff --git a/apps/docs/double-ratchet.md b/apps/docs/double-ratchet.md index aacd12b..7923b5b 100644 --- a/apps/docs/double-ratchet.md +++ b/apps/docs/double-ratchet.md @@ -1,527 +1,219 @@ -# Double Ratchet Flow: Alice โ†” Bob +# VerbEth Double Ratchet Protocol -## Overview +## Core Design: Ephemeral-Only Initial Secret -``` -โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” -โ”‚ PROTOCOL PHASES โ”‚ -โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค -โ”‚ PHASE 1: Handshake (on-chain) โ†’ Establish identity + ephemeral keys โ”‚ -โ”‚ PHASE 2: Session Init (local) โ†’ Create RatchetSession from ephemerals โ”‚ -โ”‚ PHASE 3: Messaging (on-chain) โ†’ Encrypt/decrypt with ratchet โ”‚ -โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ -``` - ---- - -## Phase 1: Handshake (Existing Flow) +| | Signal X3DH | VerbEth | +|---|---|---| +| Initial secret | `DH(IKa,SPKb) โˆฅ DH(EKa,IKb) โˆฅ DH(EKa,SPKb)` | `DH(EKa, EKb)` | +| Identity keys in secret | Yes | No | +| First message | Encrypted | Plaintext handshake | +| Authentication | Mixed into DH | On-chain `msg.sender` + binding proof | +| Forward secrecy on identity compromise | Initial secret derivable | Initial secret independent | +| Prekey infrastructure | Required | None | -``` - ALICE (Initiator) BOB (Responder) - โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• - โ”‚ โ”‚ - โ”‚ 1. Generate ephemeral keypair โ”‚ - โ”‚ eA = (eA.secret, eA.public) โ”‚ - โ”‚ โ”‚ - โ”‚ 2. Create Handshake tx: โ”‚ - โ”‚ โ€ข recipientHash โ”‚ - โ”‚ โ€ข pubKeys (identity X25519 + Ed25519) โ”‚ - โ”‚ โ€ข ephemeralPubKey = eA.public โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–บ โ”‚ - โ”‚ โ€ข plaintextPayload + identityProof โ”‚ - โ”‚ โ”‚ - โ”‚ 3. Store eA.secret locally โ”‚ - โ”‚ (needed to derive session later) โ”‚ - โ”‚ โ”‚ - โ”‚ 4. Verify handshake - โ”‚ (signature, proof) - โ”‚ โ”‚ - โ”‚ 5. Generate ephemeral - โ”‚ eB = (eB.secret, eB.public) - โ”‚ โ”‚ - โ”‚ 6. Create HandshakeResponse: - โ”‚ โ€ข inResponseTo (tag) - โ”‚ โ—„โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ€ข responderEphemeralR = eB.public - โ”‚ โ€ข encrypted payload - โ”‚ โ”‚ - โ”‚ 7. โš ๏ธ STORE eB.secret - โ”‚ (becomes dhMySecretKey!) - โ”‚ โ”‚ - 8. Verify response โ”‚ - (decrypt, verify proof) โ”‚ - โ”‚ โ”‚ - โ”‚ โ”‚ - โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• - โ”‚ HANDSHAKE COMPLETE โ”‚ - โ”‚ Both have: eA.public, eB.public โ”‚ - โ”‚ Alice has: eA.secret โ”‚ - โ”‚ Bob has: eB.secret โ”‚ - โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• -``` +**The tradeoff:** By accepting a plaintext handshake, VerbEth gains unconditional forward secrecy from message 0 and trustless authentication via Ethereum's transaction model. -### On-Chain Data After Handshake +--- -``` -โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” -โ”‚ Handshake Event (from Alice's emitter) โ”‚ -โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค -โ”‚ โ€ข sender: Alice's Safe/EOA โ”‚ -โ”‚ โ€ข pubKeys: Alice's identity keys (X25519 + Ed25519) โ”‚ -โ”‚ โ€ข ephemeralPubKey: eA.public โ—„โ”€โ”€ Used for initial DH โ”‚ -โ”‚ โ€ข plaintextPayload: message + identity proof โ”‚ -โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ - -โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” -โ”‚ HandshakeResponse Event (from Bob's emitter) โ”‚ -โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค -โ”‚ โ€ข responder: Bob's Safe/EOA โ”‚ -โ”‚ โ€ข responderEphemeralR: eB.public โ—„โ”€โ”€ Bob's first DH key โ”‚ -โ”‚ โ€ข inResponseTo: tag (links to Alice's handshake) โ”‚ -โ”‚ โ€ข ciphertext: encrypted response โ”‚ -โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ -``` +## Session Model + +### What is a Session? + +A **RatchetSession** is the complete cryptographic state required for bidirectional encrypted messaging. It is: +- **Stateful**: Every encrypt/decrypt operation produces a new session state that must replace the old one +- **Keyed by `conversationId`**: Derived from `keccak256(sort([topicOut, topicIn]))`, not addressesโ€”this handles Safe vs EOA correctly +- **Bilateral**: Both parties maintain symmetric (but not identical) session states + +```typescript +interface RatchetSession { + // Identity + conversationId: string; // Primary key + topicOutbound: `0x${string}`; // My sending topic + topicInbound: `0x${string}`; // My receiving topic + + // Root ratchet + rootKey: Uint8Array; // Advances on every DH ratchet step + + // DH ratchet keys + dhMySecretKey: Uint8Array; // My current DH secret + dhMyPublicKey: Uint8Array; // Sent in message headers + dhTheirPublicKey: Uint8Array; // Their last received DH key + + // Sending chain + sendingChainKey: Uint8Array | null; + sendingMsgNumber: number; // Next message number (Ns) + + // Receiving chain + receivingChainKey: Uint8Array | null; + receivingMsgNumber: number; // Next expected (Nr) + + // Skip handling + previousChainLength: number; // PN header field + skippedKeys: SkippedKey[]; // For out-of-order decryption + + // Metadata + epoch: number; // Increments on session reset + status: SessionStatus; +} +``` + +### Session Initialization + +**Responder (Bob)** creates session when accepting handshake: +``` +sharedSecret = DH(bobEphemeral, aliceEphemeral) +rootKey, sendingChainKey = KDF(zeros, sharedSecret) +``` + +**Initiator (Alice)** creates session after receiving response: +``` +sharedSecret = DH(aliceEphemeral, bobRatchetEphemeral) // From INSIDE payload, not on-chain R +rootKey, bobsSendingChain = KDF(zeros, sharedSecret) +// Immediate DH ratchet step: +aliceDHKeyPair = generateDHKeyPair() +finalRootKey, sendingChainKey = KDF(rootKey, DH(aliceSecret, bobRatchetEphemeral)) +receivingChainKey = bobsSendingChain +``` + +Note: Bob's on-chain `responderEphemeralR` is used only for tag verification. His ratchet ephemeral is inside the encrypted payloadโ€”this provides **unlinkability** between the HandshakeResponse and subsequent messages. --- -## Phase 2 (local): Session Initialization +## SDK vs App Layer Responsibilities -### Initial Shared Secret (Ephemeral-Only!) +| Concern | SDK (`@verbeth/sdk/ratchet`) | App Layer | +|---------|------------------------------|-----------| +| Session state | Produces new immutable session on each operation | Persists session to IndexedDB, manages cache | +| Encryption | `ratchetEncrypt()` โ†’ returns `{session, header, ciphertext, signature}` | Decides when to commit session state | +| Decryption | `ratchetDecrypt()` โ†’ returns `{session, plaintext}` or null | Handles signature verification first | +| Skip keys | Creates/uses/prunes skip keys automatically | Calls `pruneExpiredSkippedKeys()` periodically | +| DoS protection | Provides `verifyMessageSignature()` | Must call before any ratchet operation | +| Two-phase commit | Returns new session without mutating input | Implements commit/rollback logic | +| Concurrent access | None (pure functions) | Must serialize per-conversation | +| Transaction failures | N/A | Decides whether to burn slot or rollback | +| Message queue | N/A | Sequential processing per conversation | -``` -โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” -โ”‚ CRITICAL: NO IDENTITY KEYS IN DH โ”‚ -โ”‚ โ”‚ -โ”‚ sharedSecret = DH(eA.secret, eB.public) // Alice computes โ”‚ -โ”‚ = DH(eB.secret, eA.public) // Bob computes (same result) โ”‚ -โ”‚ โ”‚ -โ”‚ WHY: Compromise of identity keys NEVER decrypts past messages โ”‚ -โ”‚ (not even message #0) โ”‚ -โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ -``` +--- -### Bob's Session Init (Responder - happens first) +## Edge Cases and Crypto Safety -``` - BOB (initSessionAsResponder) - โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• - - INPUT: - โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” - โ”‚ myResponderEphemeralSecret: eB.secretโ”‚ - โ”‚ myResponderEphemeralPublic: eB.publicโ”‚ - โ”‚ theirHandshakeEphemeralPubKey: eA.publicโ”‚ - โ”‚ topicOutbound, topicInbound โ”‚ - โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ - - DERIVATION: - - sharedSecret = DH(eB.secret, eA.public) - โ”‚ - โ–ผ - โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” - โ”‚ KDF_RK(zeros, sharedSecret) โ”‚ - โ”‚ โ†’ rootKeyโ‚€ โ”‚ - โ”‚ โ†’ sendingChainKeyโ‚€ โ”‚ - โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ - - OUTPUT SESSION: - โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” - โ”‚ rootKey: rootKeyโ‚€ โ”‚ - โ”‚ dhMySecretKey: eB.secret โ—„โ”€โ”€ REUSEโ”‚ - โ”‚ dhMyPublicKey: eB.public โ”‚ - โ”‚ dhTheirPublicKey: eA.public โ”‚ - โ”‚ sendingChainKey: sendingChainKeyโ‚€ โ”‚ - โ”‚ sendingMsgNumber: 0 โ”‚ - โ”‚ receivingChainKey: null โ—„โ”€โ”€ Not yetโ”‚ - โ”‚ receivingMsgNumber: 0 โ”‚ - โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ - - Bob can SEND immediately, but cannot RECEIVE - until Alice sends (with her new DH key) -``` +### Edge Case 1: Out-of-Order Messages -### Alice's Session Init (Initiator - happens after receiving response) +**Scenario:** Bob sends messages 0, 1, 2. Alice receives 2, then 0, then 1. +**SDK handling:** ``` - ALICE (initSessionAsInitiator) - โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• - - INPUT: - โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” - โ”‚ myHandshakeEphemeralSecret: eA.secretโ”‚ - โ”‚ theirResponderEphemeralPubKey: eB.publicโ”‚ - โ”‚ topicOutbound, topicInbound โ”‚ - โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ - - DERIVATION: - - 1. Same initial secret as Bob: - sharedSecret = DH(eA.secret, eB.public) - โ”‚ - โ–ผ - KDF_RK(zeros, sharedSecret) โ†’ rootKeyโ‚€, bobsSendingChain - - 2. Generate NEW DH keypair for Alice: - dh1 = generateDHKeyPair() โ†’ (dh1.secret, dh1.public) - - 3. Perform sending ratchet step: - dhSend = DH(dh1.secret, eB.public) - โ”‚ - โ–ผ - KDF_RK(rootKeyโ‚€, dhSend) โ†’ rootKeyโ‚, aliceSendingChain - - OUTPUT SESSION: - โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” - โ”‚ rootKey: rootKeyโ‚ โ”‚ - โ”‚ dhMySecretKey: dh1.secret โ—„โ”€โ”€ NEW โ”‚ - โ”‚ dhMyPublicKey: dh1.public โ”‚ - โ”‚ dhTheirPublicKey: eB.public โ”‚ - โ”‚ sendingChainKey: aliceSendingChain โ”‚ - โ”‚ sendingMsgNumber: 0 โ”‚ - โ”‚ receivingChainKey: bobsSendingChain โ”‚โ—„โ”€โ”€ Can receive Bob's msgs! - โ”‚ receivingMsgNumber: 0 โ”‚ - โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ - - Alice can SEND and RECEIVE immediately -``` +Receive msg 2 (n=2, expected Nr=0): + โ†’ Skip n=0,1: derive and store skip keys for both + โ†’ Decrypt msg 2 with derived key for n=2 + โ†’ Update: Nr=3, skippedKeys=[{n:0}, {n:1}] -### Session State After Init +Receive msg 0: + โ†’ Found in skippedKeys โ†’ decrypt, remove from list -``` - โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” - โ”‚ ALICE SESSION โ”‚ โ”‚ BOB SESSION โ”‚ - โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค - โ”‚ dhMyPub: dh1.public โ”‚ โ”‚ dhMyPub: eB.public โ”‚ - โ”‚ dhTheirPub: eB.public โ”‚ โ”‚ dhTheirPub: eA.public โ”‚ - โ”‚ โ”‚ โ”‚ โ”‚ - โ”‚ sendingChain: โœ“ โ”‚ โ”‚ sendingChain: โœ“ โ”‚ - โ”‚ receivingChain: โœ“ โ”‚ โ”‚ receivingChain: null โ”‚ - โ”‚ โ”‚ โ”‚ โ”‚ - โ”‚ Can send: YES โ”‚ โ”‚ Can send: YES โ”‚ - โ”‚ Can receive: YES โ”‚ โ”‚ Can receive: NO* โ”‚ - โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ - - * Bob's receivingChain is established when Alice sends her first message - (which includes dh1.public in the header) +Receive msg 1: + โ†’ Found in skippedKeys โ†’ decrypt, remove from list ``` ---- +**Bounds:** +- `MAX_SKIP_PER_MESSAGE = 100,000` โ€” rejects messages requiring more skips +- `MAX_STORED_SKIPPED_KEYS = 1,000` โ€” oldest pruned when exceeded +- `MAX_SKIPPED_KEYS_AGE_MS = 24h` โ€” expired keys pruned -## Phase 3: Message Exchange +### Edge Case 2: Burned Slots (Failed Sends) -### Message Format (Binary) - -``` -โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” -โ”‚ Offset โ”‚ Size โ”‚ Field โ”‚ -โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค -โ”‚ 0 โ”‚ 1 โ”‚ Version (0x01) โ”‚ -โ”‚ 1 โ”‚ 64 โ”‚ Ed25519 signature (over header + ciphertext) โ”‚ -โ”‚ 65 โ”‚ 32 โ”‚ DH ratchet public key (sender's current) โ”‚ -โ”‚ 97 โ”‚ 4 โ”‚ pn (previous chain length) โ”‚ -โ”‚ 101 โ”‚ 4 โ”‚ n (message number in current chain) โ”‚ -โ”‚ 105 โ”‚ var โ”‚ nonce (24) + secretbox ciphertext โ”‚ -โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ -``` +**Scenario:** Bob encrypts messages 0, 1, 2. Message 1's tx fails. Alice only receives 0 and 2. -### Scenario 1: Alice Sends First Message +**Why rollback is forbidden:** Rolling back session state would reuse encryption keysโ€”a critical security violation. Each key must be used exactly once. -``` - ALICE BOB - โ•โ•โ•โ•โ• โ•โ•โ• - โ”‚ โ”‚ - โ”‚ ratchetEncrypt(session, "Hello Bob!") โ”‚ - โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ - โ”‚ โ”‚ 1. KDF_CK(sendingChainKey) โ”‚ โ”‚ - โ”‚ โ”‚ โ†’ newChainKey, messageKey โ”‚ โ”‚ - โ”‚ โ”‚ โ”‚ โ”‚ - โ”‚ โ”‚ 2. Header: โ”‚ โ”‚ - โ”‚ โ”‚ dh = dh1.public โ”‚ โ”‚ - โ”‚ โ”‚ pn = 0 โ”‚ โ”‚ - โ”‚ โ”‚ n = 0 โ”‚ โ”‚ - โ”‚ โ”‚ โ”‚ โ”‚ - โ”‚ โ”‚ 3. Encrypt with messageKey โ”‚ โ”‚ - โ”‚ โ”‚ 4. Sign(header || ciphertext) โ”‚ โ”‚ - โ”‚ โ”‚ 5. session.sendingMsgNumber = 1 โ”‚ โ”‚ - โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ - โ”‚ โ”‚ - โ”‚ โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• ON-CHAIN TX โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ–บ โ”‚ - โ”‚ Message event on Alice's topicOutbound โ”‚ - โ”‚ โ”‚ - โ”‚ verifySignature() - โ”‚ โœ“ Valid โ”‚ - โ”‚ โ”‚ - โ”‚ ratchetDecrypt() - โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” - โ”‚ โ”‚ 1. header.dh โ‰  dhTheirPub? โ”‚ - โ”‚ โ”‚ YES! (dh1.public โ‰  eA.public) โ”‚ - โ”‚ โ”‚ โ”‚ - โ”‚ โ”‚ 2. DH Ratchet Step: โ”‚ - โ”‚ โ”‚ dhRecv = DH(eB.secret, dh1.pub) โ”‚ - โ”‚ โ”‚ KDF_RK โ†’ rootKey', recvChain โ”‚ - โ”‚ โ”‚ โ”‚ - โ”‚ โ”‚ Generate new DH: โ”‚ - โ”‚ โ”‚ dh2 = generateDHKeyPair() โ”‚ - โ”‚ โ”‚ โ”‚ - โ”‚ โ”‚ dhSend = DH(dh2.secret, dh1.pub)โ”‚ - โ”‚ โ”‚ KDF_RK โ†’ rootKey'', sendChain โ”‚ - โ”‚ โ”‚ โ”‚ - โ”‚ โ”‚ 3. KDF_CK(recvChain) โ†’ messageKey โ”‚ - โ”‚ โ”‚ 4. Decrypt โ†’ "Hello Bob!" โ”‚ - โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ - โ”‚ โ”‚ -``` +**App layer handling (matches Signal):** +```typescript +// useMessageQueue.ts +const { session: nextSession, ... } = ratchetEncrypt(currentSession, plaintext, signingKey); -### Session State After Alice's First Message +// Commit IMMEDIATELY, before tx submission +currentSession = nextSession; +await dbService.saveRatchetSession(nextSession); -``` - โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” - โ”‚ ALICE SESSION โ”‚ โ”‚ BOB SESSION โ”‚ - โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค - โ”‚ dhMyPub: dh1.public โ”‚ โ”‚ dhMyPub: dh2.public โ—„NEW โ”‚ - โ”‚ dhTheirPub: eB.public โ”‚ โ”‚ dhTheirPub: dh1.public โ”‚ - โ”‚ โ”‚ โ”‚ โ”‚ - โ”‚ sendingMsgNumber: 1 โ”‚ โ”‚ sendingMsgNumber: 0 โ”‚ - โ”‚ receivingMsgNumber: 0 โ”‚ โ”‚ receivingMsgNumber: 1 โ”‚ - โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ +try { + await sendTransaction(payload); +} catch { + // Slot is "burned" โ€” do NOT rollback + // Receiver will create an orphan skip key for n=1 +} ``` -### Scenario 2: Bob Replies +**Receiver impact:** Alice creates a skip key for n=1 that will never be used. This skip key expires after 24h and is pruned. -``` - ALICE BOB - โ•โ•โ•โ•โ• โ•โ•โ• - โ”‚ โ”‚ - โ”‚ ratchetEncrypt("Hi Alice!") - โ”‚ Header: โ”‚ - โ”‚ dh = dh2.public - โ”‚ pn = 0 โ”‚ - โ”‚ n = 0 โ”‚ - โ”‚ โ”‚ - โ”‚ โ—„โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• ON-CHAIN TX โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• โ”‚ - โ”‚ โ”‚ - โ”‚ verifySignature() โœ“ โ”‚ - โ”‚ โ”‚ - โ”‚ ratchetDecrypt() โ”‚ - โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ - โ”‚ โ”‚ header.dh โ‰  dhTheirPub? โ”‚ โ”‚ - โ”‚ โ”‚ YES! (dh2.public โ‰  eB.public) โ”‚ โ”‚ - โ”‚ โ”‚ โ”‚ โ”‚ - โ”‚ โ”‚ DH Ratchet Step: โ”‚ โ”‚ - โ”‚ โ”‚ Generate dh3 โ”‚ โ”‚ - โ”‚ โ”‚ Update chains โ”‚ โ”‚ - โ”‚ โ”‚ โ”‚ โ”‚ - โ”‚ โ”‚ Decrypt โ†’ "Hi Alice!" โ”‚ โ”‚ - โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ - โ”‚ โ”‚ -``` +### Edge Case 3: Retry with New Message Number -### Scenario 3: Multiple Messages Same Direction (No DH Ratchet) +**Scenario:** Message "Hello" fails at n=1. User retries. It now encrypts at n=3. -``` - BOB sends 3 messages without Alice replying: - - Message 1: header.dh = dh2.public, n = 0 - Message 2: header.dh = dh2.public, n = 1 โ—„โ”€โ”€ Same DH key! - Message 3: header.dh = dh2.public, n = 2 - - Alice receives in order: - - No DH ratchet needed (same header.dh) - - Just advance receivingChainKey for each message -``` +**This is safe because:** +1. Each slot gets a unique key from chain ratchet +2. Receiver handles gaps via skip keys +3. No cryptographic material is reused +4. Message content can repeat; key material cannot ---- +**App consideration:** UI should sort by `blockTimestamp`, not message number. The retry appears in chronological order regardless of its `n` value. -## Edge Cases +### Edge Case 4: DH Ratchet Advancement -### Edge Case 1: Out-of-Order Messages (Skip Keys) +**Scenario:** Alice and Bob alternate messages (ping-pong pattern). +**What happens:** ``` - BOB sends: Msg0, Msg1, Msg2 - - ALICE receives in order: Msg2, Msg0, Msg1 - - โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” - โ”‚ RECEIVE Msg2 (n=2, but Alice expects n=0) โ”‚ - โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค - โ”‚ 1. header.n (2) > receivingMsgNumber (0) โ”‚ - โ”‚ 2. Skip messages 0 and 1: โ”‚ - โ”‚ - Derive messageKeyโ‚€, store in skippedKeys โ”‚ - โ”‚ - Derive messageKeyโ‚, store in skippedKeys โ”‚ - โ”‚ 3. Derive messageKeyโ‚‚, decrypt Msg2 โ”‚ - โ”‚ 4. receivingMsgNumber = 3 โ”‚ - โ”‚ โ”‚ - โ”‚ skippedKeys = [ โ”‚ - โ”‚ { dhPubKeyHex: "0x...", msgNumber: 0, messageKey: keyโ‚€ }, โ”‚ - โ”‚ { dhPubKeyHex: "0x...", msgNumber: 1, messageKey: keyโ‚ }, โ”‚ - โ”‚ ] โ”‚ - โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ - - โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” - โ”‚ RECEIVE Msg0 (n=0, using skip key) โ”‚ - โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค - โ”‚ 1. Look up in skippedKeys: found! โ”‚ - โ”‚ 2. Decrypt with stored messageKeyโ‚€ โ”‚ - โ”‚ 3. Remove keyโ‚€ from skippedKeys โ”‚ - โ”‚ 4. Session state unchanged (no chain advance) โ”‚ - โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ - - โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” - โ”‚ RECEIVE Msg1 (n=1, using skip key) โ”‚ - โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค - โ”‚ Same process, use stored messageKeyโ‚ โ”‚ - โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ +Bobโ†’Alice (msg 0): header.dh = BobDHโ‚€ +Aliceโ†’Bob (msg 0): header.dh = AliceDHโ‚ (new keypair!) + โ†’ Bob performs DH ratchet: new rootKey, new chains +Bobโ†’Alice (msg 0): header.dh = BobDHโ‚ (new keypair!) + โ†’ Alice performs DH ratchet ``` -### Edge Case 2: DH Ratchet + Skip Keys Combined +Each direction change triggers a DH ratchet step, advancing forward secrecy. Even if an attacker compromises current keys, past messages remain protected. -``` - Scenario: - - Bob sends Msg0, Msg1 with dh2.public - - Alice replies (triggers Bob's DH ratchet to dh3) - - Bob sends Msg0', Msg1' with dh3.public - - Alice receives: Msg1' (new epoch), Msg0 (old epoch) - - โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” - โ”‚ RECEIVE Msg1' (new dh3.public, n=1) โ”‚ - โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค - โ”‚ 1. header.dh (dh3) โ‰  dhTheirPub (dh2) โ†’ DH ratchet! โ”‚ - โ”‚ 2. But first: skip remaining msgs from OLD epoch (dh2) โ”‚ - โ”‚ header.pn = 2 means Bob sent 2 msgs on old chain โ”‚ - โ”‚ Alice received 0, so skip Msg0, Msg1 from old epoch โ”‚ - โ”‚ Store their keys tagged with dh2.public โ”‚ - โ”‚ 3. Perform DH ratchet (new receivingChain for dh3) โ”‚ - โ”‚ 4. Skip Msg0' in new epoch (n=1, expect n=0) โ”‚ - โ”‚ Store key tagged with dh3.public โ”‚ - โ”‚ 5. Decrypt Msg1' โ”‚ - โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ - - โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” - โ”‚ RECEIVE Msg0 (old dh2.public, n=0) โ”‚ - โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค - โ”‚ 1. Look up skippedKeys by (dh2.public, n=0) โ”‚ - โ”‚ 2. Found! Decrypt with stored key โ”‚ - โ”‚ 3. Remove from skippedKeys โ”‚ - โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ -``` +### Edge Case 5: Concurrent Sends (App Layer) -### Edge Case 3: Invalid Signature (DoS Attack) +**Scenario:** User clicks send twice rapidly, or sends from multiple tabs. -``` - ATTACKER posts garbage message to Alice's topicInbound - - โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” - โ”‚ ALICE PROCESSING โ”‚ - โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค - โ”‚ 1. parseRatchetPayload() โ†’ parsed โ”‚ - โ”‚ 2. verifyMessageSignature(sig, header, ct, bob.signingPubKey) โ”‚ - โ”‚ โ†’ FALSE โœ— โ”‚ - โ”‚ 3. REJECT immediately โ”‚ - โ”‚ - No ratchet operations performed โ”‚ - โ”‚ - No state changes โ”‚ - โ”‚ - O(1) cost (just signature verify) โ”‚ - โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ - - PROTECTION: Even if attacker sets header.n = 999999, we never - reach the skip key derivation loop because signature fails first. -``` +**Risk:** Two encryptions read the same session state, both produce n=5, one overwrites the other's session update. -### Edge Case 4: Transaction Failure (Two-Phase Commit) +**App layer solution:** +```typescript +// useMessageQueue.ts - per-conversation queue +const queuesRef = useRef>(new Map()); -``` - ALICE tries to send message - - โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” - โ”‚ SEND FLOW WITH TWO-PHASE COMMIT โ”‚ - โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค - โ”‚ 1. Load session (sendingMsgNumber = 5) โ”‚ - โ”‚ โ”‚ - โ”‚ 2. ratchetEncrypt() returns: โ”‚ - โ”‚ - NEW session object (sendingMsgNumber = 6) โ”‚ - โ”‚ - Original session UNCHANGED โ”‚ - โ”‚ โ”‚ - โ”‚ 3. Create PendingOutbound: โ”‚ - โ”‚ { sessionBefore: original, sessionAfter: new } โ”‚ - โ”‚ โ”‚ - โ”‚ 4. Send transaction... โ”‚ - โ”‚ โ”‚ - โ”‚ IF TX SUCCEEDS: IF TX FAILS: โ”‚ - โ”‚ โ”œโ”€ See event on-chain โ”œโ”€ Delete PendingOutbound โ”‚ - โ”‚ โ”œโ”€ Commit sessionAfter to DB โ”œโ”€ Session state = original โ”‚ - โ”‚ โ””โ”€ Delete PendingOutbound โ””โ”€ User can retry โ”‚ - โ”‚ sendingMsgNumber = 6 sendingMsgNumber = 5 โ”‚ - โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ +// Sequential processing +while (queue.messages.length > 0) { + const message = queue.messages[0]; + const { session: nextSession } = ratchetEncrypt(currentSession, ...); + currentSession = nextSession; // In-memory update + await dbService.saveRatchetSession(nextSession); // Persist + // ... send tx + queue.messages.shift(); +} ``` -### Edge Case 5: Sequential Blocking (Prevent State Corruption) +**Critical:** The in-memory session cache (`sessionCacheRef`) must persist across `processQueue` invocations to prevent race conditions. -``` - ALICE tries to send Msg A, then immediately Msg B - - โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” - โ”‚ PROBLEM WITHOUT BLOCKING โ”‚ - โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค - โ”‚ 1. Send Msg A: state 0 โ†’ 1, PendingA created โ”‚ - โ”‚ 2. Send Msg B: state 1 โ†’ 2, PendingB created โ”‚ - โ”‚ 3. TX A FAILS โ”‚ - โ”‚ 4. TX B SUCCEEDS (Bob receives it!) โ”‚ - โ”‚ โ”‚ - โ”‚ If we rollback to state 0: โ”‚ - โ”‚ - We've lost the keys for Msg B โ”‚ - โ”‚ - Bob has Msg B but we can't continue โ”‚ - โ”‚ - PERMANENT DESYNC โ”‚ - โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ - - โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” - โ”‚ SOLUTION: SEQUENTIAL BLOCKING โ”‚ - โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค - โ”‚ 1. Send Msg A: PendingA created โ”‚ - โ”‚ 2. Try to send Msg B: CHECK getPendingByConversation() โ”‚ - โ”‚ โ†’ PendingA exists! โ”‚ - โ”‚ โ†’ BLOCK: "Wait for previous message to confirm" โ”‚ - โ”‚ 3. TX A confirms (or fails) โ”‚ - โ”‚ 4. NOW Alice can send Msg B โ”‚ - โ”‚ โ”‚ - โ”‚ INVARIANT: At most ONE pending outbound per conversation โ”‚ - โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ -``` +### Edge Case 6: Session Reset (Not Yet Implemented) -### Edge Case 6: Session Lost (Reset Required) +**Scenario:** Keys compromised, or session state corrupted. Need fresh start. -``` - ALICE clears browser storage or switches device - - โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” - โ”‚ DETECTION โ”‚ - โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค - โ”‚ 1. Alice loads app, identity re-derived from wallet signature โ”‚ - โ”‚ 2. Check for RatchetSession with Bob: NOT FOUND โ”‚ - โ”‚ 3. Contact exists but no session โ†’ SESSION LOST โ”‚ - โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ - - โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” - โ”‚ RECOVERY: SESSION RESET PROTOCOL โ”‚ - โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค - โ”‚ 1. Alice sends NEW handshake to Bob โ”‚ - โ”‚ (marked as reset, not first contact) โ”‚ - โ”‚ โ”‚ - โ”‚ 2. Bob sees: "Alice requests new session" โ”‚ - โ”‚ - Warning: "Messages since [date] may be unreadable by Alice" โ”‚ - โ”‚ โ”‚ - โ”‚ 3. Bob accepts โ†’ NEW session with NEW topics โ”‚ - โ”‚ - Old session marked 'inactive_superseded' โ”‚ - โ”‚ - Old messages still viewable (if cached) โ”‚ - โ”‚ โ”‚ - โ”‚ 4. Both continue with fresh ratchet state โ”‚ - โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ - - โš ๏ธ TRADEOFF: Messages sent by Bob after Alice lost state and before +**Planned approach:** +1. Mark current session as `inactive_reset` +2. Initiate new handshake with fresh ephemeral +3. New session gets incremented `epoch` +4. Old `conversationId` moves to `previousConversationId` on Contact + +**Why epoch matters:** Allows distinguishing messages from old vs new session during transition period. +โš ๏ธ TRADEOFF: Messages sent by Bob after Alice lost state and before Alice reset are PERMANENTLY LOST from Alice's perspective. This is inherent to forward secrecy. -``` --- -## State Machine Summary +### State Machine Summary ``` โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” @@ -553,14 +245,91 @@ --- -## Key Invariants - -| Invariant | Description | -|-----------|-------------| -| **Auth First** | Always `verifyMessageSignature()` before `ratchetDecrypt()` | -| **Immutable Ops** | `ratchetEncrypt/Decrypt` return NEW session, never mutate | -| **Sequential Send** | Max 1 `PendingOutbound` per conversation | -| **Topics = Identity** | Session keyed by `conversationId` (from topics), not addresses | -| **Ephemeral Init** | Initial secret from ephemeral-only DH, no identity keys | -| **Skip Key TTL** | Skipped keys pruned after 24h | -| **Skip Key Cap** | Max 1000 stored skipped keys per session | \ No newline at end of file +## DoS Protection via Signatures + +### The Problem + +Without signatures, an attacker controls how much work you do: +``` +Attacker posts: header = {dh: garbage, pn: 999999, n: 999999} +Victim reads header โ†’ derives ~1M skip keys โ†’ then AEAD fails +Cost: O(N) where attacker controls N +``` + +### The Solution + +Ed25519 signatures are mandatory on all ratchet messages: +``` +Payload = [version (1)] [signature (64)] [dh (32)] [pn (4)] [n (4)] [ciphertext (var)] +``` + +**Verification order:** +```typescript +// App layer MUST do this first +const sigValid = verifyMessageSignature(signature, header, ciphertext, contactSigningPubKey); +if (!sigValid) return; // O(1) rejection, no ratchet operations + +// Only then touch ratchet state +const result = ratchetDecrypt(session, header, ciphertext); +``` + +**Cost comparison:** + +| Attack | Without signatures | With signatures | +|--------|-------------------|-----------------| +| Garbage payload | O(N) skip key derivations | O(1) signature verify | +| Wrong sender | O(N) then AEAD fail | O(1) reject | +| Replay | Depends on n value | O(1) reject (wrong sig) | + +--- + +## Binary Payload Format + +``` +Offset Size Field +โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ +0 1 Version (0x01) +1 64 Ed25519 signature +65 32 DH ratchet public key +97 4 pn (uint32 BE) - previous chain length +101 4 n (uint32 BE) - message number +105 var Ciphertext (nonce + XSalsa20-Poly1305 output) +``` + +Minimum payload: 105 bytes + ciphertext. + +--- + +## KDF Specifications + +**Root key derivation (on DH ratchet step):** +``` +KDF_RK(rk, dh_out) = HKDF-SHA256(ikm=dh_out, salt=rk, info="VerbethRatchet", len=64) + โ†’ new_rk = output[0:32], chain_key = output[32:64] +``` + +**Chain key derivation (per message):** +``` +KDF_CK(ck) = (HMAC-SHA256(ck, 0x02), HMAC-SHA256(ck, 0x01)) + โ†’ new_chain_key, message_key +``` + +**Message encryption:** XSalsa20-Poly1305 (NaCl secretbox) + +--- + +## Summary: What Makes VerbEth Different + +1. **Ephemeral-only initial secret** โ€” No identity keys in DH means unconditional forward secrecy from message 0 + +2. **Trustless authentication** โ€” `msg.sender` is a protocol guarantee; binding proofs tie keys to addresses cryptographically + +3. **No prekey infrastructure** โ€” Bob's ephemeral comes from his live response, not a pre-published bundle + +4. **Burned slots, not rollbacks** โ€” Failed sends consume their slot; receiver's skip keys handle gaps (matches Signal) + +5. **Signatures for DoS protection** โ€” Auth-before-ratchet prevents O(N) attacks from unauthenticated messages + +6. **Session by conversation, not address** โ€” `conversationId` from topics handles Safe/EOA correctly + + diff --git a/packages/sdk/test/executor.test.ts b/packages/sdk/test/executor.test.ts index ccf3ee7..ab3b958 100644 --- a/packages/sdk/test/executor.test.ts +++ b/packages/sdk/test/executor.test.ts @@ -53,7 +53,6 @@ const mockSigner = { // Test data const testRecipientKey = nacl.box.keyPair(); -const testSenderSignKey = nacl.sign.keyPair(); const testIdentityKeyPair: IdentityKeyPair = { publicKey: new Uint8Array(32).fill(1), secretKey: new Uint8Array(32).fill(2), diff --git a/packages/sdk/test/ratchet.test.ts b/packages/sdk/test/ratchet.test.ts index c1477a5..9e4b340 100644 --- a/packages/sdk/test/ratchet.test.ts +++ b/packages/sdk/test/ratchet.test.ts @@ -3,31 +3,22 @@ import { describe, it, expect, beforeEach } from "vitest"; import nacl from "tweetnacl"; import { - // Session initSessionAsResponder, initSessionAsInitiator, computeConversationId, - // Encrypt/Decrypt ratchetEncrypt, ratchetDecrypt, pruneExpiredSkippedKeys, - // Codec packageRatchetPayload, parseRatchetPayload, isRatchetPayload, hexToBytes, bytesToHex, - // Auth verifyMessageSignature, - // KDF generateDHKeyPair, - // Types RatchetSession, } from "../src/ratchet/index.js"; -// ============================================================================= -// Test Helpers -// ============================================================================= function createTestTopics(): { topicOut: `0x${string}`; topicIn: `0x${string}` } { const randomBytes = nacl.randomBytes(32); @@ -47,7 +38,6 @@ function createSigningKeyPair() { describe("Double Ratchet", () => { describe("Session Initialization", () => { it("should create matching sessions for responder and initiator", () => { - // Simulate handshake ephemeral keys const aliceEphemeral = generateDHKeyPair(); const bobEphemeral = generateDHKeyPair(); const topics = createTestTopics(); @@ -266,13 +256,12 @@ describe("Double Ratchet", () => { expect(isRatchetPayload(validPayload)).toBe(true); - // Legacy JSON would start with { (0x7b) const jsonPayload = new TextEncoder().encode('{"v":1}'); expect(isRatchetPayload(jsonPayload)).toBe(false); }); it("should reject truncated payloads", () => { - const truncated = new Uint8Array(50); // Less than minimum 105 bytes + const truncated = new Uint8Array(50); truncated[0] = 0x01; expect(parseRatchetPayload(truncated)).toBeNull(); @@ -428,10 +417,10 @@ describe("Double Ratchet", () => { status: "active", }; - const pruned = pruneExpiredSkippedKeys(session, 50000); // 50 second TTL for test + const pruned = pruneExpiredSkippedKeys(session, 50000); expect(pruned.skippedKeys.length).toBe(1); - expect(pruned.skippedKeys[0].msgNumber).toBe(0); // Fresh one remains + expect(pruned.skippedKeys[0].msgNumber).toBe(0); }); it("should convert hex to bytes and back", () => { diff --git a/packages/sdk/test/simulation.test.ts b/packages/sdk/test/simulation.test.ts new file mode 100644 index 0000000..3b02028 --- /dev/null +++ b/packages/sdk/test/simulation.test.ts @@ -0,0 +1,709 @@ +// packages/sdk/test/simulation.test.ts + +/** + * These tests simulate real-world conditions that occur at the application + * layer, particularly around message queue processing and transaction failures. + */ + +import { describe, it, expect } from "vitest"; +import nacl from "tweetnacl"; +import { + initSessionAsResponder, + initSessionAsInitiator, + ratchetEncrypt, + ratchetDecrypt, + pruneExpiredSkippedKeys, + hexToBytes, + bytesToHex, + generateDHKeyPair, + RatchetSession, + MAX_STORED_SKIPPED_KEYS, +} from "../src/ratchet/index.js"; + +function createTestTopics(): { topicOut: `0x${string}`; topicIn: `0x${string}` } { + const randomBytes = nacl.randomBytes(32); + const topicOut = bytesToHex(randomBytes) as `0x${string}`; + const topicIn = bytesToHex(nacl.randomBytes(32)) as `0x${string}`; + return { topicOut, topicIn }; +} + +function createSigningKeyPair() { + return nacl.sign.keyPair(); +} + +/** + * Helper to create a pair of initialized sessions (Alice & Bob) + */ +function createSessionPair(): { + aliceSession: RatchetSession; + bobSession: RatchetSession; + aliceSigning: nacl.SignKeyPair; + bobSigning: nacl.SignKeyPair; +} { + const aliceEphemeral = generateDHKeyPair(); + const bobEphemeral = generateDHKeyPair(); + const topics = createTestTopics(); + + const bobSession = initSessionAsResponder({ + myAddress: "0xBob", + contactAddress: "0xAlice", + myResponderEphemeralSecret: bobEphemeral.secretKey, + myResponderEphemeralPublic: bobEphemeral.publicKey, + theirHandshakeEphemeralPubKey: aliceEphemeral.publicKey, + topicOutbound: topics.topicIn, + topicInbound: topics.topicOut, + }); + + const aliceSession = initSessionAsInitiator({ + myAddress: "0xAlice", + contactAddress: "0xBob", + myHandshakeEphemeralSecret: aliceEphemeral.secretKey, + theirResponderEphemeralPubKey: bobEphemeral.publicKey, + topicOutbound: topics.topicOut, + topicInbound: topics.topicIn, + }); + + return { + aliceSession, + bobSession, + aliceSigning: createSigningKeyPair(), + bobSigning: createSigningKeyPair(), + }; +} + +/** + * Simulate serialization round-trip (as would happen with IndexedDB storage) + */ +function simulateDbRoundTrip(session: RatchetSession): RatchetSession { + // Convert Uint8Arrays to hex (as StoredRatchetSession does) + const serialized = { + ...session, + rootKey: bytesToHex(session.rootKey), + dhMySecretKey: bytesToHex(session.dhMySecretKey), + dhMyPublicKey: bytesToHex(session.dhMyPublicKey), + dhTheirPublicKey: bytesToHex(session.dhTheirPublicKey), + sendingChainKey: session.sendingChainKey ? bytesToHex(session.sendingChainKey) : null, + receivingChainKey: session.receivingChainKey ? bytesToHex(session.receivingChainKey) : null, + skippedKeys: session.skippedKeys.map(sk => ({ + ...sk, + messageKey: bytesToHex(sk.messageKey), + })), + }; + + // Simulate JSON serialization (what actually happens in storage) + const json = JSON.stringify(serialized); + const parsed = JSON.parse(json); + + // Convert back to Uint8Arrays (as deserializeRatchetSession does) + return { + ...parsed, + rootKey: hexToBytes(parsed.rootKey), + dhMySecretKey: hexToBytes(parsed.dhMySecretKey), + dhMyPublicKey: hexToBytes(parsed.dhMyPublicKey), + dhTheirPublicKey: hexToBytes(parsed.dhTheirPublicKey), + sendingChainKey: parsed.sendingChainKey ? hexToBytes(parsed.sendingChainKey) : null, + receivingChainKey: parsed.receivingChainKey ? hexToBytes(parsed.receivingChainKey) : null, + skippedKeys: parsed.skippedKeys.map((sk: any) => ({ + ...sk, + messageKey: hexToBytes(sk.messageKey), + })), + }; +} + +describe("App Layer Simulation", () => { + describe("Burned Slots from Failed Sends", () => { + it("should handle burned slots when middle message fails to send", () => { + const { aliceSession: initialAlice, bobSession: initialBob, bobSigning } = createSessionPair(); + let bobSession = initialBob; + let aliceSession = initialAlice; + + // Bob encrypts 3 messages + const enc1 = ratchetEncrypt( + bobSession, + new TextEncoder().encode("Message 1"), + bobSigning.secretKey + ); + bobSession = enc1.session; // n=0 used, now n=1 + + // Message 2 encrypts but TX FAILS (simulated) + const enc2 = ratchetEncrypt( + bobSession, + new TextEncoder().encode("Message 2 - WILL FAIL"), + bobSigning.secretKey + ); + bobSession = enc2.session; // n=1 used (burned!), now n=2 + // enc2 is never sent to Alice - tx failed + + const enc3 = ratchetEncrypt( + bobSession, + new TextEncoder().encode("Message 3"), + bobSigning.secretKey + ); + bobSession = enc3.session; // n=2 used, now n=3 + + // Verify Bob's session advanced correctly despite failure + expect(bobSession.sendingMsgNumber).toBe(3); + + // Alice only receives messages 1 and 3 (message 2 was never sent) + const dec1 = ratchetDecrypt(aliceSession, enc1.header, enc1.ciphertext); + expect(dec1).not.toBeNull(); + expect(new TextDecoder().decode(dec1!.plaintext)).toBe("Message 1"); + aliceSession = dec1!.session; + + // When Alice receives message 3 (n=2), she creates a skip key for n=1 + const dec3 = ratchetDecrypt(aliceSession, enc3.header, enc3.ciphertext); + expect(dec3).not.toBeNull(); + expect(new TextDecoder().decode(dec3!.plaintext)).toBe("Message 3"); + aliceSession = dec3!.session; + + // Alice has an orphan skip key for n=1 that will never be used + expect(aliceSession.skippedKeys.length).toBe(1); + expect(aliceSession.skippedKeys[0].msgNumber).toBe(1); + + // Session continues to work normally + expect(aliceSession.receivingMsgNumber).toBe(3); + }); + + it("should handle multiple consecutive burned slots", () => { + const { aliceSession: initialAlice, bobSession: initialBob, bobSigning } = createSessionPair(); + let bobSession = initialBob; + let aliceSession = initialAlice; + + // Bob encrypts 5 messages, but 2, 3, 4 all fail + const enc1 = ratchetEncrypt(bobSession, new TextEncoder().encode("Msg 1"), bobSigning.secretKey); + bobSession = enc1.session; + + // Messages 2, 3, 4 - all burned (tx failures) + const enc2 = ratchetEncrypt(bobSession, new TextEncoder().encode("Msg 2 - FAIL"), bobSigning.secretKey); + bobSession = enc2.session; + const enc3 = ratchetEncrypt(bobSession, new TextEncoder().encode("Msg 3 - FAIL"), bobSigning.secretKey); + bobSession = enc3.session; + const enc4 = ratchetEncrypt(bobSession, new TextEncoder().encode("Msg 4 - FAIL"), bobSigning.secretKey); + bobSession = enc4.session; + + const enc5 = ratchetEncrypt(bobSession, new TextEncoder().encode("Msg 5"), bobSigning.secretKey); + bobSession = enc5.session; + + // Alice receives only 1 and 5 + const dec1 = ratchetDecrypt(aliceSession, enc1.header, enc1.ciphertext); + aliceSession = dec1!.session; + + const dec5 = ratchetDecrypt(aliceSession, enc5.header, enc5.ciphertext); + expect(dec5).not.toBeNull(); + expect(new TextDecoder().decode(dec5!.plaintext)).toBe("Msg 5"); + aliceSession = dec5!.session; + + // Alice has 3 orphan skip keys (for n=1, 2, 3) + expect(aliceSession.skippedKeys.length).toBe(3); + expect(aliceSession.skippedKeys.map(k => k.msgNumber).sort()).toEqual([1, 2, 3]); + }); + + it("should handle burned first message", () => { + const { aliceSession: initialAlice, bobSession: initialBob, bobSigning } = createSessionPair(); + let bobSession = initialBob; + let aliceSession = initialAlice; + + // First message burns (tx fails) + const enc1 = ratchetEncrypt(bobSession, new TextEncoder().encode("Msg 1 - FAIL"), bobSigning.secretKey); + bobSession = enc1.session; + + // Second message succeeds + const enc2 = ratchetEncrypt(bobSession, new TextEncoder().encode("Msg 2"), bobSigning.secretKey); + bobSession = enc2.session; + + // Alice receives only message 2 + const dec2 = ratchetDecrypt(aliceSession, enc2.header, enc2.ciphertext); + expect(dec2).not.toBeNull(); + expect(new TextDecoder().decode(dec2!.plaintext)).toBe("Msg 2"); + aliceSession = dec2!.session; + + // Skip key created for n=0 + expect(aliceSession.skippedKeys.length).toBe(1); + expect(aliceSession.skippedKeys[0].msgNumber).toBe(0); + }); + }); + + describe("Retry with New Message Number", () => { + it("should successfully decrypt retried message at new slot", () => { + const { aliceSession: initialAlice, bobSession: initialBob, bobSigning } = createSessionPair(); + let bobSession = initialBob; + let aliceSession = initialAlice; + + // Bob sends message 1 successfully + const enc1 = ratchetEncrypt(bobSession, new TextEncoder().encode("Msg 1"), bobSigning.secretKey); + bobSession = enc1.session; + + // Message 2 - first attempt fails (burned) + const enc2FirstAttempt = ratchetEncrypt( + bobSession, + new TextEncoder().encode("Important message"), + bobSigning.secretKey + ); + bobSession = enc2FirstAttempt.session; // Slot burned + + // Message 3 sends successfully + const enc3 = ratchetEncrypt(bobSession, new TextEncoder().encode("Msg 3"), bobSigning.secretKey); + bobSession = enc3.session; + + // Retry "Important message" - now at slot n=3 + const enc2Retry = ratchetEncrypt( + bobSession, + new TextEncoder().encode("Important message"), // Same content + bobSigning.secretKey + ); + bobSession = enc2Retry.session; + + // Alice receives messages in order: 1, 3, then retry + const dec1 = ratchetDecrypt(aliceSession, enc1.header, enc1.ciphertext); + aliceSession = dec1!.session; + + const dec3 = ratchetDecrypt(aliceSession, enc3.header, enc3.ciphertext); + aliceSession = dec3!.session; + + // Retry decrypts fine at its new message number + const decRetry = ratchetDecrypt(aliceSession, enc2Retry.header, enc2Retry.ciphertext); + expect(decRetry).not.toBeNull(); + expect(new TextDecoder().decode(decRetry!.plaintext)).toBe("Important message"); + aliceSession = decRetry!.session; + + // Alice has orphan skip key for the burned n=1 slot + expect(aliceSession.skippedKeys.some(k => k.msgNumber === 1)).toBe(true); + }); + + it("should handle multiple retries of different messages", () => { + const { aliceSession: initialAlice, bobSession: initialBob, bobSigning } = createSessionPair(); + let bobSession = initialBob; + let aliceSession = initialAlice; + + // Successful: n=0 + const enc1 = ratchetEncrypt(bobSession, new TextEncoder().encode("Msg 1"), bobSigning.secretKey); + bobSession = enc1.session; + + // Fails: n=1 burned + const failedA = ratchetEncrypt(bobSession, new TextEncoder().encode("Failed A"), bobSigning.secretKey); + bobSession = failedA.session; + + // Fails: n=2 burned + const failedB = ratchetEncrypt(bobSession, new TextEncoder().encode("Failed B"), bobSigning.secretKey); + bobSession = failedB.session; + + // Successful: n=3 + const enc2 = ratchetEncrypt(bobSession, new TextEncoder().encode("Msg 2"), bobSigning.secretKey); + bobSession = enc2.session; + + // Retry A: n=4 + const retryA = ratchetEncrypt(bobSession, new TextEncoder().encode("Failed A"), bobSigning.secretKey); + bobSession = retryA.session; + + // Retry B: n=5 + const retryB = ratchetEncrypt(bobSession, new TextEncoder().encode("Failed B"), bobSigning.secretKey); + bobSession = retryB.session; + + // Alice receives: 1, 2, retryA, retryB (skipping n=1,2) + let dec = ratchetDecrypt(aliceSession, enc1.header, enc1.ciphertext); + aliceSession = dec!.session; + + dec = ratchetDecrypt(aliceSession, enc2.header, enc2.ciphertext); + aliceSession = dec!.session; + // Skip keys for n=1, n=2 created + + dec = ratchetDecrypt(aliceSession, retryA.header, retryA.ciphertext); + expect(dec).not.toBeNull(); + expect(new TextDecoder().decode(dec!.plaintext)).toBe("Failed A"); + aliceSession = dec!.session; + + dec = ratchetDecrypt(aliceSession, retryB.header, retryB.ciphertext); + expect(dec).not.toBeNull(); + expect(new TextDecoder().decode(dec!.plaintext)).toBe("Failed B"); + aliceSession = dec!.session; + + // 2 orphan skip keys remain + expect(aliceSession.skippedKeys.length).toBe(2); + }); + }); + + describe("Orphan Skip Keys Lifecycle", () => { + it("should accumulate orphan skip keys from burned slots", () => { + const { aliceSession: initialAlice, bobSession: initialBob, bobSigning } = createSessionPair(); + let bobSession = initialBob; + let aliceSession = initialAlice; + + // Send odd-numbered messages only (even slots burned) + const encryptedMessages: ReturnType[] = []; + + for (let i = 0; i < 10; i++) { + const enc = ratchetEncrypt( + bobSession, + new TextEncoder().encode(`Msg ${i}`), + bobSigning.secretKey + ); + bobSession = enc.session; + + // Only "send" odd indices (0, 2, 4, 6, 8) + if (i % 2 === 0) { + encryptedMessages.push(enc); + } + // Even indices (1, 3, 5, 7, 9) are burned + } + + // Alice receives only the even-index messages + for (const enc of encryptedMessages) { + const dec = ratchetDecrypt(aliceSession, enc.header, enc.ciphertext); + expect(dec).not.toBeNull(); + aliceSession = dec!.session; + } + + // 4 orphan skip keys for the burned slots (n=1,3,5,7) + expect(aliceSession.skippedKeys.length).toBe(4); + const burnedSlots = aliceSession.skippedKeys.map(k => k.msgNumber).sort((a, b) => a - b); + expect(burnedSlots).toEqual([1, 3, 5, 7]); + }); + + it("should expire orphan skip keys after TTL", () => { + const { aliceSession: initialAlice, bobSession: initialBob, bobSigning } = createSessionPair(); + let bobSession = initialBob; + let aliceSession = initialAlice; + + // Create some burned slots + const enc1 = ratchetEncrypt(bobSession, new TextEncoder().encode("Msg 1"), bobSigning.secretKey); + bobSession = enc1.session; + + // Burn n=1 + ratchetEncrypt(bobSession, new TextEncoder().encode("Burned"), bobSigning.secretKey); + bobSession = bobSession; // Would be advanced in real code + + const enc2 = ratchetEncrypt(bobSession, new TextEncoder().encode("Msg 2"), bobSigning.secretKey); + bobSession = enc2.session; + + // Simpler test: just create a session with old skip keys + aliceSession = { + ...aliceSession, + skippedKeys: [ + { + dhPubKeyHex: "0xold", + msgNumber: 5, + messageKey: new Uint8Array(32), + createdAt: Date.now() - 100_000_000, // Very old + }, + { + dhPubKeyHex: "0xnew", + msgNumber: 6, + messageKey: new Uint8Array(32), + createdAt: Date.now(), // Fresh + }, + ], + }; + + // Prune with 24h TTL (in ms) + const pruned = pruneExpiredSkippedKeys(aliceSession, 24 * 60 * 60 * 1000); + + expect(pruned.skippedKeys.length).toBe(1); + expect(pruned.skippedKeys[0].msgNumber).toBe(6); // Only fresh one remains + }); + }); + + describe("Skip Key Storage Limits", () => { + it("should handle approaching MAX_STORED_SKIPPED_KEYS", () => { + // Create a session with many skipped keys approaching the limit + const { aliceSession: initialAlice } = createSessionPair(); + + // Simulate a pathological case with many skip keys + const manySkipKeys = Array.from({ length: 100 }, (_, i) => ({ + dhPubKeyHex: `0x${i.toString(16).padStart(64, '0')}`, + msgNumber: i, + messageKey: nacl.randomBytes(32), + createdAt: Date.now(), + })); + + const sessionWithManyKeys: RatchetSession = { + ...initialAlice, + skippedKeys: manySkipKeys, + }; + + // Session should still be functional + expect(sessionWithManyKeys.skippedKeys.length).toBe(100); + + // In a real implementation, we'd test that the oldest keys get pruned + // when exceeding MAX_STORED_SKIPPED_KEYS (1000) + expect(MAX_STORED_SKIPPED_KEYS).toBe(1000); + }); + + it("should handle large message number gaps gracefully", () => { + const { aliceSession: initialAlice, bobSession: initialBob, bobSigning } = createSessionPair(); + let bobSession = initialBob; + let aliceSession = initialAlice; + + // Send first message + const enc1 = ratchetEncrypt(bobSession, new TextEncoder().encode("First"), bobSigning.secretKey); + bobSession = enc1.session; + + // Simulate many burned slots by manually advancing session + // In real app, this would be many failed txs + for (let i = 0; i < 50; i++) { + const burned = ratchetEncrypt(bobSession, new TextEncoder().encode(`Burned ${i}`), bobSigning.secretKey); + bobSession = burned.session; + } + + // Send message after the gap + const enc2 = ratchetEncrypt(bobSession, new TextEncoder().encode("After gap"), bobSigning.secretKey); + bobSession = enc2.session; + + // Alice receives first message + const dec1 = ratchetDecrypt(aliceSession, enc1.header, enc1.ciphertext); + aliceSession = dec1!.session; + + // Alice receives message after gap - creates 50 skip keys + const dec2 = ratchetDecrypt(aliceSession, enc2.header, enc2.ciphertext); + expect(dec2).not.toBeNull(); + expect(new TextDecoder().decode(dec2!.plaintext)).toBe("After gap"); + aliceSession = dec2!.session; + + // 50 skip keys created for the gap + expect(aliceSession.skippedKeys.length).toBe(50); + }); + }); + + describe("Session Persistence (DB Round-Trip)", () => { + it("should maintain chain continuity after save/load cycle", () => { + const { aliceSession: initialAlice, bobSession: initialBob, bobSigning, aliceSigning } = createSessionPair(); + let bobSession = initialBob; + let aliceSession = initialAlice; + + // Bob sends a message + const enc1 = ratchetEncrypt(bobSession, new TextEncoder().encode("Before save"), bobSigning.secretKey); + bobSession = enc1.session; + + // Simulate DB save/load + bobSession = simulateDbRoundTrip(bobSession); + + // Bob sends another message after "reload" + const enc2 = ratchetEncrypt(bobSession, new TextEncoder().encode("After save"), bobSigning.secretKey); + bobSession = enc2.session; + + // Alice receives both messages + const dec1 = ratchetDecrypt(aliceSession, enc1.header, enc1.ciphertext); + expect(dec1).not.toBeNull(); + aliceSession = dec1!.session; + + const dec2 = ratchetDecrypt(aliceSession, enc2.header, enc2.ciphertext); + expect(dec2).not.toBeNull(); + expect(new TextDecoder().decode(dec2!.plaintext)).toBe("After save"); + }); + + it("should preserve skip keys through save/load cycle", () => { + const { aliceSession: initialAlice, bobSession: initialBob, bobSigning } = createSessionPair(); + let bobSession = initialBob; + let aliceSession = initialAlice; + + // Bob sends 3 messages + const enc1 = ratchetEncrypt(bobSession, new TextEncoder().encode("Msg 1"), bobSigning.secretKey); + bobSession = enc1.session; + const enc2 = ratchetEncrypt(bobSession, new TextEncoder().encode("Msg 2"), bobSigning.secretKey); + bobSession = enc2.session; + const enc3 = ratchetEncrypt(bobSession, new TextEncoder().encode("Msg 3"), bobSigning.secretKey); + bobSession = enc3.session; + + // Alice receives msg 3 first (creates skip keys) + const dec3 = ratchetDecrypt(aliceSession, enc3.header, enc3.ciphertext); + aliceSession = dec3!.session; + expect(aliceSession.skippedKeys.length).toBe(2); + + // Simulate DB save/load + aliceSession = simulateDbRoundTrip(aliceSession); + + // Skip keys should still work after reload + expect(aliceSession.skippedKeys.length).toBe(2); + + const dec1 = ratchetDecrypt(aliceSession, enc1.header, enc1.ciphertext); + expect(dec1).not.toBeNull(); + expect(new TextDecoder().decode(dec1!.plaintext)).toBe("Msg 1"); + aliceSession = dec1!.session; + + const dec2 = ratchetDecrypt(aliceSession, enc2.header, enc2.ciphertext); + expect(dec2).not.toBeNull(); + expect(new TextDecoder().decode(dec2!.plaintext)).toBe("Msg 2"); + }); + + it("should handle alternating messages with save/load between each", () => { + let { aliceSession, bobSession, bobSigning, aliceSigning } = createSessionPair(); + + // Simulate realistic usage: save after every operation + + // Bob -> Alice + const enc1 = ratchetEncrypt(bobSession, new TextEncoder().encode("Bob 1"), bobSigning.secretKey); + bobSession = simulateDbRoundTrip(enc1.session); + + const dec1 = ratchetDecrypt(aliceSession, enc1.header, enc1.ciphertext); + aliceSession = simulateDbRoundTrip(dec1!.session); + + // Alice -> Bob + const enc2 = ratchetEncrypt(aliceSession, new TextEncoder().encode("Alice 1"), aliceSigning.secretKey); + aliceSession = simulateDbRoundTrip(enc2.session); + + const dec2 = ratchetDecrypt(bobSession, enc2.header, enc2.ciphertext); + bobSession = simulateDbRoundTrip(dec2!.session); + + // Bob -> Alice again + const enc3 = ratchetEncrypt(bobSession, new TextEncoder().encode("Bob 2"), bobSigning.secretKey); + bobSession = simulateDbRoundTrip(enc3.session); + + const dec3 = ratchetDecrypt(aliceSession, enc3.header, enc3.ciphertext); + expect(dec3).not.toBeNull(); + expect(new TextDecoder().decode(dec3!.plaintext)).toBe("Bob 2"); + }); + }); + + describe("DH Ratchet Advancement with Failures", () => { + it("should handle burned slots across DH ratchet steps", () => { + let { aliceSession, bobSession, bobSigning, aliceSigning } = createSessionPair(); + + // Bob sends (advances his chain) + const bobEnc1 = ratchetEncrypt(bobSession, new TextEncoder().encode("Bob 1"), bobSigning.secretKey); + bobSession = bobEnc1.session; + + // Alice receives and replies (triggers DH ratchet for her) + const aliceDec1 = ratchetDecrypt(aliceSession, bobEnc1.header, bobEnc1.ciphertext); + aliceSession = aliceDec1!.session; + + // Alice sends (with her new DH key) + const aliceEnc1 = ratchetEncrypt(aliceSession, new TextEncoder().encode("Alice 1"), aliceSigning.secretKey); + aliceSession = aliceEnc1.session; + + // Alice's second message FAILS (burned) + const aliceEnc2Burned = ratchetEncrypt(aliceSession, new TextEncoder().encode("Alice 2 FAIL"), aliceSigning.secretKey); + aliceSession = aliceEnc2Burned.session; + + // Alice's third message succeeds + const aliceEnc3 = ratchetEncrypt(aliceSession, new TextEncoder().encode("Alice 3"), aliceSigning.secretKey); + aliceSession = aliceEnc3.session; + + // Bob receives Alice's messages (skipping the burned one) + const bobDec1 = ratchetDecrypt(bobSession, aliceEnc1.header, aliceEnc1.ciphertext); + bobSession = bobDec1!.session; + + const bobDec3 = ratchetDecrypt(bobSession, aliceEnc3.header, aliceEnc3.ciphertext); + expect(bobDec3).not.toBeNull(); + expect(new TextDecoder().decode(bobDec3!.plaintext)).toBe("Alice 3"); + bobSession = bobDec3!.session; + + // Bob has skip key for Alice's n=1 + expect(bobSession.skippedKeys.length).toBe(1); + + // Bob replies (triggers DH ratchet for him) + const bobEnc2 = ratchetEncrypt(bobSession, new TextEncoder().encode("Bob 2"), bobSigning.secretKey); + bobSession = bobEnc2.session; + + // Alice receives + const aliceDec2 = ratchetDecrypt(aliceSession, bobEnc2.header, bobEnc2.ciphertext); + expect(aliceDec2).not.toBeNull(); + expect(new TextDecoder().decode(aliceDec2!.plaintext)).toBe("Bob 2"); + }); + }); + + describe("Concurrent Conversation Isolation", () => { + it("should isolate failures between different conversations", () => { + // Create two separate conversations + const convAB = createSessionPair(); // Alice <-> Bob + const convAC = createSessionPair(); // Alice <-> Charlie (reusing Alice's signing key) + + let aliceBobSession = convAB.aliceSession; + let bobSession = convAB.bobSession; + let aliceCharlieSession = convAC.aliceSession; + let charlieSession = convAC.bobSession; + + const aliceSigning = convAB.aliceSigning; + const bobSigning = convAB.bobSigning; + const charlieSigning = convAC.bobSigning; + + // Send message to Bob (succeeds) + const toBob = ratchetEncrypt(aliceBobSession, new TextEncoder().encode("Hi Bob"), aliceSigning.secretKey); + aliceBobSession = toBob.session; + + // Send message to Charlie (fails - burned) + const toCharlieFail = ratchetEncrypt(aliceCharlieSession, new TextEncoder().encode("Hi Charlie FAIL"), aliceSigning.secretKey); + aliceCharlieSession = toCharlieFail.session; + + // Send another to Charlie (succeeds) + const toCharlieSuccess = ratchetEncrypt(aliceCharlieSession, new TextEncoder().encode("Hi Charlie"), aliceSigning.secretKey); + aliceCharlieSession = toCharlieSuccess.session; + + // Bob's conversation unaffected + const bobDec = ratchetDecrypt(bobSession, toBob.header, toBob.ciphertext); + expect(bobDec).not.toBeNull(); + expect(new TextDecoder().decode(bobDec!.plaintext)).toBe("Hi Bob"); + bobSession = bobDec!.session; + expect(bobSession.skippedKeys.length).toBe(0); // No skip keys + + // Charlie has skip key from burned message + const charlieDec = ratchetDecrypt(charlieSession, toCharlieSuccess.header, toCharlieSuccess.ciphertext); + expect(charlieDec).not.toBeNull(); + expect(new TextDecoder().decode(charlieDec!.plaintext)).toBe("Hi Charlie"); + charlieSession = charlieDec!.session; + expect(charlieSession.skippedKeys.length).toBe(1); // Skip key for n=0 + }); + }); + + describe("Edge Cases", () => { + it("should handle empty message", () => { + const { aliceSession, bobSession, bobSigning } = createSessionPair(); + + const enc = ratchetEncrypt(bobSession, new Uint8Array(0), bobSigning.secretKey); + const dec = ratchetDecrypt(aliceSession, enc.header, enc.ciphertext); + + expect(dec).not.toBeNull(); + expect(dec!.plaintext.length).toBe(0); + }); + + it("should handle large message", () => { + const { aliceSession, bobSession, bobSigning } = createSessionPair(); + + // 1MB message + const largeMessage = nacl.randomBytes(1024 * 1024); + const enc = ratchetEncrypt(bobSession, largeMessage, bobSigning.secretKey); + const dec = ratchetDecrypt(aliceSession, enc.header, enc.ciphertext); + + expect(dec).not.toBeNull(); + expect(Buffer.from(dec!.plaintext)).toEqual(Buffer.from(largeMessage)); + }); + + it("should reject replay of same message", () => { + const { aliceSession: initialAlice, bobSession, bobSigning } = createSessionPair(); + let aliceSession = initialAlice; + + const enc = ratchetEncrypt(bobSession, new TextEncoder().encode("Original"), bobSigning.secretKey); + + // First decrypt succeeds + const dec1 = ratchetDecrypt(aliceSession, enc.header, enc.ciphertext); + expect(dec1).not.toBeNull(); + aliceSession = dec1!.session; + + // Replay attempt - same header/ciphertext + const dec2 = ratchetDecrypt(aliceSession, enc.header, enc.ciphertext); + + // Should fail - message key was consumed + expect(dec2).toBeNull(); + }); + + it("should handle message after long idle period", () => { + let { aliceSession, bobSession, bobSigning } = createSessionPair(); + + // Send first message + const enc1 = ratchetEncrypt(bobSession, new TextEncoder().encode("Before idle"), bobSigning.secretKey); + bobSession = enc1.session; + + const dec1 = ratchetDecrypt(aliceSession, enc1.header, enc1.ciphertext); + aliceSession = dec1!.session; + + // Simulate long idle by manipulating timestamps (in real app, session would be loaded from DB) + bobSession = simulateDbRoundTrip(bobSession); + aliceSession = simulateDbRoundTrip(aliceSession); + + // Send message after "idle" + const enc2 = ratchetEncrypt(bobSession, new TextEncoder().encode("After idle"), bobSigning.secretKey); + const dec2 = ratchetDecrypt(aliceSession, enc2.header, enc2.ciphertext); + + expect(dec2).not.toBeNull(); + expect(new TextDecoder().decode(dec2!.plaintext)).toBe("After idle"); + }); + }); +}); \ No newline at end of file diff --git a/plan.md b/plan.md index 6c55dc3..ce674f0 100644 --- a/plan.md +++ b/plan.md @@ -45,23 +45,26 @@ interface RatchetSession { Lookup: `session where topicInbound === event.topic` -### 1.4 Two-Phase Commit (Sequential Blocking) +### 1.4 Immediate Session Commit (Skip-Key Resilient) -**Problem**: Advancing ratchet state before tx confirms risks permanent desync on failure. +**Original design**: Two-phase commit with sequential blocking. -**Solution**: Immutable operations + pending state with sequential blocking. +**Implemented design**: Immediate session commit after encryption. ``` -1. Check: pending outbound exists? โ†’ Block send -2. Load session -3. Compute (nextState, header, ciphertext) โ€” DON'T save -4. Create PendingOutbound { prevState, nextState, txHash } -5. Send transaction -6. On SUCCESS: commit nextState, delete pending -7. On FAILURE: discard pending, session unchanged +1. Load session (from cache or DB) +2. Compute (nextState, header, ciphertext) +3. Save nextState to DB IMMEDIATELY +4. Send transaction +5. On SUCCESS: clean up pending record +6. On FAILURE: ratchet "slot" is burned, receiver handles via skip keys ``` -**Constraint**: User cannot send message N+1 until transaction N confirms. This prevents dependent pending states. +**Why this works**: +- The ratchet protocol is designed for message loss +- Receivers handle gaps via skip-key mechanism +- Saving session immediately ensures subsequent messages use the advanced state +- Matches how Signal handles message failures ### 1.5 Auth-Before-Ratchet (DoS Protection) @@ -80,7 +83,7 @@ Lookup: `session where topicInbound === event.topic` ``` Offset โ”‚ Size โ”‚ Field -โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ +โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ 0 โ”‚ 1 โ”‚ Version (0x01) 1 โ”‚ 64 โ”‚ Ed25519 signature 65 โ”‚ 32 โ”‚ DH ratchet public key @@ -97,12 +100,12 @@ Fixed overhead: ~105 bytes (vs ~200+ for JSON+base64). **Reality**: - **Offline catch-up**: Process chain logs in order โ†’ chain key advances sequentially โ†’ no skipped keys -- **Skipped keys**: Handle block reorgs and out-of-order RPC responses +- **Skipped keys**: Handle block reorgs, out-of-order RPC responses, and failed transactions | Concept | Purpose | |---------|---------| | Chain key derivation | Sequential catch-up after offline | -| Skipped keys | Out-of-order delivery tolerance | +| Skipped keys | Out-of-order delivery + tx failure tolerance | Bounds: - `MAX_STORED_SKIPPED_KEYS = 1000` (memory limit) @@ -112,94 +115,250 @@ Bounds: ## 2. State Loss & Session Reset -**Tradeoff**: Forward secrecy means lost local state = lost messages. +### 2.1 The Forward Secrecy Tradeoff -**Solution**: Session Reset Protocol -- User initiates new handshake to existing contact -- Creates new session with new topics -- Old session becomes `inactive_reset` (frozen, not deleted) -- Peer sees "Alice requests new session" notification +**Fundamental truth**: Forward secrecy means lost local state = lost messages. + +The ratchet state is: +- **Stateful**: Each message advances the state irreversibly +- **Local-only**: Not stored on-chain or derivable from identity +- **Critical**: Without it, decryption is impossible + +Topics are derived from `HKDF(DH(myIdentity, theirIdentity), salt)`. The salt comes from the handshake. Even if you re-derive identity, you need the salt (stored in contact) AND the ratchet state to decrypt. + +### 2.3 Session Reset Protocol + +When local state is lost, the ONLY option is to establish a new session: + +``` +1. User initiates new handshake to existing contact +2. Include flag/context: "session reset request" +3. Creates new session with NEW topics (new salt) +4. Old session becomes `inactive_reset` (frozen, not deleted) +5. Peer sees "Alice requests new session" notification +6. Peer accepts โ†’ both parties have fresh session +7. Old messages remain encrypted/unreadable +``` **UX**: "Session recovered - messages before [date] unavailable" +### 2.4 Detection & User Notification + +The app should detect state loss and notify users: + +```typescript +// On app startup after identity derivation +async function checkSessionIntegrity(address: string): Promise { + const contacts = await dbService.getAllContacts(address); + const issues: SessionIssue[] = []; + + for (const contact of contacts) { + if (contact.status === 'established' && contact.conversationId) { + const session = await dbService.getRatchetSessionByConversation(contact.conversationId); + + if (!session) { + issues.push({ + contactAddress: contact.address, + type: 'missing_session', + message: 'Ratchet session not found - reset required' + }); + } + } + } + + return { healthy: issues.length === 0, issues }; +} +``` + --- ## 3. Implementation Milestones -No need to provide migration or backward compatibility. +### Milestone 1: SDK Ratchet Core โœ… COMPLETED +### Milestone 2: Handshake + Persistence โœ… COMPLETED +### Milestone 3: Encrypted Messaging โœ… COMPLETED +Full send/receive with session caching and batch processing. + +**Implementation Details**: + +| Component | Status | Notes | +|-----------|--------|-------| +| `useMessageQueue.ts` | โœ… | Sequential message processing with optimistic UI | +| Session caching | โœ… | Per-conversation cache in `sessionCacheRef` | +| Immediate session commit | โœ… | DB save before tx send (skip-key resilient) | +| Batch incoming processing | โœ… | `processMessageLogWithCache()` with shared cache | +| Auth-first decryption | โœ… | `verifyMessageSignature()` before `ratchetDecrypt()` | +| Pending outbound tracking | โœ… | `PendingOutbound` table for tx confirmation matching | +| Retry failed messages | โœ… | Re-encrypts with current state (burns new slot) | -### Milestone 1: SDK Ratchet Core โœ… -Pure crypto module, fully testable without blockchain/DB. +**Test Cases Verified**: +- โœ… Send โ†’ pending created โ†’ confirmed โ†’ session committed +- โœ… Send failure โ†’ session already advanced, skip key handles gap +- โœ… Batch incoming โ†’ session cache ensures sequential decryption +- โœ… Invalid signature โ†’ rejected before ratchet work (DoS protection) -**Files**: `ratchet/{types,kdf,session,encrypt,decrypt,codec,auth}.ts` +### Milestone 4: Session Reset Protocol ๐Ÿ”„ IN PROGRESS -**Functions**: -- `initSessionAsResponder()`, `initSessionAsInitiator()` -- `ratchetEncrypt()`, `ratchetDecrypt()` -- `packageRatchetPayload()`, `parseRatchetPayload()`, `isRatchetPayload()` -- `verifyMessageSignature()` +**Status**: Design complete, implementation pending. -### Milestone 2: Handshake + Persistence -Wire ratchet into handshake; sessions persist to IndexedDB. +#### 4.1 Scenarios Requiring Reset + +| Trigger | Detection | Action | +|---------|-----------|--------| +| User clears IndexedDB | Missing session for established contact | Prompt: "Re-establish session with X?" | +| New device login | No sessions exist, contacts may exist | Prompt: "Restore backup or reset sessions?" | +| Corrupted ratchet state | Decryption fails repeatedly | Prompt: "Session corrupted, reset?" | +| User-initiated | Manual action | "Reset session with X" | + +#### 4.2 Reset Flow Design + +``` +โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” +โ”‚ ALICE (State Lost) โ”‚ +โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค +โ”‚ 1. Detect: session missing for established contact โ”‚ +โ”‚ 2. UI: "Session with Bob unavailable. Reset?" โ”‚ +โ”‚ 3. User confirms โ”‚ +โ”‚ 4. Mark old contact as "pending_reset" โ”‚ +โ”‚ 5. Send new handshake with reset flag โ”‚ +โ”‚ โ””โ”€ plaintextPayload: { type: "session_reset", ... } โ”‚ +โ”‚ 6. Wait for response โ”‚ +โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ + โ”‚ + โ–ผ +โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” +โ”‚ BOB (State Intact) โ”‚ +โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค +โ”‚ 1. Receive handshake with reset flag โ”‚ +โ”‚ 2. UI: "Alice requests session reset. Accept?" โ”‚ +โ”‚ โ””โ”€ Warning: "Old messages will remain encrypted" โ”‚ +โ”‚ 3. User confirms โ”‚ +โ”‚ 4. Mark old session as "inactive_superseded" โ”‚ +โ”‚ 5. Accept handshake โ†’ create new session โ”‚ +โ”‚ 6. Old messages: keep but mark "archived" โ”‚ +โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ + โ”‚ + โ–ผ +โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” +โ”‚ BOTH PARTIES โ”‚ +โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค +โ”‚ โ€ข New session active with new topics โ”‚ +โ”‚ โ€ข Old session frozen (read-only archive) โ”‚ +โ”‚ โ€ข UI shows: "Session reset on [date]" โ”‚ +โ”‚ โ€ข Old messages shown grayed: "Encrypted - session reset" โ”‚ +โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ +``` + +#### 4.3 Implementation Tasks **SDK Changes**: -- `send.ts`: Return two keypairs (tag + ratchet) from `respondToHandshake()` -- `VerbethClient.tsacceptHandshake()` returns ephemeral keys; `sendMessage()` REMOVED -- `crypto.ts` Mark `encryptMessage`/`decryptMessage` as `@deprecated` +```typescript +// New type for handshake content +interface HandshakeContent { + plaintextPayload: string; + identityProof: IdentityProof; + resetContext?: { + type: 'session_reset'; + previousTopicOut?: `0x${string}`; // For linking to old conversation + reason?: 'state_lost' | 'user_initiated' | 'corruption'; + }; +} +``` **App Changes**: -- `types.ts`: Add `StoredRatchetSession`, `PendingOutbound` -- `schema.ts`: Add `ratchetSessions`, `pendingOutbound` tables -- `DbService.ts`: Add ~8 ratchet methods -- `useChatActions.ts`: Create session on `acceptHandshake` -- `useMessageProcessor.ts`: Create session on `HandshakeResponse` -**Key**: Ratchet key comes from decrypted payload, NOT on-chain `responderEphemeralR`. +| File | Changes | +|------|---------| +| `types.ts` | Add `SessionResetRequest` type | +| `schema.ts` | Add index for finding reset-eligible sessions | +| `DbService.ts` | Add `markSessionAsReset()`, `getSessionsNeedingReset()` | +| `useMessageProcessor.ts` | Detect reset flag in incoming handshakes | +| `useChatActions.ts` | Add `initiateSessionReset()` action | +| `App.tsx` / UI | Reset UI, prompts, archived message display | -### Milestone 3: Encrypted Messaging -Full send/receive with two-phase commit. +#### 4.4 Edge Cases -**App Changes**: -- `useChatActions.ts`: Rewrite `sendMessageToContact()` with sequential blocking -- `useMessageProcessor.ts`: Auth-first ratchet decrypt for incoming +| Case | Handling | +|------|----------| +| Both parties lost state simultaneously | Both send reset โ†’ first one processed wins | +| Reset during active conversation | Pending messages fail, resend after reset | +| Malicious reset spam | Rate limit reset requests per contact | +| Partial state loss (some sessions ok) | Per-contact reset, not global | -**Test Cases**: -- Send โ†’ pending created โ†’ confirmed โ†’ session committed -- Send failure โ†’ session unchanged -- Sequential blocking โ†’ 2nd message blocked while 1st pending -- Invalid signature โ†’ rejected, no ratchet work +--- + +## 4. Future Improvements + +### 4.1 Cloud Sync (Planned) -### Post-M3: Session Reset Protocol -Separate PR for recovery flow. +**Problem**: Device loss = data loss. + +**Solution**: Encrypted cloud backup of full database state. + +``` +โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” +โ”‚ CLOUD SYNC FLOW โ”‚ +โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค +โ”‚ 1. Derive backup key: HKDF(identitySeed, "verbeth-backup") โ”‚ +โ”‚ 2. Serialize: { contacts, messages, ratchetSessions, ... } โ”‚ +โ”‚ 3. Encrypt: AES-GCM(backupKey, serializedData) โ”‚ +โ”‚ 4. Upload to user's cloud storage (Drive/iCloud/S3) โ”‚ +โ”‚ 5. On new device: download, decrypt, import โ”‚ +โ”‚ 6. Ratchet state restored โ†’ no reset needed โ”‚ +โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ +``` + +**Key properties**: +- Backup key derived from identity โ†’ only owner can decrypt +- Cloud provider never sees plaintext +- Backup includes ratchet state โ†’ seamless device migration +- Optional: encrypted sync on every state change + +**Implementation scope**: Separate feature, not part of core ratchet. + +### 4.2 Topic Ratcheting (Phase 2) + +Periodic topic rotation for enhanced metadata privacy. + +### 4.3 Post-Quantum (Phase 3) + +ML-KEM hybrid for quantum resistance. --- -## 4. Success Criteria +## 5. Success Criteria + +### Cryptographic โœ… +- [x] Identity key compromise never decrypts past messages (including message 0) +- [x] Post-compromise security: session recovers after key compromise +- [x] DoS resistance: unauthenticated messages rejected in O(1) +- [x] Unlinkability: on-chain R โ‰  message DH headers -**Cryptographic**: -- [ ] Identity key compromise never decrypts past messages (including message 0) -- [ ] Post-compromise security: session recovers after key compromise -- [ ] DoS resistance: unauthenticated messages rejected in O(1) -- [ ] Unlinkability: on-chain R โ‰  message DH headers +### State Management โœ… +- [x] Immediate session commit with skip-key resilience +- [x] Session caching: in-memory cache + DB persistence +- [x] Session keyed by topics (not addresses) +- [x] Confirmation matching by txHash -**State Management**: -- [ ] Two-phase commit prevents desync on tx failure -- [ ] Sequential blocking: max one pending per conversation -- [ ] Session keyed by topics (not addresses) -- [ ] Confirmation matching by txHash +### Resilience โœ… +- [x] Long offline periods: process in order, no skipped keys needed +- [x] Skipped keys for reorg tolerance (24h TTL) +- [x] Batch message processing with shared session cache -**Resilience**: -- [ ] Long offline periods: process in order, no skipped keys needed -- [ ] Skipped keys only for reorg tolerance (24h TTL) -- [ ] Session reset creates new topics (doesn't reuse old) +### Session Reset ๐Ÿ”„ +- [ ] Detect missing sessions for established contacts +- [ ] Reset handshake with context flag +- [ ] Peer notification and acceptance flow +- [ ] Old session archival (frozen, not deleted) +- [ ] UI for reset prompts and archived messages --- -## 5. What's NOT in Scope +## 6. What's NOT in Scope | Feature | Phase | |---------|-------| | Topic ratcheting | Phase 2 | | Post-quantum (ML-KEM) | Phase 3 | | Cloud sync | Future | -| Export/import | Future | \ No newline at end of file +| Export/import encryption | Future (current export is plaintext JSON) | \ No newline at end of file From f5a4a16824a71f42575bdbd298b5eb51e69a93e3 Mon Sep 17 00:00:00 2001 From: Marco Esposito Date: Tue, 13 Jan 2026 14:49:34 +0100 Subject: [PATCH 10/51] session reset handling --- apps/demo/src/App.tsx | 60 ++++-- .../src/components/PinnedResetRequest.tsx | 79 ++++++++ .../src/components/SideToastNotification.tsx | 17 +- apps/demo/src/hooks/useChatActions.ts | 16 +- apps/demo/src/hooks/useMessageProcessor.ts | 37 +++- apps/demo/src/hooks/usePendingSessionReset.ts | 39 ++++ apps/demo/src/services/DbService.ts | 92 +++++----- .../src/services/EventProcessorService.ts | 13 +- apps/demo/src/types.ts | 30 +-- packages/sdk/src/ratchet/index.ts | 55 ------ packages/sdk/src/ratchet/session.ts | 3 - packages/sdk/src/ratchet/types.ts | 15 +- packages/sdk/test/ratchet.test.ts | 1 - plan.md | 171 +++++------------- 14 files changed, 325 insertions(+), 303 deletions(-) create mode 100644 apps/demo/src/components/PinnedResetRequest.tsx create mode 100644 apps/demo/src/hooks/usePendingSessionReset.ts diff --git a/apps/demo/src/App.tsx b/apps/demo/src/App.tsx index 609b1e5..8846258 100644 --- a/apps/demo/src/App.tsx +++ b/apps/demo/src/App.tsx @@ -22,6 +22,8 @@ import { SessionSetupPrompt } from './components/SessionSetupPrompt.js'; import { useChatActions } from './hooks/useChatActions.js'; import { useSessionSetup } from './hooks/useSessionSetup.js'; import { useInitIdentity } from './hooks/useInitIdentity.js'; +import { usePendingSessionReset } from './hooks/usePendingSessionReset.js'; +import { PinnedResetRequest } from './components/PinnedResetRequest.js'; export default function App() { const { ethers: readProvider, viem: viemClient } = useRpcClients(); @@ -40,6 +42,9 @@ export default function App() { const [activityLogs, setActivityLogs] = useState(""); const [verbethClient, setVerbethClient] = useState(null); + const [healthBannerDismissed, setHealthBannerDismissed] = useState(false); + const [isResettingContacts, setIsResettingContacts] = useState(false); + const logRef = useRef(null); const chainId = Number(import.meta.env.VITE_CHAIN_ID); @@ -124,20 +129,24 @@ export default function App() { pendingHandshakes, contacts, addMessage, - updateMessageStatus, - removeMessage, + updateMessageStatus, + removeMessage, removePendingHandshake, updateContact, - processEvents + processEvents, + markMessagesLost } = useMessageProcessor({ readProvider, identityContext, address: address ?? undefined, - emitterAddress: emitterAddress ?? undefined, + emitterAddress: emitterAddress ?? undefined, identityKeyPair, onLog: addLog }); + const { hasPendingReset, pendingHandshake: pendingResetHandshake, limboAfterTimestamp } = + usePendingSessionReset(selectedContact, pendingHandshakes); + const { isInitialLoading, isLoadingMore, @@ -171,6 +180,7 @@ export default function App() { setLoading, setMessage, setRecipientAddress, + markMessagesLost, }); useEffect(() => { @@ -207,6 +217,7 @@ export default function App() { sender: h.sender, message: h.message, verified: h.verified, + isExistingContact: h.isExistingContact, onAccept: (msg: string) => acceptHandshake(h, msg), onReject: () => removePendingHandshake(h.id), })) @@ -232,6 +243,8 @@ export default function App() { const isOutgoing = msg.direction === 'outgoing'; const isFailed = msg.status === 'failed'; const isPending = msg.status === 'pending'; + const isLost = msg.isLost === true; + const isInLimbo = !isLost && hasPendingReset && isOutgoing && msg.type !== 'system' && limboAfterTimestamp && msg.timestamp > limboAfterTimestamp; return (

{msg.type === "system" && msg.verified !== undefined && ( @@ -282,10 +294,12 @@ export default function App() { {new Date(msg.timestamp).toLocaleTimeString()} {isOutgoing && ( - - {msg.status === 'confirmed' ? 'โœ“โœ“' : - msg.status === 'failed' ? 'โœ—' : - msg.status === 'pending' ? 'โœ“' : '?'} + + {isLost ? 'โœ—' : + isInLimbo ? 'โœ“' : + msg.status === 'confirmed' ? 'โœ“โœ“' : + msg.status === 'failed' ? 'โœ—' : + msg.status === 'pending' ? 'โœ“' : '?'} )}

@@ -391,7 +405,7 @@ export default function App() { sessionSignerBalance={sessionSignerBalance} needsSessionSetup={needsSessionSetup} isSafeDeployed={isSafeDeployed} - isModuleEnabled={isModuleEnabled} + isModuleEnabled={isModuleEnabled} onSetupSession={setupSession} onRefreshBalance={refreshSessionBalance} loading={loading} @@ -401,7 +415,7 @@ export default function App() { {(needsIdentityCreation || needsModeSelection) ? ( a.timestamp - b.timestamp) .map(renderMessage)} + {messages.filter(m => { const currentAddress = address; if (!currentAddress || !selectedContact?.address) return false; @@ -519,11 +534,18 @@ export default function App() { (selectedContact.topicOutbound && m.topic === selectedContact.topicOutbound) || (selectedContact.topicInbound && m.topic === selectedContact.topicInbound) ); - }).length === 0 && ( + }).length === 0 && !hasPendingReset && (

No messages yet. {selectedContact.status === 'established' ? 'Start the conversation!' : 'Waiting for handshake completion.'}

)} + + {hasPendingReset && pendingResetHandshake && ( + + )}
{/* Queue Status Indicator */} diff --git a/apps/demo/src/components/PinnedResetRequest.tsx b/apps/demo/src/components/PinnedResetRequest.tsx new file mode 100644 index 0000000..e1ca5bf --- /dev/null +++ b/apps/demo/src/components/PinnedResetRequest.tsx @@ -0,0 +1,79 @@ +// src/components/PinnedResetRequest.tsx + +import { useState } from 'react'; +import type { PendingHandshake } from '../types.js'; + +interface PinnedResetRequestProps { + handshake: PendingHandshake; + onAccept: (handshake: PendingHandshake, message: string) => void; +} + +export function PinnedResetRequest({ handshake, onAccept }: PinnedResetRequestProps) { + const [response, setResponse] = useState(''); + const [isExpanded, setIsExpanded] = useState(false); + + const handleAccept = () => { + if (response.trim()) { + onAccept(handshake, response.trim()); + } + }; + + const shortAddress = `${handshake.sender.slice(0, 6)}...${handshake.sender.slice(-4)}`; + + return ( +
+
+
setIsExpanded(!isExpanded)} + > +
+ โš ๏ธ +
+

+ {shortAddress} requests a new handshake +

+

+ Your session was reset. Please accept to re-establish secure communication. +

+
+ + {isExpanded ? 'โ–ผ' : 'โ–ถ'} + +
+
+ + {/* Expanded content */} + {isExpanded && ( +
+

+ "{handshake.message}" +

+ +
+ setResponse(e.target.value)} + placeholder="La tua risposta..." + className="flex-1 px-3 py-1.5 bg-gray-900/80 border border-amber-800/40 rounded text-sm text-white placeholder-gray-500 focus:outline-none focus:border-amber-600" + onKeyDown={(e) => { + if (e.key === 'Enter' && response.trim()) { + handleAccept(); + } + }} + /> + +
+
+ )} +
+
+ ); +} \ No newline at end of file diff --git a/apps/demo/src/components/SideToastNotification.tsx b/apps/demo/src/components/SideToastNotification.tsx index eb21a80..ba077f6 100644 --- a/apps/demo/src/components/SideToastNotification.tsx +++ b/apps/demo/src/components/SideToastNotification.tsx @@ -27,6 +27,7 @@ interface SideToastNotificationsProps { sender: string; message: string; verified: boolean; + isExistingContact?: boolean; onAccept: (msg: string) => void; onReject: () => void; }[]; @@ -122,11 +123,10 @@ export function SideToastNotifications({ {/* Notifications container */}
= 640) ? 'opacity-100' : 'opacity-0 sm:opacity-100' - }`} - style={{ - top: "5px", + className={`fixed left-1/2 z-[9999] w-full flex flex-col items-center pointer-events-none transition-opacity duration-300 ${shouldShowNotifications && (mobileVisible || window.innerWidth >= 640) ? 'opacity-100' : 'opacity-0 sm:opacity-100' + }`} + style={{ + top: "5px", transform: "translateX(-50%)", visibility: shouldShowNotifications && (mobileVisible || window.innerWidth >= 640) ? 'visible' : 'hidden' }} @@ -207,6 +207,11 @@ export function SideToastNotifications({ โš ๏ธ Unverified )} + {notif.isExistingContact && ( + + ๐Ÿ”„ Session reset + + )}

"{notif.message}"

@@ -239,7 +244,7 @@ export function SideToastNotifications({ const input = document.getElementById( `side-toast-response-${notif.id}` ) as HTMLInputElement; - const note = input?.value ?? ""; + const note = input?.value ?? ""; notif.onAccept(note.trim()); if (input) input.value = ""; removeNotification(notif.id); diff --git a/apps/demo/src/hooks/useChatActions.ts b/apps/demo/src/hooks/useChatActions.ts index 77d77a8..4e417ba 100644 --- a/apps/demo/src/hooks/useChatActions.ts +++ b/apps/demo/src/hooks/useChatActions.ts @@ -1,11 +1,5 @@ // src/hooks/useChatActions.ts -/** - * Chat actions hook with Double Ratchet integration and Message Queue. - * - * UPDATED: Added session cache invalidation for when sessions are reset externally. - */ - import { useCallback } from "react"; import { hexlify } from "ethers"; import { @@ -32,6 +26,7 @@ interface UseChatActionsProps { setLoading: (loading: boolean) => void; setMessage: (message: string) => void; setRecipientAddress: (address: string) => void; + markMessagesLost: (contactAddress: string, afterTimestamp: number) => Promise; } export const useChatActions = ({ @@ -46,6 +41,7 @@ export const useChatActions = ({ setLoading, setMessage, setRecipientAddress, + markMessagesLost, }: UseChatActionsProps) => { const { @@ -197,6 +193,12 @@ export const useChatActions = ({ }; await updateContact(newContact); + if (handshake.isExistingContact && handshake.timestamp) { + const lostCount = await markMessagesLost(handshake.sender, handshake.timestamp); + if (lostCount > 0) { + addLog(`โš ๏ธ ${lostCount} messages marked as lost`); + } + } await removePendingHandshake(handshake.id); setSelectedContact(newContact); @@ -316,11 +318,9 @@ export const useChatActions = ({ ); return { - // Existing actions sendHandshake, acceptHandshake, sendMessageToContact, - // Queue-related actions retryFailedMessage, cancelQueuedMessage, diff --git a/apps/demo/src/hooks/useMessageProcessor.ts b/apps/demo/src/hooks/useMessageProcessor.ts index fb150af..61badca 100644 --- a/apps/demo/src/hooks/useMessageProcessor.ts +++ b/apps/demo/src/hooks/useMessageProcessor.ts @@ -1,13 +1,8 @@ // src/hooks/useMessageProcessor.ts /** - * Message Processor Hook. - * * Manages messaging state (messages, contacts, pendingHandshakes) and * orchestrates event processing via EventProcessorService. - * - * The service handles decoding, verification, decryption, and persistence. - * This hook just applies the results to React state. */ import { useState, useEffect, useCallback } from "react"; @@ -31,7 +26,6 @@ import { interface UseMessageProcessorProps { readProvider: any; address: string | undefined; - /** Safe address in fast mode, EOA in classic mode. Used for outbound detection. */ emitterAddress: string | undefined; identityKeyPair: IdentityKeyPair | null; identityContext: IdentityContext; @@ -80,10 +74,8 @@ export const useMessageProcessor = ({ async (events: ProcessedEvent[]) => { if (!address) return; - // Session cache for batch processing const batchSessionCache = new Map(); - // Log batch info const messageEvents = events.filter((e) => e.eventType === "message"); if (messageEvents.length > 1) { onLog(`๐Ÿ“จ Processing batch of ${messageEvents.length} messages...`); @@ -235,6 +227,34 @@ export const useMessageProcessor = ({ setMessages((prev) => prev.filter((m) => m.id !== messageId)); }, []); + const markMessagesLost = useCallback( + async (contactAddress: string, afterTimestamp: number): Promise => { + if (!address) return 0; + + const count = await dbService.markMessagesAsLost(address, contactAddress, afterTimestamp); + + if (count > 0) { + const normalizedContact = contactAddress.toLowerCase(); + setMessages((prev) => + prev.map((m) => { + if ( + m.direction === 'outgoing' && + m.recipient?.toLowerCase() === normalizedContact && + m.timestamp > afterTimestamp && + m.type !== 'system' + ) { + return { ...m, isLost: true }; + } + return m; + }) + ); + } + + return count; + }, + [address] +); + const removePendingHandshake = useCallback(async (id: string) => { await dbService.deletePendingHandshake(id); setPendingHandshakes((prev) => prev.filter((h) => h.id !== id)); @@ -271,5 +291,6 @@ export const useMessageProcessor = ({ removePendingHandshake, updateContact, processEvents, + markMessagesLost, }; }; \ No newline at end of file diff --git a/apps/demo/src/hooks/usePendingSessionReset.ts b/apps/demo/src/hooks/usePendingSessionReset.ts new file mode 100644 index 0000000..fef3e82 --- /dev/null +++ b/apps/demo/src/hooks/usePendingSessionReset.ts @@ -0,0 +1,39 @@ +// src/hooks/usePendingSessionReset.ts + +import { useMemo } from 'react'; +import type { Contact, PendingHandshake } from '../types.js'; + +interface PendingSessionReset { + hasPendingReset: boolean; + pendingHandshake: PendingHandshake | null; + limboAfterTimestamp: number | null; +} + +/** + * Hook to detect if there's a pending session reset from the selected contact. + */ +export function usePendingSessionReset( + selectedContact: Contact | null, + pendingHandshakes: PendingHandshake[] +): PendingSessionReset { + return useMemo(() => { + if (!selectedContact) { + return { hasPendingReset: false, pendingHandshake: null, limboAfterTimestamp: null }; + } + + const resetHandshake = pendingHandshakes.find( + h => h.sender.toLowerCase() === selectedContact.address.toLowerCase() + && h.isExistingContact === true + ); + + if (!resetHandshake) { + return { hasPendingReset: false, pendingHandshake: null, limboAfterTimestamp: null }; + } + + return { + hasPendingReset: true, + pendingHandshake: resetHandshake, + limboAfterTimestamp: resetHandshake.timestamp, + }; + }, [selectedContact, pendingHandshakes]); +} \ No newline at end of file diff --git a/apps/demo/src/services/DbService.ts b/apps/demo/src/services/DbService.ts index 416d0fa..1891d7d 100644 --- a/apps/demo/src/services/DbService.ts +++ b/apps/demo/src/services/DbService.ts @@ -4,16 +4,16 @@ import { VerbEthDatabase } from "./schema.js"; import type { StoredIdentity, Contact, + ContactStatus, Message, PendingHandshake, - StoredRatchetSession, PendingOutbound, } from "../types.js"; import { serializeRatchetSession, deserializeRatchetSession, } from "../types.js"; -import type { RatchetSession, SessionStatus } from "@verbeth/sdk"; +import type { RatchetSession } from "@verbeth/sdk"; import { pruneExpiredSkippedKeys } from "@verbeth/sdk"; export class DbService { @@ -459,20 +459,6 @@ export class DbService { return pruned; } - /** - * Update ratchet session status. - */ - async updateRatchetSessionStatus( - conversationId: string, - status: SessionStatus - ): Promise { - await this.db.ratchetSessions.update(conversationId, { - status, - updatedAt: Date.now(), - }); - console.log(`๐Ÿ“ Updated session ${conversationId.slice(0, 10)}... status to: ${status}`); - } - /** * Delete ratchet session. */ @@ -540,8 +526,6 @@ export class DbService { * Finalize pending outbound: just delete the pending record. * Called when on-chain confirmation is received. * - * With the new architecture, session state is committed immediately during - * encryption, so confirmation just needs to clean up the pending record. */ async finalizePendingOutbound(id: string): Promise<{ plaintext: string } | null> { const pending = await this.db.pendingOutbound.get(id); @@ -549,8 +533,6 @@ export class DbService { console.warn(`โš ๏ธ Pending outbound ${id} not found for finalization`); return null; } - - // Just delete the pending record - session state was already committed await this.db.pendingOutbound.delete(id); console.log(`โœ… Finalized pending outbound ${id.slice(0, 10)}...`); @@ -586,34 +568,33 @@ export class DbService { return stale.length; } - /** - * Clear all ratchet data for a user (for reset/debug). - */ - async clearRatchetData(myAddress: string): Promise { - const normalizedAddress = this.normalizeAddress(myAddress); - - await this.db.transaction( - "rw", - [this.db.ratchetSessions, this.db.pendingOutbound], - async () => { - const sessions = await this.db.ratchetSessions - .where("myAddress") - .equals(normalizedAddress) - .toArray(); + async markMessagesAsLost( + ownerAddress: string, + contactAddress: string, + afterTimestamp: number +): Promise { + const normalizedOwner = this.normalizeAddress(ownerAddress); + const normalizedContact = this.normalizeAddress(contactAddress); - for (const s of sessions) { - await this.db.ratchetSessions.delete(s.conversationId); - await this.db.pendingOutbound - .where("conversationId") - .equals(s.conversationId) - .delete(); - } - } - ); + const messages = await this.db.messages + .where('ownerAddress') + .equals(normalizedOwner) + .filter(m => + m.direction === 'outgoing' && + m.recipient?.toLowerCase() === normalizedContact && + m.timestamp > afterTimestamp && + m.type !== 'system' + ) + .toArray(); - console.log(`๐Ÿงน Cleared all ratchet data for ${normalizedAddress.slice(0, 8)}...`); + for (const msg of messages) { + await this.db.messages.update(msg.id, { isLost: true }); } + return messages.length; +} + + /* -------------------------------- SETTINGS ------------------------------ */ setSetting(name: string, value: any) { return this.db.settings.put({ name, value }); @@ -736,6 +717,29 @@ export class DbService { //this.deduplicator.clear(); console.log(`User data cleared for ${normalizedAddr.slice(0, 8)}...`); } +/* ----------------------------- SESSION ----------------------------- */ + +/** + * Check if a sender is an existing contact. + * Used during handshake processing for receiver hints. + */ +async isExistingContact(senderAddress: string, ownerAddress: string): Promise<{ + exists: boolean; + previousStatus?: ContactStatus; + previousConversationId?: string; +}> { + const contact = await this.getContact(senderAddress, ownerAddress); + + if (!contact) { + return { exists: false }; + } + + return { + exists: true, + previousStatus: contact.status, + previousConversationId: contact.conversationId, + }; +} /* ---------------------------- BACKUP / IMPORT --------------------------- */ async exportData() { diff --git a/apps/demo/src/services/EventProcessorService.ts b/apps/demo/src/services/EventProcessorService.ts index 049fec9..5ad9ffd 100644 --- a/apps/demo/src/services/EventProcessorService.ts +++ b/apps/demo/src/services/EventProcessorService.ts @@ -162,6 +162,9 @@ export async function processHandshakeEvent( } catch (e) {} } + const existingContact = await dbService.getContact(identityAddress, address); + const isExistingEstablished = existingContact?.status === 'established'; + const pendingHandshake: PendingHandshake = { id: log.transactionHash, ownerAddress: address, @@ -174,8 +177,13 @@ export async function processHandshakeEvent( timestamp: Date.now(), blockNumber: log.blockNumber, verified: isVerified, + isExistingContact: isExistingEstablished, }; + const messagePrefix = pendingHandshake.isExistingContact + ? 'Session reset request received' + : 'Request received'; + const systemMessage: Message = { id: generateTempMessageId(), topic: "", @@ -186,7 +194,7 @@ export async function processHandshakeEvent( blockTimestamp: Date.now(), blockNumber: log.blockNumber, direction: "incoming" as const, - decrypted: `Request received: "${handshakeContent.plaintextPayload}"`, + decrypted: `${messagePrefix}: "${handshakeContent.plaintextPayload}"`, read: true, nonce: 0, dedupKey: `handshake-received-${log.transactionHash}`, @@ -200,8 +208,9 @@ export async function processHandshakeEvent( await dbService.savePendingHandshake(pendingHandshake); await dbService.saveMessage(systemMessage); + const logSuffix = isExistingEstablished ? ' (session reset)' : ''; onLog( - `๐Ÿ“จ Handshake received from ${identityAddress.slice(0, 8)}... ${ + `๐Ÿ“จ Handshake received from ${identityAddress.slice(0, 8)}...${logSuffix} ${ isVerified ? "โœ…" : "โš ๏ธ" }: "${handshakeContent.plaintextPayload}"` ); diff --git a/apps/demo/src/types.ts b/apps/demo/src/types.ts index a1b763c..1fdc6bc 100644 --- a/apps/demo/src/types.ts +++ b/apps/demo/src/types.ts @@ -1,6 +1,5 @@ -import type { IdentityKeyPair, IdentityProof, RatchetSession as SDKRatchetSession, SessionStatus, SkippedKey } from '@verbeth/sdk'; +import type { IdentityKeyPair, IdentityProof, RatchetSession as SDKRatchetSession, } from '@verbeth/sdk'; import { keccak256, toUtf8Bytes, hexlify, getBytes } from 'ethers'; -export type { SessionStatus } from '@verbeth/sdk'; /* ------------------------------- CONSTANTS -------------------------------- */ export const LOGCHAIN_SINGLETON_ADDR = @@ -29,38 +28,24 @@ export const EVENT_SIGNATURES = { /* ------------------------------- ENTITIES -------------------------------- */ export interface Contact { - /** Contact's address (EOA or Safe) */ - address: string; - /** Contact's emitter address (Safe in fast mode, same as address in classic mode) */ + address: string; // Contact's address (EOA or Safe) */ emitterAddress?: string; - /** Owner's address (the user viewing this contact) */ ownerAddress: string; - /** Contact's display name */ name?: string; - /** Contact's X25519 public key for encryption */ identityPubKey?: Uint8Array; - /** Contact's Ed25519 public key for signature verification */ signingPubKey?: Uint8Array; - /** Topic for outbound messages (owner โ†’ contact) */ topicOutbound?: string; - /** Topic for inbound messages (contact โ†’ owner) */ topicInbound?: string; - /** Contact status */ status: "none" | "handshake_sent" | "established"; - /** Last message preview */ lastMessage?: string; - /** Last message timestamp */ lastTimestamp?: number; - /** Unread message count */ unreadCount?: number; note?: string; - /** Conversation ID for ratchet session lookup */ conversationId?: string; - /** Previous conversation ID (after session reset) */ previousConversationId?: string; - /** Initiator's ephemeral secret (stored until handshake response received) */ - handshakeEphemeralSecret?: string; // hex + handshakeEphemeralSecret?: string; + sessionResetAt?: number; } @@ -82,6 +67,7 @@ export interface Message { type: 'text' | 'system'; status: 'pending' | 'confirmed' | 'failed'; verified?: boolean; + isLost?: boolean; } export interface PendingHandshake { @@ -96,6 +82,8 @@ export interface PendingHandshake { timestamp: number; blockNumber: number; verified: boolean; + isExistingContact?: boolean; + previousConversationId?: string; } export type ExecutionMode = 'classic' | 'fast' | 'custom'; @@ -142,7 +130,6 @@ export interface StoredRatchetSession { createdAt: number; updatedAt: number; epoch: number; - status: SessionStatus; } export interface StoredSkippedKey { @@ -227,6 +214,7 @@ export interface MessageProcessorResult { removePendingHandshake: (id: string) => void; updateContact: (contact: Contact) => void; processEvents: (events: ProcessedEvent[]) => Promise; + markMessagesLost: (contactAddress: string, afterTimestamp: number) => Promise; } @@ -268,7 +256,6 @@ export function serializeRatchetSession(session: SDKRatchetSession): StoredRatch createdAt: session.createdAt, updatedAt: session.updatedAt, epoch: session.epoch, - status: session.status, }; } @@ -304,6 +291,5 @@ export function deserializeRatchetSession(stored: StoredRatchetSession): SDKRatc createdAt: stored.createdAt, updatedAt: stored.updatedAt, epoch: stored.epoch, - status: stored.status, }; } \ No newline at end of file diff --git a/packages/sdk/src/ratchet/index.ts b/packages/sdk/src/ratchet/index.ts index 6cd1d63..6b8c720 100644 --- a/packages/sdk/src/ratchet/index.ts +++ b/packages/sdk/src/ratchet/index.ts @@ -1,52 +1,4 @@ // packages/sdk/src/ratchet/index.ts - -/** - * Double Ratchet Module for Verbeth E2EE Messaging. - * - * This module provides bilateral forward secrecy using a Signal-style - * Double Ratchet protocol adapted for on-chain messaging. - * - * Key Features: - * - Ephemeral-only initial secret (no identity keys in DH) - * - Ed25519 signatures for DoS protection - * - Binary encoding for gas efficiency - * - Two-phase commit support (immutable session operations) - * - * @example - * ```typescript - * import { - * initSessionAsResponder, - * initSessionAsInitiator, - * ratchetEncrypt, - * ratchetDecrypt, - * verifyMessageSignature, - * packageRatchetPayload, - * parseRatchetPayload, - * } from '@verbeth/sdk/ratchet'; - * - * // Bob accepts handshake and creates session - * const bobSession = initSessionAsResponder({ - * myAddress: bobAddress, - * contactAddress: aliceAddress, - * myResponderEphemeralSecret: ephemeralSecret, - * myResponderEphemeralPublic: ephemeralPublic, - * theirHandshakeEphemeralPubKey: aliceEphemeral, - * topicOutbound: topics.topicIn, - * topicInbound: topics.topicOut, - * }); - * - * // Bob encrypts a message - * const { session: newSession, header, ciphertext, signature } = ratchetEncrypt( - * bobSession, - * new TextEncoder().encode('Hello Alice!'), - * bobSigningSecretKey - * ); - * - * // Package for on-chain - * const payload = packageRatchetPayload(signature, header, ciphertext); - * ``` - */ - export { MAX_SKIP_PER_MESSAGE, @@ -57,7 +9,6 @@ export { type RatchetSession, type SkippedKey, - type SessionStatus, type MessageHeader, type EncryptResult, @@ -68,7 +19,6 @@ export { type InitInitiatorParams, } from './types.js'; -// KDF functions export { kdfRootKey, kdfChainKey, @@ -76,26 +26,22 @@ export { generateDHKeyPair, } from './kdf.js'; -// Session initialization export { initSessionAsResponder, initSessionAsInitiator, computeConversationId, } from './session.js'; -// Encryption export { ratchetEncrypt, encodeHeader, } from './encrypt.js'; -// Decryption export { ratchetDecrypt, pruneExpiredSkippedKeys, } from './decrypt.js'; -// Binary codec export { packageRatchetPayload, parseRatchetPayload, @@ -105,7 +51,6 @@ export { bytesToHex, } from './codec.js'; -// Authentication export { verifyMessageSignature, signMessage, diff --git a/packages/sdk/src/ratchet/session.ts b/packages/sdk/src/ratchet/session.ts index d2ce68f..45efb36 100644 --- a/packages/sdk/src/ratchet/session.ts +++ b/packages/sdk/src/ratchet/session.ts @@ -100,7 +100,6 @@ export function initSessionAsResponder(params: InitResponderParams): RatchetSess createdAt: now, updatedAt: now, epoch: 0, - status: 'active', }; } @@ -137,7 +136,6 @@ export function initSessionAsInitiator(params: InitInitiatorParams): RatchetSess new Uint8Array(32), // Same initial salt sharedSecret ); - // Note: bobsSendingChain is Bob's sending chain = Alice's receiving chain // Generate Alice's first DH keypair for sending const myDHKeyPair = generateDHKeyPair(); @@ -179,6 +177,5 @@ export function initSessionAsInitiator(params: InitInitiatorParams): RatchetSess createdAt: now, updatedAt: now, epoch: 0, - status: 'active', }; } \ No newline at end of file diff --git a/packages/sdk/src/ratchet/types.ts b/packages/sdk/src/ratchet/types.ts index d40be7b..5b2d85a 100644 --- a/packages/sdk/src/ratchet/types.ts +++ b/packages/sdk/src/ratchet/types.ts @@ -48,7 +48,7 @@ export const RATCHET_VERSION_V1 = 0x01; /** * Ratchet session state. * - * CRITICAL: This is stateful - must be persisted after every encrypt/decrypt. + * This is stateful - must be persisted after every encrypt/decrypt. * Session is identified by conversationId (derived from topics), enabling * correct handling of Safe addresses vs EOAs. */ @@ -104,10 +104,6 @@ export interface RatchetSession { // === Recovery === /** Increments on session reset (internal bookkeeping only) */ epoch: number; - - // === Status === - /** Session lifecycle status */ - status: SessionStatus; } /** @@ -124,15 +120,6 @@ export interface SkippedKey { createdAt: number; } -/** - * Session lifecycle status. - */ -export type SessionStatus = - | 'active' // Normal operating state - | 'inactive_reset' // I initiated reset, waiting for peer - | 'inactive_superseded' // Peer initiated reset, I accepted - | 'frozen'; // Read-only archive - /** * Message header (40 bytes when encoded). */ diff --git a/packages/sdk/test/ratchet.test.ts b/packages/sdk/test/ratchet.test.ts index 9e4b340..d222043 100644 --- a/packages/sdk/test/ratchet.test.ts +++ b/packages/sdk/test/ratchet.test.ts @@ -414,7 +414,6 @@ describe("Double Ratchet", () => { createdAt: Date.now(), updatedAt: Date.now(), epoch: 0, - status: "active", }; const pruned = pruneExpiredSkippedKeys(session, 50000); diff --git a/plan.md b/plan.md index ce674f0..ea99976 100644 --- a/plan.md +++ b/plan.md @@ -113,7 +113,7 @@ Bounds: --- -## 2. State Loss & Session Reset +## 2. State Loss & Recovery ### 2.1 The Forward Secrecy Tradeoff @@ -124,58 +124,40 @@ The ratchet state is: - **Local-only**: Not stored on-chain or derivable from identity - **Critical**: Without it, decryption is impossible -Topics are derived from `HKDF(DH(myIdentity, theirIdentity), salt)`. The salt comes from the handshake. Even if you re-derive identity, you need the salt (stored in contact) AND the ratchet state to decrypt. +### 2.2 When State Loss Occurs -### 2.3 Session Reset Protocol +| Scenario | What's Lost | Recovery Path | +|----------|-------------|---------------| +| Browser IndexedDB cleared | Everything | Re-handshake all contacts | +| New device, same identity | Everything | Re-handshake all contacts | +| Corrupted database | Depends | Re-handshake affected contacts | +| Export then Import | Nothing | Seamless (ratchet state preserved) | -When local state is lost, the ONLY option is to establish a new session: +### 2.3 Recovery: Just Re-Handshake + +No special "reset protocol" needed. The existing handshake flow handles recovery: ``` -1. User initiates new handshake to existing contact -2. Include flag/context: "session reset request" -3. Creates new session with NEW topics (new salt) -4. Old session becomes `inactive_reset` (frozen, not deleted) -5. Peer sees "Alice requests new session" notification -6. Peer accepts โ†’ both parties have fresh session -7. Old messages remain encrypted/unreadable +Alice (lost state) โ†’ sendHandshake(bob) โ†’ Bob accepts โ†’ New session ``` -**UX**: "Session recovered - messages before [date] unavailable" - -### 2.4 Detection & User Notification - -The app should detect state loss and notify users: +- New ephemeral keys generate new salt โ†’ new topics +- Old ratchet session orphaned in Bob's DB (harmless) +- Both parties continue with fresh session -```typescript -// On app startup after identity derivation -async function checkSessionIntegrity(address: string): Promise { - const contacts = await dbService.getAllContacts(address); - const issues: SessionIssue[] = []; - - for (const contact of contacts) { - if (contact.status === 'established' && contact.conversationId) { - const session = await dbService.getRatchetSessionByConversation(contact.conversationId); - - if (!session) { - issues.push({ - contactAddress: contact.address, - type: 'missing_session', - message: 'Ratchet session not found - reset required' - }); - } - } - } - - return { healthy: issues.length === 0, issues }; -} -``` +**UX implication**: Alice must manually re-initiate contact with each peer. This is acceptable; cloud sync (future) would eliminate this friction. --- ## 3. Implementation Milestones ### Milestone 1: SDK Ratchet Core โœ… COMPLETED +Pure crypto module, fully testable without blockchain/DB. + ### Milestone 2: Handshake + Persistence โœ… COMPLETED +Wire ratchet into handshake; sessions persist to IndexedDB. +Ratchet key comes from decrypted payload, NOT on-chain `responderEphemeralR`. + ### Milestone 3: Encrypted Messaging โœ… COMPLETED Full send/receive with session caching and batch processing. @@ -197,93 +179,40 @@ Full send/receive with session caching and batch processing. - โœ… Batch incoming โ†’ session cache ensures sequential decryption - โœ… Invalid signature โ†’ rejected before ratchet work (DoS protection) -### Milestone 4: Session Reset Protocol ๐Ÿ”„ IN PROGRESS - -**Status**: Design complete, implementation pending. +### Milestone 4: Session Recovery UX -#### 4.1 Scenarios Requiring Reset +**Status**: Existing handshake flow (probably) handles reset naturally. -| Trigger | Detection | Action | -|---------|-----------|--------| -| User clears IndexedDB | Missing session for established contact | Prompt: "Re-establish session with X?" | -| New device login | No sessions exist, contacts may exist | Prompt: "Restore backup or reset sessions?" | -| Corrupted ratchet state | Decryption fails repeatedly | Prompt: "Session corrupted, reset?" | -| User-initiated | Manual action | "Reset session with X" | - -#### 4.2 Reset Flow Design +#### 4.1 Why No Special Protocol Needed ``` -โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” -โ”‚ ALICE (State Lost) โ”‚ -โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค -โ”‚ 1. Detect: session missing for established contact โ”‚ -โ”‚ 2. UI: "Session with Bob unavailable. Reset?" โ”‚ -โ”‚ 3. User confirms โ”‚ -โ”‚ 4. Mark old contact as "pending_reset" โ”‚ -โ”‚ 5. Send new handshake with reset flag โ”‚ -โ”‚ โ””โ”€ plaintextPayload: { type: "session_reset", ... } โ”‚ -โ”‚ 6. Wait for response โ”‚ -โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ - โ”‚ - โ–ผ -โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” -โ”‚ BOB (State Intact) โ”‚ -โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค -โ”‚ 1. Receive handshake with reset flag โ”‚ -โ”‚ 2. UI: "Alice requests session reset. Accept?" โ”‚ -โ”‚ โ””โ”€ Warning: "Old messages will remain encrypted" โ”‚ -โ”‚ 3. User confirms โ”‚ -โ”‚ 4. Mark old session as "inactive_superseded" โ”‚ -โ”‚ 5. Accept handshake โ†’ create new session โ”‚ -โ”‚ 6. Old messages: keep but mark "archived" โ”‚ -โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ - โ”‚ - โ–ผ -โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” -โ”‚ BOTH PARTIES โ”‚ -โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค -โ”‚ โ€ข New session active with new topics โ”‚ -โ”‚ โ€ข Old session frozen (read-only archive) โ”‚ -โ”‚ โ€ข UI shows: "Session reset on [date]" โ”‚ -โ”‚ โ€ข Old messages shown grayed: "Encrypted - session reset" โ”‚ -โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ +Alice (lost state) โ†’ sends new handshake โ†’ Bob accepts โ†’ new session created ``` -#### 4.3 Implementation Tasks +What happens: +1. Alice's contact record gets overwritten with `status: "handshake_sent"` +2. New ephemeral keys โ†’ new salt โ†’ new topics +3. Bob sees pending handshake, accepts it +4. New ratchet session created, old one orphaned (but harmless) -**SDK Changes**: -```typescript -// New type for handshake content -interface HandshakeContent { - plaintextPayload: string; - identityProof: IdentityProof; - resetContext?: { - type: 'session_reset'; - previousTopicOut?: `0x${string}`; // For linking to old conversation - reason?: 'state_lost' | 'user_initiated' | 'corruption'; - }; -} -``` -**App Changes**: +#### 4.2 What's Actually Missing (Nice-to-Have UX) -| File | Changes | -|------|---------| -| `types.ts` | Add `SessionResetRequest` type | -| `schema.ts` | Add index for finding reset-eligible sessions | -| `DbService.ts` | Add `markSessionAsReset()`, `getSessionsNeedingReset()` | -| `useMessageProcessor.ts` | Detect reset flag in incoming handshakes | -| `useChatActions.ts` | Add `initiateSessionReset()` action | -| `App.tsx` / UI | Reset UI, prompts, archived message display | +| Enhancement | Description | Priority | +|-------------|-------------|----------| +| Startup health check | Detect "contacts exist but sessions missing" | Low | +| Receiver hint | Bob sees "Alice (existing contact) requests new session" vs confusing duplicate | Medium | +| Orphan cleanup | Periodically delete ratchet sessions with no matching contact | Low | +| Chat boundary | Visual indicator "Session reset on [date]" | Low | -#### 4.4 Edge Cases +#### 4.3 Current Behavior (Acceptable but improvable) -| Case | Handling | -|------|----------| -| Both parties lost state simultaneously | Both send reset โ†’ first one processed wins | -| Reset during active conversation | Pending messages fail, resend after reset | -| Malicious reset spam | Rate limit reset requests per contact | -| Partial state loss (some sessions ok) | Per-contact reset, not global | +| Scenario | What Happens | User Experience | +|----------|--------------|-----------------| +| Alice clears IndexedDB | Loses everything, must re-handshake all contacts | "Start fresh" - acceptable | +| Alice on new device | No data, must re-handshake | Same as new user - acceptable | +| Bob receives 2nd handshake from Alice | Sees new pending request | Slightly confusing but works | +| Old ratchet session | Orphaned in DB | No functional impact | --- @@ -345,12 +274,12 @@ ML-KEM hybrid for quantum resistance. - [x] Skipped keys for reorg tolerance (24h TTL) - [x] Batch message processing with shared session cache -### Session Reset ๐Ÿ”„ -- [ ] Detect missing sessions for established contacts -- [ ] Reset handshake with context flag -- [ ] Peer notification and acceptance flow -- [ ] Old session archival (frozen, not deleted) -- [ ] UI for reset prompts and archived messages +### Session Reset โณ DEFERRED (handled implicitly by existing handshake) +- [x] New handshake to existing contact creates fresh session +- [x] Old session orphaned (no functional impact) +- [ ] *(Nice-to-have)* Detect missing sessions on startup +- [ ] *(Nice-to-have)* UI hint for "existing contact requests new session" +- [ ] *(Nice-to-have)* Cleanup orphaned sessions --- From 0b8a8fd1d9ca6a4cbcdb38d8d97d27aa6711f207 Mon Sep 17 00:00:00 2001 From: Marco Esposito Date: Tue, 13 Jan 2026 15:42:34 +0100 Subject: [PATCH 11/51] cleaning --- apps/demo/src/services/DbService.ts | 310 +++++++-------------- apps/demo/src/services/RatchetDbService.ts | 126 +++++++++ packages/sdk/src/ratchet/auth.ts | 10 +- packages/sdk/src/ratchet/codec.ts | 45 +-- packages/sdk/src/ratchet/decrypt.ts | 55 +--- packages/sdk/src/ratchet/encrypt.ts | 25 +- packages/sdk/src/ratchet/kdf.ts | 25 -- packages/sdk/src/ratchet/session.ts | 45 +-- packages/sdk/src/ratchet/types.ts | 53 +--- 9 files changed, 254 insertions(+), 440 deletions(-) create mode 100644 apps/demo/src/services/RatchetDbService.ts diff --git a/apps/demo/src/services/DbService.ts b/apps/demo/src/services/DbService.ts index 1891d7d..e8194ac 100644 --- a/apps/demo/src/services/DbService.ts +++ b/apps/demo/src/services/DbService.ts @@ -15,12 +15,15 @@ import { } from "../types.js"; import type { RatchetSession } from "@verbeth/sdk"; import { pruneExpiredSkippedKeys } from "@verbeth/sdk"; +import { RatchetDbService } from "./RatchetDbService.js"; export class DbService { private readonly db: VerbEthDatabase; + public readonly ratchet: RatchetDbService; constructor() { this.db = new VerbEthDatabase(); + this.ratchet = new RatchetDbService(this.db); } /* ----------------------------- ADDRESS HELPERS --------------------------- */ @@ -111,7 +114,6 @@ export class DbService { return this.db.identity.delete(normalizedAddress); } - /* ------------------------------ CONTACTS --------------------------------- */ saveContact(contact: Contact) { const normalizedContact = { @@ -364,6 +366,33 @@ export class DbService { return this.db.messages.update(id, { read: true }); } + async markMessagesAsLost( + ownerAddress: string, + contactAddress: string, + afterTimestamp: number + ): Promise { + const normalizedOwner = this.normalizeAddress(ownerAddress); + const normalizedContact = this.normalizeAddress(contactAddress); + + const messages = await this.db.messages + .where("ownerAddress") + .equals(normalizedOwner) + .filter( + (m) => + m.direction === "outgoing" && + m.recipient?.toLowerCase() === normalizedContact && + m.timestamp > afterTimestamp && + m.type !== "system" + ) + .toArray(); + + for (const msg of messages) { + await this.db.messages.update(msg.id, { isLost: true }); + } + + return messages.length; + } + getUnreadMessagesCount() { return this.db.messages.filter((m) => !m.read).count(); } @@ -408,193 +437,55 @@ export class DbService { return this.db.pendingHandshakes.delete(id); } - /* ========================= RATCHET SESSIONS ========================= */ - - /** - * Save or update a ratchet session. - * Automatically serializes Uint8Arrays to hex strings. - */ - async saveRatchetSession(session: RatchetSession): Promise { - const stored = serializeRatchetSession(session); - console.log(`๐Ÿ’พ Saving ratchet session: ${stored.conversationId.slice(0, 10)}... (sendingMsgNumber=${stored.sendingMsgNumber})`); - await this.db.ratchetSessions.put(stored); + /* ========================= RATCHET (DELEGATED) ========================= */ + saveRatchetSession(session: RatchetSession): Promise { + return this.ratchet.saveRatchetSession(session); } - - /** - * Get ratchet session by conversation ID. - */ - async getRatchetSessionByConversation(conversationId: string): Promise { - const stored = await this.db.ratchetSessions.get(conversationId); - if (!stored) return null; - - const session = deserializeRatchetSession(stored); - const pruned = pruneExpiredSkippedKeys(session); - - if (pruned.skippedKeys.length !== session.skippedKeys.length) { - await this.saveRatchetSession(pruned); - } - - return pruned; -} - - /** - * Get ratchet session by inbound topic (for incoming message processing). - */ - async getRatchetSessionByTopic(topicInbound: string): Promise { - const stored = await this.db.ratchetSessions - .where("topicInbound") - .equals(topicInbound.toLowerCase()) - .first(); - if (!stored) return null; - const session = deserializeRatchetSession(stored); - - // Prune expired skipped keys (24h TTL) - const pruned = pruneExpiredSkippedKeys(session); - - // If keys were pruned, persist the cleaned session - if (pruned.skippedKeys.length !== session.skippedKeys.length) { - await this.saveRatchetSession(pruned); - } - - return pruned; -} - - /** - * Delete ratchet session. - */ - async deleteRatchetSession(conversationId: string): Promise { - await this.db.ratchetSessions.delete(conversationId); - console.log(`๐Ÿ—‘๏ธ Deleted ratchet session: ${conversationId.slice(0, 10)}...`); + getRatchetSessionByConversation( + conversationId: string + ): Promise { + return this.ratchet.getRatchetSessionByConversation(conversationId); } - - /* ========================= PENDING OUTBOUND ========================= */ - - /** - * Save a pending outbound message (for two-phase commit). - */ - async savePendingOutbound(pending: PendingOutbound): Promise { - console.log(`๐Ÿ“ค Saving pending outbound: ${pending.id.slice(0, 10)}...`); - await this.db.pendingOutbound.put(pending); + getRatchetSessionByTopic( + topicInbound: string + ): Promise { + return this.ratchet.getRatchetSessionByTopic(topicInbound); } - - /** - * Get pending outbound by ID. - */ - async getPendingOutbound(id: string): Promise { - return await this.db.pendingOutbound.get(id) ?? null; + deleteRatchetSession(conversationId: string): Promise { + return this.ratchet.deleteRatchetSession(conversationId); } - /** - * Get pending outbound by transaction hash (for confirmation matching). - * This is the PRIMARY lookup method for confirmations. - */ - async getPendingOutboundByTxHash(txHash: string): Promise { - return await this.db.pendingOutbound - .where("txHash") - .equals(txHash.toLowerCase()) - .first() ?? null; + savePendingOutbound(pending: PendingOutbound): Promise { + return this.ratchet.savePendingOutbound(pending); } - - /** - * Get all pending outbound for a conversation (for sequential blocking check). - */ - async getPendingOutboundByConversation(conversationId: string): Promise { - return await this.db.pendingOutbound - .where("conversationId") - .equals(conversationId) - .filter((p) => p.status === "preparing" || p.status === "submitted") - .toArray(); + getPendingOutbound(id: string): Promise { + return this.ratchet.getPendingOutbound(id); } - - /** - * Update pending outbound status and optionally set txHash. - */ - async updatePendingOutboundStatus( + getPendingOutboundByTxHash(txHash: string): Promise { + return this.ratchet.getPendingOutboundByTxHash(txHash); + } + getPendingOutboundByConversation( + conversationId: string + ): Promise { + return this.ratchet.getPendingOutboundByConversation(conversationId); + } + updatePendingOutboundStatus( id: string, status: PendingOutbound["status"], txHash?: string ): Promise { - const updates: Partial = { status }; - if (txHash) { - updates.txHash = txHash.toLowerCase(); - } - await this.db.pendingOutbound.update(id, updates); - console.log(`๐Ÿ“ Updated pending outbound ${id.slice(0, 10)}... status to: ${status}`); + return this.ratchet.updatePendingOutboundStatus(id, status, txHash); } - - /** - * Finalize pending outbound: just delete the pending record. - * Called when on-chain confirmation is received. - * - */ - async finalizePendingOutbound(id: string): Promise<{ plaintext: string } | null> { - const pending = await this.db.pendingOutbound.get(id); - if (!pending) { - console.warn(`โš ๏ธ Pending outbound ${id} not found for finalization`); - return null; - } - await this.db.pendingOutbound.delete(id); - - console.log(`โœ… Finalized pending outbound ${id.slice(0, 10)}...`); - return { plaintext: pending.plaintext }; + finalizePendingOutbound(id: string): Promise<{ plaintext: string } | null> { + return this.ratchet.finalizePendingOutbound(id); } - - /** - * Delete pending outbound (on failure - no session state change). - */ - async deletePendingOutbound(id: string): Promise { - await this.db.pendingOutbound.delete(id); - console.log(`๐Ÿ—‘๏ธ Deleted pending outbound: ${id.slice(0, 10)}...`); + deletePendingOutbound(id: string): Promise { + return this.ratchet.deletePendingOutbound(id); } - - /** - * Clean up stale pending outbound records (older than maxAge). - */ - async cleanupStalePendingOutbound(maxAgeMs: number = 24 * 60 * 60 * 1000): Promise { - const cutoff = Date.now() - maxAgeMs; - const stale = await this.db.pendingOutbound - .where("createdAt") - .below(cutoff) - .toArray(); - - for (const p of stale) { - await this.db.pendingOutbound.delete(p.id); - } - - if (stale.length > 0) { - console.log(`๐Ÿงน Cleaned up ${stale.length} stale pending outbound records`); - } - - return stale.length; + cleanupStalePendingOutbound(maxAgeMs?: number): Promise { + return this.ratchet.cleanupStalePendingOutbound(maxAgeMs); } - async markMessagesAsLost( - ownerAddress: string, - contactAddress: string, - afterTimestamp: number -): Promise { - const normalizedOwner = this.normalizeAddress(ownerAddress); - const normalizedContact = this.normalizeAddress(contactAddress); - - const messages = await this.db.messages - .where('ownerAddress') - .equals(normalizedOwner) - .filter(m => - m.direction === 'outgoing' && - m.recipient?.toLowerCase() === normalizedContact && - m.timestamp > afterTimestamp && - m.type !== 'system' - ) - .toArray(); - - for (const msg of messages) { - await this.db.messages.update(msg.id, { isLost: true }); - } - - return messages.length; -} - - /* -------------------------------- SETTINGS ------------------------------ */ setSetting(name: string, value: any) { return this.db.settings.put({ name, value }); @@ -643,8 +534,8 @@ export class DbService { this.db.messages, this.db.pendingHandshakes, this.db.settings, - this.db.ratchetSessions, - this.db.pendingOutbound, + this.db.ratchetSessions, + this.db.pendingOutbound, ], async () => { await this.db.identity.clear(); @@ -652,8 +543,8 @@ export class DbService { await this.db.messages.clear(); await this.db.pendingHandshakes.clear(); await this.db.settings.clear(); - await this.db.ratchetSessions.clear(); - await this.db.pendingOutbound.clear(); + await this.db.ratchetSessions.clear(); + await this.db.pendingOutbound.clear(); } ); console.log("All database data cleared"); @@ -670,8 +561,8 @@ export class DbService { this.db.messages, this.db.pendingHandshakes, this.db.settings, - this.db.ratchetSessions, - this.db.pendingOutbound, + this.db.ratchetSessions, + this.db.pendingOutbound, ], async () => { await this.db.identity.delete(normalizedAddr); @@ -717,29 +608,32 @@ export class DbService { //this.deduplicator.clear(); console.log(`User data cleared for ${normalizedAddr.slice(0, 8)}...`); } -/* ----------------------------- SESSION ----------------------------- */ - -/** - * Check if a sender is an existing contact. - * Used during handshake processing for receiver hints. - */ -async isExistingContact(senderAddress: string, ownerAddress: string): Promise<{ - exists: boolean; - previousStatus?: ContactStatus; - previousConversationId?: string; -}> { - const contact = await this.getContact(senderAddress, ownerAddress); - - if (!contact) { - return { exists: false }; - } - - return { - exists: true, - previousStatus: contact.status, - previousConversationId: contact.conversationId, - }; -} + /* ----------------------------- SESSION ----------------------------- */ + + /** + * Check if a sender is an existing contact. + * Used during handshake processing for receiver hints. + */ + async isExistingContact( + senderAddress: string, + ownerAddress: string + ): Promise<{ + exists: boolean; + previousStatus?: ContactStatus; + previousConversationId?: string; + }> { + const contact = await this.getContact(senderAddress, ownerAddress); + + if (!contact) { + return { exists: false }; + } + + return { + exists: true, + previousStatus: contact.status, + previousConversationId: contact.conversationId, + }; + } /* ---------------------------- BACKUP / IMPORT --------------------------- */ async exportData() { @@ -750,8 +644,8 @@ async isExistingContact(senderAddress: string, ownerAddress: string): Promise<{ messages: await this.db.messages.toArray(), pendingHandshakes: await this.db.pendingHandshakes.toArray(), settings: await this.db.settings.toArray(), - ratchetSessions: await this.db.ratchetSessions.toArray(), - pendingOutbound: await this.db.pendingOutbound.toArray(), + ratchetSessions: await this.db.ratchetSessions.toArray(), + pendingOutbound: await this.db.pendingOutbound.toArray(), exportedAt: Date.now(), } as const; @@ -773,8 +667,8 @@ async isExistingContact(senderAddress: string, ownerAddress: string): Promise<{ this.db.messages, this.db.pendingHandshakes, this.db.settings, - this.db.ratchetSessions, - this.db.pendingOutbound, + this.db.ratchetSessions, + this.db.pendingOutbound, ], async () => { if (data.identity) await this.db.identity.bulkPut(data.identity); @@ -783,9 +677,9 @@ async isExistingContact(senderAddress: string, ownerAddress: string): Promise<{ if (data.pendingHandshakes) await this.db.pendingHandshakes.bulkPut(data.pendingHandshakes); if (data.settings) await this.db.settings.bulkPut(data.settings); - if (data.ratchetSessions) + if (data.ratchetSessions) await this.db.ratchetSessions.bulkPut(data.ratchetSessions); - if (data.pendingOutbound) + if (data.pendingOutbound) await this.db.pendingOutbound.bulkPut(data.pendingOutbound); } ); @@ -830,4 +724,4 @@ async isExistingContact(senderAddress: string, ownerAddress: string): Promise<{ } } -export const dbService = new DbService(); \ No newline at end of file +export const dbService = new DbService(); diff --git a/apps/demo/src/services/RatchetDbService.ts b/apps/demo/src/services/RatchetDbService.ts new file mode 100644 index 0000000..0b02af1 --- /dev/null +++ b/apps/demo/src/services/RatchetDbService.ts @@ -0,0 +1,126 @@ +import { VerbEthDatabase } from "./schema.js"; +import type { PendingOutbound } from "../types.js"; +import { serializeRatchetSession, deserializeRatchetSession } from "../types.js"; +import type { RatchetSession } from "@verbeth/sdk"; +import { pruneExpiredSkippedKeys } from "@verbeth/sdk"; + +export class RatchetDbService { + constructor(private readonly db: VerbEthDatabase) {} + + /* ========================= RATCHET SESSIONS ========================= */ + + async saveRatchetSession(session: RatchetSession): Promise { + const stored = serializeRatchetSession(session); + console.log(`๐Ÿ’พ Saving ratchet session: ${stored.conversationId.slice(0, 10)}... (sendingMsgNumber=${stored.sendingMsgNumber})`); + await this.db.ratchetSessions.put(stored); + } + + async getRatchetSessionByConversation(conversationId: string): Promise { + const stored = await this.db.ratchetSessions.get(conversationId); + if (!stored) return null; + + const session = deserializeRatchetSession(stored); + const pruned = pruneExpiredSkippedKeys(session); + + if (pruned.skippedKeys.length !== session.skippedKeys.length) { + await this.saveRatchetSession(pruned); + } + + return pruned; + } + + async getRatchetSessionByTopic(topicInbound: string): Promise { + const stored = await this.db.ratchetSessions + .where("topicInbound") + .equals(topicInbound.toLowerCase()) + .first(); + if (!stored) return null; + + const session = deserializeRatchetSession(stored); + const pruned = pruneExpiredSkippedKeys(session); + + if (pruned.skippedKeys.length !== session.skippedKeys.length) { + await this.saveRatchetSession(pruned); + } + + return pruned; + } + + async deleteRatchetSession(conversationId: string): Promise { + await this.db.ratchetSessions.delete(conversationId); + console.log(`๐Ÿ—‘๏ธ Deleted ratchet session: ${conversationId.slice(0, 10)}...`); + } + + /* ========================= PENDING OUTBOUND ========================= */ + + async savePendingOutbound(pending: PendingOutbound): Promise { + console.log(`๐Ÿ“ค Saving pending outbound: ${pending.id.slice(0, 10)}...`); + await this.db.pendingOutbound.put(pending); + } + + async getPendingOutbound(id: string): Promise { + return await this.db.pendingOutbound.get(id) ?? null; + } + + async getPendingOutboundByTxHash(txHash: string): Promise { + return await this.db.pendingOutbound + .where("txHash") + .equals(txHash.toLowerCase()) + .first() ?? null; + } + + async getPendingOutboundByConversation(conversationId: string): Promise { + return await this.db.pendingOutbound + .where("conversationId") + .equals(conversationId) + .filter((p) => p.status === "preparing" || p.status === "submitted") + .toArray(); + } + + async updatePendingOutboundStatus( + id: string, + status: PendingOutbound["status"], + txHash?: string + ): Promise { + const updates: Partial = { status }; + if (txHash) { + updates.txHash = txHash.toLowerCase(); + } + await this.db.pendingOutbound.update(id, updates); + console.log(`๐Ÿ“ Updated pending outbound ${id.slice(0, 10)}... status to: ${status}`); + } + + async finalizePendingOutbound(id: string): Promise<{ plaintext: string } | null> { + const pending = await this.db.pendingOutbound.get(id); + if (!pending) { + console.warn(`โš ๏ธ Pending outbound ${id} not found for finalization`); + return null; + } + await this.db.pendingOutbound.delete(id); + console.log(`โœ… Finalized pending outbound ${id.slice(0, 10)}...`); + return { plaintext: pending.plaintext }; + } + + async deletePendingOutbound(id: string): Promise { + await this.db.pendingOutbound.delete(id); + console.log(`๐Ÿ—‘๏ธ Deleted pending outbound: ${id.slice(0, 10)}...`); + } + + async cleanupStalePendingOutbound(maxAgeMs: number = 24 * 60 * 60 * 1000): Promise { + const cutoff = Date.now() - maxAgeMs; + const stale = await this.db.pendingOutbound + .where("createdAt") + .below(cutoff) + .toArray(); + + for (const p of stale) { + await this.db.pendingOutbound.delete(p.id); + } + + if (stale.length > 0) { + console.log(`๐Ÿงน Cleaned up ${stale.length} stale pending outbound records`); + } + + return stale.length; + } +} \ No newline at end of file diff --git a/packages/sdk/src/ratchet/auth.ts b/packages/sdk/src/ratchet/auth.ts index a28eab2..ec38b4d 100644 --- a/packages/sdk/src/ratchet/auth.ts +++ b/packages/sdk/src/ratchet/auth.ts @@ -2,13 +2,6 @@ /** * Message Authentication for Ratchet Protocol. - * - * Ed25519 signatures are mandatory on all ratchet messages. - * This provides DoS protection: unauthenticated messages are rejected in O(1) - * signature verification, preventing attackers from triggering expensive - * ratchet operations. - * - * CRITICAL: Always verify signature BEFORE any ratchet operations. */ import nacl from 'tweetnacl'; @@ -19,7 +12,7 @@ import { MessageHeader } from './types.js'; // ============================================================================= /** - * Verify message signature BEFORE any ratchet operations. + * Verify message signature before any ratchet operations. * This is the primary DoS protection layer. * * The signature covers (header || ciphertext), where header is the 40-byte @@ -59,7 +52,6 @@ export function verifyMessageSignature( /** * Encode header as 40 bytes for signature verification. - * Must match the format used during signing in encrypt.ts. */ function encodeHeaderForSigning(header: MessageHeader): Uint8Array { const buf = new Uint8Array(40); diff --git a/packages/sdk/src/ratchet/codec.ts b/packages/sdk/src/ratchet/codec.ts index 88fb82a..403040c 100644 --- a/packages/sdk/src/ratchet/codec.ts +++ b/packages/sdk/src/ratchet/codec.ts @@ -17,16 +17,9 @@ import { MessageHeader, ParsedRatchetPayload, RATCHET_VERSION_V1 } from './types.js'; -/** Minimum valid payload length: version + sig + header */ const MIN_PAYLOAD_LENGTH = 1 + 64 + 32 + 4 + 4; // 105 bytes -// ============================================================================= -// Encoding -// ============================================================================= - /** - * Package a ratchet message into binary format. - * * @param signature - Ed25519 signature (64 bytes) * @param header - Message header (dh, pn, n) * @param ciphertext - Encrypted payload (nonce + secretbox output) @@ -50,14 +43,11 @@ export function packageRatchetPayload( let offset = 0; - // Version byte payload[offset++] = RATCHET_VERSION_V1; - // Signature (64 bytes) payload.set(signature, offset); offset += 64; - // DH public key (32 bytes) payload.set(header.dh, offset); offset += 32; @@ -69,16 +59,11 @@ export function packageRatchetPayload( view.setUint32(offset, header.n, false); offset += 4; - // Ciphertext (variable length) payload.set(ciphertext, offset); return payload; } -// ============================================================================= -// Decoding -// ============================================================================= - /** * Parse a binary ratchet payload. * @@ -87,23 +72,20 @@ export function packageRatchetPayload( */ export function parseRatchetPayload(payload: Uint8Array): ParsedRatchetPayload | null { if (payload.length < MIN_PAYLOAD_LENGTH) { - return null; // Too short + return null; } const view = new DataView(payload.buffer, payload.byteOffset, payload.byteLength); let offset = 0; - // Version const version = payload[offset++]; if (version !== RATCHET_VERSION_V1) { - return null; // Unknown version + return null; } - // Signature (64 bytes) const signature = payload.slice(offset, offset + 64); offset += 64; - // DH public key (32 bytes) const dh = payload.slice(offset, offset + 32); offset += 32; @@ -115,7 +97,6 @@ export function parseRatchetPayload(payload: Uint8Array): ParsedRatchetPayload | const n = view.getUint32(offset, false); offset += 4; - // Ciphertext (remaining bytes) const ciphertext = payload.slice(offset); return { @@ -126,12 +107,7 @@ export function parseRatchetPayload(payload: Uint8Array): ParsedRatchetPayload | }; } -// ============================================================================= -// Detection -// ============================================================================= - /** - * Check if payload is in ratchet binary format. * Used to distinguish ratchet messages from legacy JSON format. * * @param payload - Raw payload bytes @@ -143,7 +119,6 @@ export function isRatchetPayload(payload: Uint8Array): boolean { /** * Check if hex string represents a ratchet payload. - * Convenience wrapper for hex-encoded payloads from chain. * * @param hexPayload - Hex string (with or without 0x prefix) * @returns true if payload is ratchet format @@ -158,16 +133,7 @@ export function isRatchetPayloadHex(hexPayload: string): boolean { return firstByte === RATCHET_VERSION_V1; } -// ============================================================================= -// Utilities -// ============================================================================= -/** - * Convert hex string to Uint8Array. - * - * @param hex - Hex string (with or without 0x prefix) - * @returns Byte array - */ export function hexToBytes(hex: string): Uint8Array { const cleanHex = hex.startsWith('0x') ? hex.slice(2) : hex; const bytes = new Uint8Array(cleanHex.length / 2); @@ -177,13 +143,6 @@ export function hexToBytes(hex: string): Uint8Array { return bytes; } -/** - * Convert Uint8Array to hex string. - * - * @param bytes - Byte array - * @param prefix - Whether to include 0x prefix (default: true) - * @returns Hex string - */ export function bytesToHex(bytes: Uint8Array, prefix: boolean = true): string { const hex = Array.from(bytes) .map((b) => b.toString(16).padStart(2, '0')) diff --git a/packages/sdk/src/ratchet/decrypt.ts b/packages/sdk/src/ratchet/decrypt.ts index 23d6d61..7854949 100644 --- a/packages/sdk/src/ratchet/decrypt.ts +++ b/packages/sdk/src/ratchet/decrypt.ts @@ -2,14 +2,9 @@ /** * Ratchet Decryption with Skip Key Handling. - * - * Handles: * - Normal sequential message decryption * - DH ratchet steps when sender's DH key changes * - Out-of-order messages via skipped keys - * - * N.b: Caller must verify Ed25519 signature before calling this function. - * This function assumes the message is authenticated. */ import nacl from 'tweetnacl'; @@ -24,16 +19,8 @@ import { } from './types.js'; import { kdfRootKey, kdfChainKey, dh, generateDHKeyPair } from './kdf.js'; -// ============================================================================= -// Main Decrypt Function -// ============================================================================= - /** * Decrypt a message using the ratchet. - * - * Handles DH ratchet steps and out-of-order messages (skip keys). - * Returns updated session state and plaintext, or null if decryption fails. - * * @param session - Current ratchet session state * @param header - Parsed message header * @param ciphertext - Encrypted payload (nonce + secretbox output) @@ -44,8 +31,7 @@ export function ratchetDecrypt( header: MessageHeader, ciphertext: Uint8Array ): DecryptResult | null { - // Sanity check: even authenticated messages shouldn't require insane skips - // This protects against malicious peers or corrupted state + // even authenticated messages shouldn't require insane skips const skipNeeded = Math.max(0, header.n - session.receivingMsgNumber); if (skipNeeded > MAX_SKIP_PER_MESSAGE || header.pn > MAX_SKIP_PER_MESSAGE) { console.error( @@ -70,12 +56,10 @@ export function ratchetDecrypt( // 3. Check if we need to perform a DH ratchet step if (dhPubHex !== currentTheirDHHex) { - // Skip remaining messages on current receiving chain (if any) if (newSession.receivingChainKey) { newSession = skipMessages(newSession, newSession.receivingMsgNumber, header.pn); } - // Perform DH ratchet newSession = dhRatchetStep(newSession, header.dh); } @@ -101,7 +85,6 @@ export function ratchetDecrypt( try { messageKey.fill(0); } catch { - // Some environments may not allow filling typed arrays } if (!plaintext) { @@ -122,10 +105,6 @@ export function ratchetDecrypt( }; } -// ============================================================================= -// DH Ratchet Step -// ============================================================================= - /** * Perform a DH ratchet step when receiving a message with a new DH public key. * @@ -135,17 +114,14 @@ export function ratchetDecrypt( * 3. Sending DH: derive new sending chain from DH(newSecret, theirNewPub) */ function dhRatchetStep(session: RatchetSession, theirNewDHPub: Uint8Array): RatchetSession { - // Receiving DH: use our current secret with their new public const dhReceive = dh(session.dhMySecretKey, theirNewDHPub); const { rootKey: rootKey1, chainKey: receivingChainKey } = kdfRootKey( session.rootKey, dhReceive ); - // Generate new DH keypair for sending const newDHKeyPair = generateDHKeyPair(); - // Sending DH: use new secret with their new public const dhSend = dh(newDHKeyPair.secretKey, theirNewDHPub); const { rootKey: rootKey2, chainKey: sendingChainKey } = kdfRootKey(rootKey1, dhSend); @@ -163,13 +139,8 @@ function dhRatchetStep(session: RatchetSession, theirNewDHPub: Uint8Array): Ratc }; } -// ============================================================================= -// Skip Key Management -// ============================================================================= - /** * Skip messages by deriving and storing their keys for later out-of-order decryption. - * * Called when: * - header.n > receivingMsgNumber (messages skipped in current epoch) * - DH ratchet step with header.pn > 0 (messages from previous epoch) @@ -188,22 +159,19 @@ function skipMessages( const dhPubHex = hexlify(session.dhTheirPublicKey); const now = Date.now(); - // Derive and store skipped keys for (let i = start; i < until; i++) { const { chainKey: newChainKey, messageKey } = kdfChainKey(chainKey); skippedKeys.push({ dhPubKeyHex: dhPubHex, msgNumber: i, - messageKey: new Uint8Array(messageKey), // Copy to avoid reference issues + messageKey: new Uint8Array(messageKey), createdAt: now, }); chainKey = newChainKey; } - // Prune if exceeds storage limit (keep newest) let prunedKeys = skippedKeys; if (skippedKeys.length > MAX_STORED_SKIPPED_KEYS) { - // Sort by createdAt descending, keep newest prunedKeys = skippedKeys .sort((a, b) => b.createdAt - a.createdAt) .slice(0, MAX_STORED_SKIPPED_KEYS); @@ -216,10 +184,7 @@ function skipMessages( }; } -/** - * Try to decrypt using stored skipped keys. - * Returns decrypt result if found, null otherwise. - */ + function trySkippedKeys( session: RatchetSession, dhPubHex: string, @@ -241,7 +206,6 @@ function trySkippedKeys( return null; } - // Remove used key from list const newSkippedKeys = [...session.skippedKeys]; newSkippedKeys.splice(idx, 1); @@ -249,7 +213,6 @@ function trySkippedKeys( try { skippedKey.messageKey.fill(0); } catch { - // Some environments may not allow filling typed arrays } return { @@ -262,10 +225,6 @@ function trySkippedKeys( }; } -// ============================================================================= -// Low-Level Decryption -// ============================================================================= - /** * Decrypt ciphertext with message key using XSalsa20-Poly1305. * Ciphertext format: nonce (24 bytes) + secretbox output @@ -282,14 +241,7 @@ function decryptWithKey(ciphertext: Uint8Array, messageKey: Uint8Array): Uint8Ar return result || null; } -// ============================================================================= -// Utility: Prune Expired Skipped Keys -// ============================================================================= - /** - * Remove skipped keys older than MAX_SKIPPED_KEYS_AGE_MS. - * Should be called periodically (e.g., on session load or after decrypt). - * * @param session - Current session * @param maxAgeMs - Maximum age in milliseconds (default: 24 hours) * @returns Session with pruned skipped keys @@ -308,7 +260,6 @@ export function pruneExpiredSkippedKeys( try { sk.messageKey.fill(0); } catch { - // typed array fill may not be supported } } } diff --git a/packages/sdk/src/ratchet/encrypt.ts b/packages/sdk/src/ratchet/encrypt.ts index 35e5cc0..0da3895 100644 --- a/packages/sdk/src/ratchet/encrypt.ts +++ b/packages/sdk/src/ratchet/encrypt.ts @@ -6,18 +6,14 @@ * Encrypts plaintext using the current sending chain, advances chain state, * and signs the message with Ed25519. * - * IMPORTANT: Returns a NEW session object. Caller must NOT persist until - * the transaction is confirmed on-chain (two-phase commit pattern). + * Returns a new session object. Caller must not persist until + * the tx is confirmed on-chain (two-phase commit pattern). */ import nacl from 'tweetnacl'; import { RatchetSession, MessageHeader, EncryptResult } from './types.js'; import { kdfChainKey } from './kdf.js'; -// ============================================================================= -// Header Encoding -// ============================================================================= - /** * Encode message header as 40 bytes for signing. * Format: dh (32) + pn (4, BE) + n (4, BE) @@ -30,19 +26,7 @@ export function encodeHeader(header: MessageHeader): Uint8Array { return buf; } -// ============================================================================= -// Encryption -// ============================================================================= - -/** - * Encrypt a message using the ratchet. - * - * Returns updated session state (caller must persist after tx confirms) and - * encrypted payload with signature. - * - * Does NOT mutate the input session - returns a new session object. - * This enables two-phase commit: only persist if tx succeeds. - * +/** * @param session - Current ratchet session state * @param plaintext - Message to encrypt * @param signingSecretKey - Ed25519 secret key for signing (64 bytes) @@ -93,11 +77,10 @@ export function ratchetEncrypt( updatedAt: Date.now(), }; - // 7. Wipe message key from memory (security hygiene) + // 7. Wipe message key from memory try { messageKey.fill(0); } catch { - // Some environments may not allow filling typed arrays } return { diff --git a/packages/sdk/src/ratchet/kdf.ts b/packages/sdk/src/ratchet/kdf.ts index a5f81cb..eefbd7f 100644 --- a/packages/sdk/src/ratchet/kdf.ts +++ b/packages/sdk/src/ratchet/kdf.ts @@ -11,18 +11,7 @@ import { hkdf } from '@noble/hashes/hkdf'; import { sha256 } from '@noble/hashes/sha2'; import { hmac } from '@noble/hashes/hmac'; import nacl from 'tweetnacl'; - -// ============================================================================= -// Root Key Derivation -// ============================================================================= - /** - * Derive new root key and chain key from DH output. - * Called on every DH ratchet step. - * - * KDF_RK(rk, dh_out) = HKDF(dh_out, rk, "VerbethRatchet", 64) - * โ†’ (new_rk[0:32], chain_key[32:64]) - * * @param rootKey - Current root key (32 bytes) * @param dhOutput - DH shared secret (32 bytes) * @returns New root key and chain key @@ -38,17 +27,7 @@ export function kdfRootKey( }; } -// ============================================================================= -// Chain Key Derivation -// ============================================================================= - /** - * Derive message key and advance chain key. - * Called for every message sent/received. - * - * KDF_CK(ck) = (HMAC(ck, 0x02), HMAC(ck, 0x01)) - * โ†’ (new_chain_key, message_key) - * * @param chainKey - Current chain key (32 bytes) * @returns New chain key and message key for encryption/decryption */ @@ -66,10 +45,6 @@ export function kdfChainKey( }; } -// ============================================================================= -// Diffie-Hellman Operations -// ============================================================================= - /** * Perform X25519 Diffie-Hellman key exchange. * diff --git a/packages/sdk/src/ratchet/session.ts b/packages/sdk/src/ratchet/session.ts index 45efb36..8e8e668 100644 --- a/packages/sdk/src/ratchet/session.ts +++ b/packages/sdk/src/ratchet/session.ts @@ -2,12 +2,7 @@ /** * Ratchet Session Initialization. - * - * CRITICAL DESIGN: Initial shared secret is derived from ephemeralโ†”ephemeral DH ONLY. - * NO identity keys are used in secret derivation. This ensures that compromise of - * identity keys NEVER allows decryption of past messages, not even the first one. - * - * Authentication is provided separately via Ed25519 signatures on every message. + * Initial shared secret is derived from ephemeral to ephemeral DH only. */ import { keccak256, toUtf8Bytes } from 'ethers'; @@ -18,10 +13,6 @@ import { } from './types.js'; import { kdfRootKey, dh, generateDHKeyPair } from './kdf.js'; -// ============================================================================= -// Helpers -// ============================================================================= - /** * Compute deterministic conversation ID from topics. * Sorting ensures both parties derive the same ID regardless of perspective. @@ -31,18 +22,9 @@ export function computeConversationId(topicA: string, topicB: string): string { return keccak256(toUtf8Bytes(sorted.join(':'))); } -// ============================================================================= -// Session Initialization -// ============================================================================= - /** - * Initialize session as RESPONDER (Bob). * Called after receiving handshake, before/during sending response. - * - * Bob reuses his HandshakeResponse ephemeral key (responderEphemeralR) as his - * first DH ratchet key. This avoids adding new fields to the on-chain format. - * - * โš ๏ธ CRITICAL: The responder MUST persist myResponderEphemeralSecret immediately. + * The responder must persist myResponderEphemeralSecret immediately. * This becomes dhMySecretKey and is required for all future ratchet operations. * * @param params - Initialization parameters @@ -59,8 +41,6 @@ export function initSessionAsResponder(params: InitResponderParams): RatchetSess topicInbound, } = params; - // Initial shared secret: DH(myEphemeral, theirEphemeral) ONLY - // NO identity keys โ†’ true forward secrecy from message 0 const sharedSecret = dh(myResponderEphemeralSecret, theirHandshakeEphemeralPubKey); // Derive initial root key and sending chain key @@ -86,11 +66,10 @@ export function initSessionAsResponder(params: InitResponderParams): RatchetSess dhMyPublicKey: myResponderEphemeralPublic, dhTheirPublicKey: theirHandshakeEphemeralPubKey, - // Bob can send immediately using sendingChainKey sendingChainKey, sendingMsgNumber: 0, - // Receiving chain not yet established (Alice hasn't sent with her new DH key) + // Receiving chain not yet established receivingChainKey: null, receivingMsgNumber: 0, @@ -104,13 +83,9 @@ export function initSessionAsResponder(params: InitResponderParams): RatchetSess } /** - * Initialize session as INITIATOR (Alice). * Called after receiving and validating handshake response. * - * Alice performs an immediate DH ratchet step upon initialization because - * Bob's ratchet ephemeral (from inside the decrypted payload) is his first DH public key. - * - * IMPORTANT: theirResponderEphemeralPubKey comes from INSIDE the decrypted + * NB: theirResponderEphemeralPubKey comes from inside the decrypted * HandshakeResponse payload, NOT from the on-chain responderEphemeralR field. * The on-chain R is only used for tag verification and is different for unlinkability. * @@ -127,20 +102,18 @@ export function initSessionAsInitiator(params: InitInitiatorParams): RatchetSess topicInbound, } = params; - // Initial shared secret: DH(myEphemeral, theirEphemeral) ONLY - // This matches what Bob computed: DH(bobEphemeral, aliceEphemeral) const sharedSecret = dh(myHandshakeEphemeralSecret, theirResponderEphemeralPubKey); - // Derive same initial root key as Bob + // Derive same initial root key as hs responder const { rootKey: initialRootKey, chainKey: bobsSendingChain } = kdfRootKey( new Uint8Array(32), // Same initial salt sharedSecret ); - // Generate Alice's first DH keypair for sending + // Generate first DH keypair for sending const myDHKeyPair = generateDHKeyPair(); - // Perform sending ratchet step (Alice does this immediately) + // Perform sending ratchet step const dhSend = dh(myDHKeyPair.secretKey, theirResponderEphemeralPubKey); const { rootKey: finalRootKey, chainKey: sendingChainKey } = kdfRootKey( initialRootKey, @@ -158,16 +131,14 @@ export function initSessionAsInitiator(params: InitInitiatorParams): RatchetSess rootKey: finalRootKey, - // Alice's newly generated DH keypair dhMySecretKey: myDHKeyPair.secretKey, dhMyPublicKey: myDHKeyPair.publicKey, - // Bob's responder ephemeral is his first DH public key + dhTheirPublicKey: theirResponderEphemeralPubKey, sendingChainKey, sendingMsgNumber: 0, - // Alice's receiving chain = Bob's sending chain (from initial secret) receivingChainKey: bobsSendingChain, receivingMsgNumber: 0, diff --git a/packages/sdk/src/ratchet/types.ts b/packages/sdk/src/ratchet/types.ts index 5b2d85a..9f6ad2f 100644 --- a/packages/sdk/src/ratchet/types.ts +++ b/packages/sdk/src/ratchet/types.ts @@ -1,33 +1,22 @@ // packages/sdk/src/ratchet/types.ts /** - * Double Ratchet types and constants for Verbeth E2EE messaging. - * - * Key design decisions: - * - Sessions keyed by conversationId (derived from topics), NOT addresses - * - Initial secret from ephemeral-only DH (no identity keys) for true forward secrecy - * - Ed25519 signatures mandatory on all messages (DoS protection) + * Double Ratchet types and constants. */ -// ============================================================================= -// Constants -// ============================================================================= - /** - * Sanity cap per ratchet step - protects against malicious peers or corrupted state. - * Auth-before-ratchet prevents external attackers; this caps internal state issues. + * Sanity cap per ratchet step, protects against malicious peers or corrupted state. */ export const MAX_SKIP_PER_MESSAGE = 100_000; /** - * Maximum stored skipped keys (memory/storage bound). * When exceeded, oldest keys are pruned. */ export const MAX_STORED_SKIPPED_KEYS = 1000; /** - * Skipped keys TTL - 24 hours is sufficient for reorg tolerance. - * This is NOT message expiry; sequential messages don't use skipped keys. + * Skipped keys TTL (24 hours is sufficient for reorg tolerance). + * (this is not message expiry as sequential messages don't use skipped keys) */ export const MAX_SKIPPED_KEYS_AGE_MS = 24 * 60 * 60 * 1000; @@ -41,10 +30,6 @@ export const SYNC_BATCH_SIZE = 10_000; */ export const RATCHET_VERSION_V1 = 0x01; -// ============================================================================= -// Core Types -// ============================================================================= - /** * Ratchet session state. * @@ -132,21 +117,13 @@ export interface MessageHeader { n: number; } -// ============================================================================= -// Result Types -// ============================================================================= - /** * Result of ratchetEncrypt - includes new session state for two-phase commit. */ export interface EncryptResult { - /** Updated session state (caller must persist after tx confirms) */ session: RatchetSession; - /** Message header */ header: MessageHeader; - /** Encrypted payload (nonce + ciphertext) */ ciphertext: Uint8Array; - /** Ed25519 signature over (header || ciphertext) */ signature: Uint8Array; } @@ -154,9 +131,7 @@ export interface EncryptResult { * Result of ratchetDecrypt. */ export interface DecryptResult { - /** Updated session state (caller must persist) */ session: RatchetSession; - /** Decrypted plaintext */ plaintext: Uint8Array; } @@ -164,48 +139,36 @@ export interface DecryptResult { * Parsed binary ratchet payload. */ export interface ParsedRatchetPayload { - /** Protocol version */ version: number; - /** Ed25519 signature (64 bytes) */ signature: Uint8Array; - /** Message header */ header: MessageHeader; - /** Encrypted payload */ ciphertext: Uint8Array; } -// ============================================================================= -// Initialization Parameters -// ============================================================================= - /** - * Parameters for initializing session as responder (Bob). + * Parameters for initializing session as responder. */ export interface InitResponderParams { myAddress: string; contactAddress: string; /** Ephemeral secret used in HandshakeResponse (becomes dhMySecretKey) */ myResponderEphemeralSecret: Uint8Array; - /** = responderEphemeralR on-chain */ myResponderEphemeralPublic: Uint8Array; - /** Alice's ephemeral from Handshake event */ + /** Initiator's ephemeral from Handshake event */ theirHandshakeEphemeralPubKey: Uint8Array; topicOutbound: `0x${string}`; topicInbound: `0x${string}`; } /** - * Parameters for initializing session as initiator (Alice). + * Parameters for initializing session as initiator. */ export interface InitInitiatorParams { myAddress: string; contactAddress: string; /** Handshake ephemeral secret (must persist until response arrives) */ myHandshakeEphemeralSecret: Uint8Array; - /** - * Bob's ratchet ephemeral from INSIDE the decrypted HandshakeResponse payload. - * NOTE: This is DIFFERENT from the on-chain responderEphemeralR (which is only for tag). - */ + theirResponderEphemeralPubKey: Uint8Array; topicOutbound: `0x${string}`; topicInbound: `0x${string}`; From c25b2e3a0ed2265be71028a1ed9628aa924b295e Mon Sep 17 00:00:00 2001 From: Marco Esposito Date: Wed, 14 Jan 2026 19:47:23 +0100 Subject: [PATCH 12/51] dh sync topic ratcheting --- .gitignore | 4 + apps/demo/src/hooks/useChatActions.ts | 7 +- apps/demo/src/hooks/useMessageListener.ts | 108 ++- apps/demo/src/hooks/useMessageProcessor.ts | 1 + apps/demo/src/hooks/useMessageQueue.ts | 17 +- apps/demo/src/services/DbService.ts | 14 +- .../src/services/EventProcessorService.ts | 141 +++- apps/demo/src/services/RatchetDbService.ts | 78 +- apps/demo/src/services/schema.ts | 21 +- apps/demo/src/types.ts | 27 +- packages/sdk/src/ratchet/decrypt.ts | 60 +- packages/sdk/src/ratchet/encrypt.ts | 3 +- packages/sdk/src/ratchet/index.ts | 5 +- packages/sdk/src/ratchet/kdf.ts | 21 + packages/sdk/src/ratchet/session.ts | 44 +- packages/sdk/src/ratchet/types.ts | 20 +- packages/sdk/test/ratchet.test.ts | 790 +++++++++--------- plan.md | 598 +++++++++++-- 18 files changed, 1361 insertions(+), 598 deletions(-) diff --git a/.gitignore b/.gitignore index cc8e32d..4a5b58c 100644 --- a/.gitignore +++ b/.gitignore @@ -18,3 +18,7 @@ dist ignition/deployments/chain-31337 ignition/deployments/chain-84532 +.aider* +.venv/ +.envrc +.python-version diff --git a/apps/demo/src/hooks/useChatActions.ts b/apps/demo/src/hooks/useChatActions.ts index 4e417ba..aa844ff 100644 --- a/apps/demo/src/hooks/useChatActions.ts +++ b/apps/demo/src/hooks/useChatActions.ts @@ -179,14 +179,15 @@ export const useChatActions = ({ await dbService.saveRatchetSession(ratchetSession); + // Use ratcheted topics from session for contact storage const newContact: Contact = { address: handshake.sender, ownerAddress: verbethClient.userAddress, status: "established", identityPubKey: handshake.identityPubKey, signingPubKey: handshake.signingPubKey, - topicOutbound, - topicInbound, + topicOutbound: ratchetSession.currentTopicOutbound, + topicInbound: ratchetSession.currentTopicInbound, conversationId: ratchetSession.conversationId, lastMessage: responseMessage, lastTimestamp: Date.now(), @@ -204,7 +205,7 @@ export const useChatActions = ({ const acceptanceMessage = { id: generateTempMessageId(), - topic: topicOutbound, + topic: ratchetSession.currentTopicOutbound, sender: verbethClient.userAddress, recipient: handshake.sender, ciphertext: "", diff --git a/apps/demo/src/hooks/useMessageListener.ts b/apps/demo/src/hooks/useMessageListener.ts index 814a512..ed8937a 100644 --- a/apps/demo/src/hooks/useMessageListener.ts +++ b/apps/demo/src/hooks/useMessageListener.ts @@ -299,68 +299,62 @@ export const useMessageListener = ({ } } - const establishedContacts = contacts.filter( - (c) => c.status === "established" - ); - if (establishedContacts.length > 0) { - // 1) INBOUND ONLY: listen exclusively to topics where we receive messages - const inboundTopics = establishedContacts - .map((c) => c.topicInbound) - .filter(Boolean); - - if (inboundTopics.length > 0) { - const messageFilterIn = { - address: LOGCHAIN_SINGLETON_ADDR, - topics: [EVENT_SIGNATURES.MessageSent, null, inboundTopics], - }; - const inboundLogs = await safeGetLogs( - messageFilterIn, - fromBlock, - toBlock - ); + // Get ALL active inbound topics (current + previous within grace period) + const activeTopics = await dbService.getAllActiveInboundTopics(address); - for (const log of inboundLogs) { - const logKey = `${log.transactionHash}-${log.logIndex}`; - if (!processedLogs.current.has(logKey)) { - processedLogs.current.add(logKey); - allEvents.push({ - logKey, - eventType: "message", - rawLog: log, - blockNumber: log.blockNumber, - timestamp: Date.now(), - }); - } + if (activeTopics.length > 0) { + // Query messages on all active topics + const messageFilterIn = { + address: LOGCHAIN_SINGLETON_ADDR, + topics: [EVENT_SIGNATURES.MessageSent, null, activeTopics], + }; + const inboundLogs = await safeGetLogs( + messageFilterIn, + fromBlock, + toBlock + ); + + for (const log of inboundLogs) { + const logKey = `${log.transactionHash}-${log.logIndex}`; + if (!processedLogs.current.has(logKey)) { + processedLogs.current.add(logKey); + allEvents.push({ + logKey, + eventType: "message", + rawLog: log, + blockNumber: log.blockNumber, + timestamp: Date.now(), + }); } } + } - // 2) OUTBOUND CONFIRMATION: use emitterAddress (Safe in fast mode, EOA in classic) - const emitter = emitterAddress || address; - if (emitter) { - const senderTopic = - "0x000000000000000000000000" + emitter.slice(2).toLowerCase(); - const messageFilterOutConfirm = { - address: LOGCHAIN_SINGLETON_ADDR, - topics: [EVENT_SIGNATURES.MessageSent, senderTopic], - }; - const outLogs = await safeGetLogs( - messageFilterOutConfirm, - fromBlock, - toBlock - ); + // 2) OUTBOUND CONFIRMATION: use emitterAddress (Safe in fast mode, EOA in classic) + const emitter = emitterAddress || address; + if (emitter) { + const senderTopic = + "0x000000000000000000000000" + emitter.slice(2).toLowerCase(); + const messageFilterOutConfirm = { + address: LOGCHAIN_SINGLETON_ADDR, + topics: [EVENT_SIGNATURES.MessageSent, senderTopic], + }; + const outLogs = await safeGetLogs( + messageFilterOutConfirm, + fromBlock, + toBlock + ); - for (const log of outLogs) { - const logKey = `${log.transactionHash}-${log.logIndex}`; - if (!processedLogs.current.has(logKey)) { - processedLogs.current.add(logKey); - allEvents.push({ - logKey, - eventType: "message", - rawLog: log, - blockNumber: log.blockNumber, - timestamp: Date.now(), - }); - } + for (const log of outLogs) { + const logKey = `${log.transactionHash}-${log.logIndex}`; + if (!processedLogs.current.has(logKey)) { + processedLogs.current.add(logKey); + allEvents.push({ + logKey, + eventType: "message", + rawLog: log, + blockNumber: log.blockNumber, + timestamp: Date.now(), + }); } } } diff --git a/apps/demo/src/hooks/useMessageProcessor.ts b/apps/demo/src/hooks/useMessageProcessor.ts index 61badca..7b447c0 100644 --- a/apps/demo/src/hooks/useMessageProcessor.ts +++ b/apps/demo/src/hooks/useMessageProcessor.ts @@ -74,6 +74,7 @@ export const useMessageProcessor = ({ async (events: ProcessedEvent[]) => { if (!address) return; + // Session cache keyed by conversationId (not topic) for topic ratcheting support const batchSessionCache = new Map(); const messageEvents = events.filter((e) => e.eventType === "message"); diff --git a/apps/demo/src/hooks/useMessageQueue.ts b/apps/demo/src/hooks/useMessageQueue.ts index 86580af..77bc792 100644 --- a/apps/demo/src/hooks/useMessageQueue.ts +++ b/apps/demo/src/hooks/useMessageQueue.ts @@ -143,11 +143,15 @@ export const useMessageQueue = ({ const sessionBefore = currentSession; const plaintext = new TextEncoder().encode(message.plaintext); - const { session: nextSession, header, ciphertext, signature } = ratchetEncrypt( + + // ratchetEncrypt now returns topic in the result (ratcheted topic) + const encryptResult = ratchetEncrypt( sessionBefore, plaintext, verbethClient.identityKeyPairInstance.signingSecretKey ); + + const { session: nextSession, header, ciphertext, signature, topic: ratchetedTopic } = encryptResult; // ===================================================================== // Update BOTH in-memory cache AND DB immediately after encryption @@ -163,7 +167,7 @@ export const useMessageQueue = ({ sessionCacheRef.current.set(conversationId, nextSession); await dbService.saveRatchetSession(nextSession); - addLog(`๐Ÿ’พ Session state committed (sendingMsgNumber=${nextSession.sendingMsgNumber})`); + addLog(`๐Ÿ’พ Session state committed (sendingMsgNumber=${nextSession.sendingMsgNumber}, topicEpoch=${nextSession.topicEpoch})`); // Package binary payload const payload = packageRatchetPayload(signature, header, ciphertext); @@ -173,7 +177,7 @@ export const useMessageQueue = ({ const pending: PendingOutbound = { id: message.id, conversationId, - topic: sessionBefore.topicOutbound, + topic: ratchetedTopic, // Use ratcheted topic from EncryptResult payloadHex, plaintext: message.plaintext, sessionStateBefore: JSON.stringify(serializeRatchetSession(sessionBefore)), @@ -190,9 +194,10 @@ export const useMessageQueue = ({ await dbService.updatePendingOutboundStatus(message.id, "submitted"); + // Use ratcheted topic from EncryptResult for on-chain message const tx = await verbethClient.executorInstance.sendMessage( payload, - sessionBefore.topicOutbound, + ratchetedTopic, timestamp, BigInt(nonce) ); @@ -204,9 +209,11 @@ export const useMessageQueue = ({ addLog(`๐Ÿ“ค Message sent: "${message.plaintext.slice(0, 30)}..." (tx: ${tx.hash.slice(0, 10)}..., n=${nonce})`); - // Update contact + // Update contact with current topic const updatedContact: Contact = { ...message.contact, + topicOutbound: nextSession.currentTopicOutbound, + topicInbound: nextSession.currentTopicInbound, lastMessage: message.plaintext, lastTimestamp: Date.now(), }; diff --git a/apps/demo/src/services/DbService.ts b/apps/demo/src/services/DbService.ts index e8194ac..d49d9c3 100644 --- a/apps/demo/src/services/DbService.ts +++ b/apps/demo/src/services/DbService.ts @@ -9,12 +9,7 @@ import type { PendingHandshake, PendingOutbound, } from "../types.js"; -import { - serializeRatchetSession, - deserializeRatchetSession, -} from "../types.js"; import type { RatchetSession } from "@verbeth/sdk"; -import { pruneExpiredSkippedKeys } from "@verbeth/sdk"; import { RatchetDbService } from "./RatchetDbService.js"; export class DbService { @@ -446,10 +441,13 @@ export class DbService { ): Promise { return this.ratchet.getRatchetSessionByConversation(conversationId); } - getRatchetSessionByTopic( - topicInbound: string + getRatchetSessionByAnyInboundTopic( + topic: string ): Promise { - return this.ratchet.getRatchetSessionByTopic(topicInbound); + return this.ratchet.getRatchetSessionByAnyInboundTopic(topic); + } + getAllActiveInboundTopics(myAddress: string): Promise { + return this.ratchet.getAllActiveInboundTopics(myAddress); } deleteRatchetSession(conversationId: string): Promise { return this.ratchet.deleteRatchetSession(conversationId); diff --git a/apps/demo/src/services/EventProcessorService.ts b/apps/demo/src/services/EventProcessorService.ts index 5ad9ffd..5313ced 100644 --- a/apps/demo/src/services/EventProcessorService.ts +++ b/apps/demo/src/services/EventProcessorService.ts @@ -29,6 +29,7 @@ import { } from "@verbeth/sdk"; import { dbService } from "./DbService.js"; +import { RatchetDbService } from "./RatchetDbService.js"; import { Contact, Message, @@ -162,8 +163,11 @@ export async function processHandshakeEvent( } catch (e) {} } - const existingContact = await dbService.getContact(identityAddress, address); - const isExistingEstablished = existingContact?.status === 'established'; + const existingContact = await dbService.getContact( + identityAddress, + address + ); + const isExistingEstablished = existingContact?.status === "established"; const pendingHandshake: PendingHandshake = { id: log.transactionHash, @@ -180,9 +184,9 @@ export async function processHandshakeEvent( isExistingContact: isExistingEstablished, }; - const messagePrefix = pendingHandshake.isExistingContact - ? 'Session reset request received' - : 'Request received'; + const messagePrefix = pendingHandshake.isExistingContact + ? "Session reset request received" + : "Request received"; const systemMessage: Message = { id: generateTempMessageId(), @@ -208,11 +212,14 @@ export async function processHandshakeEvent( await dbService.savePendingHandshake(pendingHandshake); await dbService.saveMessage(systemMessage); - const logSuffix = isExistingEstablished ? ' (session reset)' : ''; + const logSuffix = isExistingEstablished ? " (session reset)" : ""; onLog( - `๐Ÿ“จ Handshake received from ${identityAddress.slice(0, 8)}...${logSuffix} ${ - isVerified ? "โœ…" : "โš ๏ธ" - }: "${handshakeContent.plaintextPayload}"` + `๐Ÿ“จ Handshake received from ${identityAddress.slice( + 0, + 8 + )}...${logSuffix} ${isVerified ? "โœ…" : "โš ๏ธ"}: "${ + handshakeContent.plaintextPayload + }"` ); return { pendingHandshake, systemMessage }; @@ -324,7 +331,10 @@ export async function processHandshakeResponseEvent( if (!isValidTopics) { onLog( - `โŒ Invalid duplex topics checksum for ${contact.address.slice(0, 8)}...` + `โŒ Invalid duplex topics checksum for ${contact.address.slice( + 0, + 8 + )}...` ); return null; } @@ -345,14 +355,15 @@ export async function processHandshakeResponseEvent( topicInbound, }); + // Use ratcheted topics from session for contact storage const updatedContact: Contact = { ...contact, status: "established" as ContactStatus, identityPubKey, signingPubKey, handshakeEphemeralSecret: undefined, - topicOutbound, - topicInbound, + topicOutbound: ratchetSession.currentTopicOutbound, + topicInbound: ratchetSession.currentTopicInbound, conversationId: ratchetSession.conversationId, lastMessage: note || "Handshake accepted", lastTimestamp: Date.now(), @@ -400,6 +411,10 @@ export async function processHandshakeResponseEvent( // Message Processing (Outgoing Confirmation + Incoming Decryption) // ============================================================================= +/** + * Process a message event. + * Session cache is keyed by conversationId (not topic) to handle topic ratcheting. + */ export async function processMessageEvent( event: ProcessedEvent, address: string, @@ -422,7 +437,8 @@ export async function processMessageEvent( const ciphertextHex = ciphertextBytes as string; const ciphertextRaw = hexToUint8Array(ciphertextHex); const emitter = emitterAddress || address; - const isOurMessage = emitter && sender.toLowerCase() === emitter.toLowerCase(); + const isOurMessage = + emitter && sender.toLowerCase() === emitter.toLowerCase(); if (!isOurMessage) { const already = await dbService.getByDedupKey(dedupKey); @@ -460,7 +476,12 @@ export async function processMessageEvent( const finalized = await dbService.finalizePendingOutbound(pending.id); if (!finalized) { - onLog(`โš ๏ธ Failed to finalize pending outbound ${pending.id.slice(0, 8)}...`); + onLog( + `โš ๏ธ Failed to finalize pending outbound ${pending.id.slice( + 0, + 8 + )}...` + ); return null; } @@ -497,26 +518,20 @@ export async function processMessageEvent( // No matching pending record - this shouldn't happen in normal flow onLog( - `โš ๏ธ Outgoing message on-chain but no pending record found (tx: ${log.transactionHash.slice(0, 10)}...)` + `โš ๏ธ Outgoing message on-chain but no pending record found (tx: ${log.transactionHash.slice( + 0, + 10 + )}...)` ); return null; } // ========================================================================= - // INCOMING MESSAGE - Use ratchet session for decryption + // INCOMING MESSAGE - Use multi-topic lookup for ratchet session // ========================================================================= - // Check session cache FIRST, then fall back to DB - let session = sessionCache.get(topic); - - if (!session) { - session = - (await dbService.getRatchetSessionByTopic(topic)) || undefined; - - if (session) { - sessionCache.set(topic, session); - } - } + // Multi-topic lookup: handles both current and previous (grace period) topics + const session = await dbService.getRatchetSessionByAnyInboundTopic(topic); if (!session) { onLog( @@ -528,11 +543,54 @@ export async function processMessageEvent( return null; } + // Check session cache by conversationId (not topic, since topic can change) + let cachedSession = sessionCache.get(session.conversationId); + let workingSession = cachedSession || session; + + // ========================================================================= + // Promuovi next โ†’ current se riceviamo su nextTopicInbound + // ========================================================================= + const topicLower = (topic as string).toLowerCase(); + if ( + workingSession.nextTopicInbound && + topicLower === workingSession.nextTopicInbound.toLowerCase() + ) { + onLog( + `๐Ÿ“ˆ Promoting next topics to current (epoch ${ + workingSession.topicEpoch + } โ†’ ${workingSession.topicEpoch + 1})` + ); + + workingSession = { + ...workingSession, + // Salva current come previous (grace period) + previousTopicInbound: workingSession.currentTopicInbound, + previousTopicExpiry: Date.now() + 5 * 60 * 1000, // 5 min grace + // Promuovi next โ†’ current + currentTopicInbound: workingSession.nextTopicInbound, + currentTopicOutbound: workingSession.nextTopicOutbound!, + // Cancella next (verrร  ricalcolato da dhRatchetStep) + nextTopicInbound: undefined, + nextTopicOutbound: undefined, + topicEpoch: workingSession.topicEpoch + 1, + }; + + // Aggiorna la cache con la sessione promossa + sessionCache.set(workingSession.conversationId, workingSession); + } + // ========================================================================= + // Find contact for signing key verification - const contact = await dbService.getContact(session.contactAddress, address); + const contact = await dbService.getContact( + workingSession.contactAddress, + address + ); if (!contact?.signingPubKey) { onLog( - `โœ— No signing key for contact ${session.contactAddress.slice(0, 8)}...` + `โœ— No signing key for contact ${workingSession.contactAddress.slice( + 0, + 8 + )}...` ); return null; } @@ -574,9 +632,9 @@ export async function processMessageEvent( return null; } - // decrypt with ratchet (signature verified) + // Decrypt with ratchet (signature verified) const decryptResult = ratchetDecrypt( - session, + workingSession, parsed.header, parsed.ciphertext ); @@ -588,8 +646,11 @@ export async function processMessageEvent( return null; } - // Update session cache IMMEDIATELY - sessionCache.set(topic, decryptResult.session); + // Update session cache by conversationId (topic may have changed due to DH ratchet) + sessionCache.set( + decryptResult.session.conversationId, + decryptResult.session + ); const decryptedText = new TextDecoder().decode(decryptResult.plaintext); @@ -612,8 +673,11 @@ export async function processMessageEvent( status: "confirmed", }; + // Update contact with current topic (may have ratcheted) const updatedContact: Contact = { ...contact, + topicInbound: decryptResult.session.currentTopicInbound, + topicOutbound: decryptResult.session.currentTopicOutbound, lastMessage: decryptedText, lastTimestamp: Date.now(), }; @@ -649,14 +713,17 @@ export async function persistSessionCache( ): Promise { if (sessionCache.size === 0) return; - for (const [topic, session] of sessionCache) { + for (const [conversationId, session] of sessionCache) { try { await dbService.saveRatchetSession(session); - onLog(`๐Ÿ’พ Persisted session state for topic ${topic.slice(0, 10)}...`); + onLog(`๐Ÿ’พ Persisted session state for ${conversationId.slice(0, 10)}...`); } catch (error) { onLog( - `โœ— Failed to persist session for topic ${topic.slice(0, 10)}...: ${error}` + `โœ— Failed to persist session for ${conversationId.slice( + 0, + 10 + )}...: ${error}` ); } } -} \ No newline at end of file +} diff --git a/apps/demo/src/services/RatchetDbService.ts b/apps/demo/src/services/RatchetDbService.ts index 0b02af1..b3402a8 100644 --- a/apps/demo/src/services/RatchetDbService.ts +++ b/apps/demo/src/services/RatchetDbService.ts @@ -11,7 +11,7 @@ export class RatchetDbService { async saveRatchetSession(session: RatchetSession): Promise { const stored = serializeRatchetSession(session); - console.log(`๐Ÿ’พ Saving ratchet session: ${stored.conversationId.slice(0, 10)}... (sendingMsgNumber=${stored.sendingMsgNumber})`); + console.log(`๐Ÿ’พ Saving ratchet session: ${stored.conversationId.slice(0, 10)}... (sendingMsgNumber=${stored.sendingMsgNumber}, topicEpoch=${stored.topicEpoch})`); await this.db.ratchetSessions.put(stored); } @@ -29,22 +29,76 @@ export class RatchetDbService { return pruned; } - async getRatchetSessionByTopic(topicInbound: string): Promise { - const stored = await this.db.ratchetSessions - .where("topicInbound") - .equals(topicInbound.toLowerCase()) - .first(); - if (!stored) return null; + /** + * Find session by any active inbound topic (current or previous). + * Handles topic ratcheting grace period. + */ + async getRatchetSessionByAnyInboundTopic(topic: string): Promise { + const topicLower = topic.toLowerCase(); - const session = deserializeRatchetSession(stored); - const pruned = pruneExpiredSkippedKeys(session); + // Try current topic first + let stored = await this.db.ratchetSessions + .where("currentTopicInbound") + .equals(topicLower) + .first(); + + if (stored) { + const session = deserializeRatchetSession(stored); + const pruned = pruneExpiredSkippedKeys(session); + if (pruned.skippedKeys.length !== session.skippedKeys.length) { + await this.saveRatchetSession(pruned); + } + return pruned; + } - if (pruned.skippedKeys.length !== session.skippedKeys.length) { - await this.saveRatchetSession(pruned); + // Try previous topic (check expiry) + stored = await this.db.ratchetSessions + .where("previousTopicInbound") + .equals(topicLower) + .first(); + + if (stored && stored.previousTopicExpiry && Date.now() < stored.previousTopicExpiry) { + const session = deserializeRatchetSession(stored); + const pruned = pruneExpiredSkippedKeys(session); + if (pruned.skippedKeys.length !== session.skippedKeys.length) { + await this.saveRatchetSession(pruned); + } + return pruned; } - return pruned; + return null; + } + + /** + * Get all active inbound topics for a user (for event filtering). + * Returns both current and non-expired previous topics. + */ + async getAllActiveInboundTopics(myAddress: string): Promise { + const sessions = await this.db.ratchetSessions + .where("myAddress") + .equals(myAddress.toLowerCase()) + .toArray(); + + const topics: string[] = []; + const now = Date.now(); + + for (const s of sessions) { + // Current topic + if (s.currentTopicInbound) { + topics.push(s.currentTopicInbound); + } + // Next topic (pre-computed) + if (s.nextTopicInbound) { + topics.push(s.nextTopicInbound); + } + // Previous topic (grace period) + if (s.previousTopicInbound && s.previousTopicExpiry && now < s.previousTopicExpiry) { + topics.push(s.previousTopicInbound); + } } + + return [...new Set(topics)]; +} async deleteRatchetSession(conversationId: string): Promise { await this.db.ratchetSessions.delete(conversationId); diff --git a/apps/demo/src/services/schema.ts b/apps/demo/src/services/schema.ts index 33b1a9c..bb1dc34 100644 --- a/apps/demo/src/services/schema.ts +++ b/apps/demo/src/services/schema.ts @@ -37,13 +37,26 @@ export class VerbEthDatabase extends Dexie { settings: "name", // Ratchet session storage - // Primary key: conversationId - // Indexes: topicInbound (for incoming message lookup), topicOutbound, status ratchetSessions: "conversationId, topicInbound, topicOutbound, status, myAddress, contactAddress", // Pending outbound for two-phase commit - // Primary key: id - // Indexes: conversationId (for sequential blocking), txHash (for confirmation matching) + pendingOutbound: "id, conversationId, txHash, status, createdAt", + }); + + this.version(1).stores({ + identity: "address", + contacts: + "[address+ownerAddress], ownerAddress, lastTimestamp, status, topicOutbound, topicInbound, emitterAddress, conversationId", + messages: + "id, ownerAddress, sender, recipient, topic, nonce, timestamp, blockTimestamp, read, status, [ownerAddress+sender+status], [ownerAddress+sender+topic+nonce+status]", + dedup: "key, messageId, txHash, blockNumber", + pendingHandshakes: "id, ownerAddress, sender, timestamp, verified, emitterAddress", + settings: "name", + + // Ratchet session storage - added currentTopicInbound and previousTopicInbound indexes + ratchetSessions: "conversationId, topicInbound, topicOutbound, currentTopicInbound, previousTopicInbound, myAddress, contactAddress", + + // Pending outbound for two-phase commit pendingOutbound: "id, conversationId, txHash, status, createdAt", }); } diff --git a/apps/demo/src/types.ts b/apps/demo/src/types.ts index 1fdc6bc..31539ec 100644 --- a/apps/demo/src/types.ts +++ b/apps/demo/src/types.ts @@ -130,6 +130,15 @@ export interface StoredRatchetSession { createdAt: number; updatedAt: number; epoch: number; + + // === Topic Ratcheting === + currentTopicOutbound: string; + currentTopicInbound: string; + nextTopicOutbound?: string; + nextTopicInbound?: string; + previousTopicInbound?: string; + previousTopicExpiry?: number; + topicEpoch: number; } export interface StoredSkippedKey { @@ -232,8 +241,8 @@ export function serializeRatchetSession(session: SDKRatchetSession): StoredRatch conversationId: session.conversationId, topicOutbound: session.topicOutbound.toLowerCase() as `0x${string}`, topicInbound: session.topicInbound.toLowerCase() as `0x${string}`, - myAddress: session.myAddress, - contactAddress: session.contactAddress, + myAddress: session.myAddress.toLowerCase(), + contactAddress: session.contactAddress.toLowerCase(), rootKey: hexlify(session.rootKey), dhMySecretKey: hexlify(session.dhMySecretKey), @@ -256,6 +265,13 @@ export function serializeRatchetSession(session: SDKRatchetSession): StoredRatch createdAt: session.createdAt, updatedAt: session.updatedAt, epoch: session.epoch, + + // Topic Ratcheting + currentTopicOutbound: session.currentTopicOutbound.toLowerCase(), + currentTopicInbound: session.currentTopicInbound.toLowerCase(), + previousTopicInbound: session.previousTopicInbound?.toLowerCase(), + previousTopicExpiry: session.previousTopicExpiry, + topicEpoch: session.topicEpoch, }; } @@ -291,5 +307,12 @@ export function deserializeRatchetSession(stored: StoredRatchetSession): SDKRatc createdAt: stored.createdAt, updatedAt: stored.updatedAt, epoch: stored.epoch, + + // Topic Ratcheting + currentTopicOutbound: stored.currentTopicOutbound as `0x${string}`, + currentTopicInbound: stored.currentTopicInbound as `0x${string}`, + previousTopicInbound: stored.previousTopicInbound as `0x${string}` | undefined, + previousTopicExpiry: stored.previousTopicExpiry, + topicEpoch: stored.topicEpoch, }; } \ No newline at end of file diff --git a/packages/sdk/src/ratchet/decrypt.ts b/packages/sdk/src/ratchet/decrypt.ts index 7854949..0b26660 100644 --- a/packages/sdk/src/ratchet/decrypt.ts +++ b/packages/sdk/src/ratchet/decrypt.ts @@ -5,10 +5,11 @@ * - Normal sequential message decryption * - DH ratchet steps when sender's DH key changes * - Out-of-order messages via skipped keys + * - Topic ratcheting synchronized with DH ratchet */ import nacl from 'tweetnacl'; -import { hexlify } from 'ethers'; +import { hexlify, getBytes } from 'ethers'; import { RatchetSession, MessageHeader, @@ -16,8 +17,9 @@ import { SkippedKey, MAX_SKIP_PER_MESSAGE, MAX_STORED_SKIPPED_KEYS, + TOPIC_TRANSITION_WINDOW_MS, } from './types.js'; -import { kdfRootKey, kdfChainKey, dh, generateDHKeyPair } from './kdf.js'; +import { kdfRootKey, kdfChainKey, dh, generateDHKeyPair, deriveTopicFromDH } from './kdf.js'; /** * Decrypt a message using the ratchet. @@ -108,12 +110,10 @@ export function ratchetDecrypt( /** * Perform a DH ratchet step when receiving a message with a new DH public key. * - * This advances both the receiving and sending chains: - * 1. Receiving DH: derive new receiving chain from DH(mySecret, theirNewPub) - * 2. Generate new DH keypair for sending - * 3. Sending DH: derive new sending chain from DH(newSecret, theirNewPub) + * This advances both the receiving and sending chains and derives new ratcheted topics */ function dhRatchetStep(session: RatchetSession, theirNewDHPub: Uint8Array): RatchetSession { + // Receiving DH is shared secret from my secret and their new public const dhReceive = dh(session.dhMySecretKey, theirNewDHPub); const { rootKey: rootKey1, chainKey: receivingChainKey } = kdfRootKey( session.rootKey, @@ -125,6 +125,16 @@ function dhRatchetStep(session: RatchetSession, theirNewDHPub: Uint8Array): Ratc const dhSend = dh(newDHKeyPair.secretKey, theirNewDHPub); const { rootKey: rootKey2, chainKey: sendingChainKey } = kdfRootKey(rootKey1, dhSend); + // derive new topics from dhReceive + const saltBytes = getBytes(session.conversationId); + const newTopicOut = deriveTopicFromDH(dhReceive, 'outbound', saltBytes); + const newTopicIn = deriveTopicFromDH(dhReceive, 'inbound', saltBytes); + + + // Deriva i PROSSIMI topics da dhSend (che l'altra parte riceverร  come dhReceive) + const nextTopicOut = deriveTopicFromDH(dhSend, 'outbound', saltBytes); + const nextTopicIn = deriveTopicFromDH(dhSend, 'inbound', saltBytes); + return { ...session, rootKey: rootKey2, @@ -136,6 +146,15 @@ function dhRatchetStep(session: RatchetSession, theirNewDHPub: Uint8Array): Ratc sendingChainKey, sendingMsgNumber: 0, previousChainLength: session.sendingMsgNumber, + + nextTopicOutbound: nextTopicOut, + nextTopicInbound: nextTopicIn, + + currentTopicOutbound: newTopicOut, + currentTopicInbound: newTopicIn, + previousTopicInbound: session.currentTopicInbound, + previousTopicExpiry: Date.now() + TOPIC_TRANSITION_WINDOW_MS, + topicEpoch: session.topicEpoch + 1, }; } @@ -273,4 +292,33 @@ export function pruneExpiredSkippedKeys( skippedKeys: prunedKeys, updatedAt: now, }; +} + +/** + * Check if topic matches this session. + * Returns match type or null. + * + * @param session - Ratchet session to check + * @param topic - Topic to match against + * @returns 'current' if matches current inbound, 'previous' if matches previous (within grace), null otherwise + */ +export function matchesSessionTopic( + session: RatchetSession, + topic: `0x${string}` +): 'current' | 'previous' | null { + const t = topic.toLowerCase(); + + if (session.currentTopicInbound.toLowerCase() === t) { + return 'current'; + } + + if ( + session.previousTopicInbound?.toLowerCase() === t && + session.previousTopicExpiry && + Date.now() < session.previousTopicExpiry + ) { + return 'previous'; + } + + return null; } \ No newline at end of file diff --git a/packages/sdk/src/ratchet/encrypt.ts b/packages/sdk/src/ratchet/encrypt.ts index 0da3895..13605b7 100644 --- a/packages/sdk/src/ratchet/encrypt.ts +++ b/packages/sdk/src/ratchet/encrypt.ts @@ -30,7 +30,7 @@ export function encodeHeader(header: MessageHeader): Uint8Array { * @param session - Current ratchet session state * @param plaintext - Message to encrypt * @param signingSecretKey - Ed25519 secret key for signing (64 bytes) - * @returns Encrypt result with new session state, header, ciphertext, and signature + * @returns Encrypt result with new session state, header, ciphertext, signature, and topic * @throws If session is not ready to send (no sending chain key) */ export function ratchetEncrypt( @@ -88,5 +88,6 @@ export function ratchetEncrypt( header, ciphertext: encryptedPayload, signature, + topic: session.currentTopicOutbound, }; } \ No newline at end of file diff --git a/packages/sdk/src/ratchet/index.ts b/packages/sdk/src/ratchet/index.ts index 6b8c720..3610c12 100644 --- a/packages/sdk/src/ratchet/index.ts +++ b/packages/sdk/src/ratchet/index.ts @@ -1,11 +1,12 @@ // packages/sdk/src/ratchet/index.ts + export { - MAX_SKIP_PER_MESSAGE, MAX_STORED_SKIPPED_KEYS, MAX_SKIPPED_KEYS_AGE_MS, SYNC_BATCH_SIZE, RATCHET_VERSION_V1, + TOPIC_TRANSITION_WINDOW_MS, type RatchetSession, type SkippedKey, @@ -24,6 +25,7 @@ export { kdfChainKey, dh, generateDHKeyPair, + deriveTopicFromDH, } from './kdf.js'; export { @@ -40,6 +42,7 @@ export { export { ratchetDecrypt, pruneExpiredSkippedKeys, + matchesSessionTopic, } from './decrypt.js'; export { diff --git a/packages/sdk/src/ratchet/kdf.ts b/packages/sdk/src/ratchet/kdf.ts index eefbd7f..68ff317 100644 --- a/packages/sdk/src/ratchet/kdf.ts +++ b/packages/sdk/src/ratchet/kdf.ts @@ -10,7 +10,9 @@ import { hkdf } from '@noble/hashes/hkdf'; import { sha256 } from '@noble/hashes/sha2'; import { hmac } from '@noble/hashes/hmac'; +import { keccak256 } from 'ethers'; import nacl from 'tweetnacl'; + /** * @param rootKey - Current root key (32 bytes) * @param dhOutput - DH shared secret (32 bytes) @@ -67,4 +69,23 @@ export function dh( export function generateDHKeyPair(): { secretKey: Uint8Array; publicKey: Uint8Array } { const kp = nacl.box.keyPair(); return { secretKey: kp.secretKey, publicKey: kp.publicKey }; +} + +/** + * Derive topic from DH shared secret. + * Called after each DH ratchet step to rotate topics. + * + * @param dhSharedSecret - DH output from ratchet step (32 bytes) + * @param direction - 'outbound' or 'inbound' for topic direction + * @param salt - Conversation ID bytes for domain separation + * @returns bytes32 topic as hex string + */ +export function deriveTopicFromDH( + dhSharedSecret: Uint8Array, + direction: 'outbound' | 'inbound', + salt: Uint8Array +): `0x${string}` { + const info = `verbeth:topic-${direction}:v2`; + const okm = hkdf(sha256, dhSharedSecret, salt, info, 32); + return keccak256(okm) as `0x${string}`; } \ No newline at end of file diff --git a/packages/sdk/src/ratchet/session.ts b/packages/sdk/src/ratchet/session.ts index 8e8e668..da034c7 100644 --- a/packages/sdk/src/ratchet/session.ts +++ b/packages/sdk/src/ratchet/session.ts @@ -5,13 +5,13 @@ * Initial shared secret is derived from ephemeral to ephemeral DH only. */ -import { keccak256, toUtf8Bytes } from 'ethers'; +import { keccak256, toUtf8Bytes, getBytes } from 'ethers'; import { RatchetSession, InitResponderParams, - InitInitiatorParams + InitInitiatorParams, } from './types.js'; -import { kdfRootKey, dh, generateDHKeyPair } from './kdf.js'; +import { kdfRootKey, dh, generateDHKeyPair, deriveTopicFromDH } from './kdf.js'; /** * Compute deterministic conversation ID from topics. @@ -27,6 +27,8 @@ export function computeConversationId(topicA: string, topicB: string): string { * The responder must persist myResponderEphemeralSecret immediately. * This becomes dhMySecretKey and is required for all future ratchet operations. * + * Epoch 0: uses handshake-derived topics (no ratcheting yet). + * * @param params - Initialization parameters * @returns Initialized ratchet session */ @@ -61,7 +63,6 @@ export function initSessionAsResponder(params: InitResponderParams): RatchetSess rootKey, // Reuse responder ephemeral as first DH ratchet key - // This is already on-chain as responderEphemeralR dhMySecretKey: myResponderEphemeralSecret, dhMyPublicKey: myResponderEphemeralPublic, dhTheirPublicKey: theirHandshakeEphemeralPubKey, @@ -76,6 +77,13 @@ export function initSessionAsResponder(params: InitResponderParams): RatchetSess previousChainLength: 0, skippedKeys: [], + // Topic Ratcheting - Epoch 0: use handshake-derived topics + currentTopicOutbound: topicOutbound, + currentTopicInbound: topicInbound, + previousTopicInbound: undefined, + previousTopicExpiry: undefined, + topicEpoch: 0, + createdAt: now, updatedAt: now, epoch: 0, @@ -89,6 +97,8 @@ export function initSessionAsResponder(params: InitResponderParams): RatchetSess * HandshakeResponse payload, NOT from the on-chain responderEphemeralR field. * The on-chain R is only used for tag verification and is different for unlinkability. * + * Epoch 1: initiator already does first DH step, so topics are ratcheted immediately. + * * @param params - Initialization parameters * @returns Initialized ratchet session */ @@ -104,47 +114,59 @@ export function initSessionAsInitiator(params: InitInitiatorParams): RatchetSess const sharedSecret = dh(myHandshakeEphemeralSecret, theirResponderEphemeralPubKey); - // Derive same initial root key as hs responder + // Derive same initial root key as responder const { rootKey: initialRootKey, chainKey: bobsSendingChain } = kdfRootKey( - new Uint8Array(32), // Same initial salt + new Uint8Array(32), sharedSecret ); // Generate first DH keypair for sending const myDHKeyPair = generateDHKeyPair(); - // Perform sending ratchet step const dhSend = dh(myDHKeyPair.secretKey, theirResponderEphemeralPubKey); const { rootKey: finalRootKey, chainKey: sendingChainKey } = kdfRootKey( initialRootKey, dhSend ); + // โœ… Deriva epoch 1 topics da dhSend + // Questo sarร  uguale a dhReceive quando Bob fa il suo primo ratchet + const conversationId = computeConversationId(topicOutbound, topicInbound); + const saltBytes = getBytes(conversationId); + const epoch1TopicOut = deriveTopicFromDH(dhSend, 'outbound', saltBytes); + const epoch1TopicIn = deriveTopicFromDH(dhSend, 'inbound', saltBytes); + const now = Date.now(); return { - conversationId: computeConversationId(topicOutbound, topicInbound), + conversationId, topicOutbound, topicInbound, myAddress, contactAddress, rootKey: finalRootKey, - dhMySecretKey: myDHKeyPair.secretKey, dhMyPublicKey: myDHKeyPair.publicKey, - dhTheirPublicKey: theirResponderEphemeralPubKey, sendingChainKey, sendingMsgNumber: 0, - receivingChainKey: bobsSendingChain, receivingMsgNumber: 0, previousChainLength: 0, skippedKeys: [], + // โœ… FIX: Inizia a epoch 0, ma pre-calcola epoch 1 topics + // E ascolta su ENTRAMBI i topic inbound + currentTopicOutbound: topicOutbound, + currentTopicInbound: topicInbound, + // Aggiungi questi nuovi campi per il "next" topic + nextTopicOutbound: epoch1TopicOut, + nextTopicInbound: epoch1TopicIn, + topicEpoch: 0, + createdAt: now, updatedAt: now, epoch: 0, diff --git a/packages/sdk/src/ratchet/types.ts b/packages/sdk/src/ratchet/types.ts index 9f6ad2f..c9410a2 100644 --- a/packages/sdk/src/ratchet/types.ts +++ b/packages/sdk/src/ratchet/types.ts @@ -30,6 +30,11 @@ export const SYNC_BATCH_SIZE = 10_000; */ export const RATCHET_VERSION_V1 = 0x01; +/** + * Topic transition window (5 minutes). + */ +export const TOPIC_TRANSITION_WINDOW_MS = 5 * 60 * 1000; + /** * Ratchet session state. * @@ -41,9 +46,9 @@ export interface RatchetSession { // === Conversation Identity === /** Primary key: keccak256(sort([topicOut, topicIn])) */ conversationId: string; - /** My sending topic (bytes32 hex) */ + /** Original handshake-derived outbound topic (immutable reference) */ topicOutbound: `0x${string}`; - /** My receiving topic (bytes32 hex) */ + /** Original handshake-derived inbound topic (immutable reference) */ topicInbound: `0x${string}`; /** My EOA address (for convenience/lookup) */ myAddress: string; @@ -80,6 +85,15 @@ export interface RatchetSession { /** Stored keys for out-of-order messages */ skippedKeys: SkippedKey[]; + // === Topic Ratcheting === + currentTopicOutbound: `0x${string}`; + currentTopicInbound: `0x${string}`; + nextTopicOutbound?: `0x${string}`; + nextTopicInbound?: `0x${string}`; + previousTopicInbound?: `0x${string}`; + previousTopicExpiry?: number; + topicEpoch: number; + // === Metadata === /** Session creation timestamp */ createdAt: number; @@ -125,6 +139,8 @@ export interface EncryptResult { header: MessageHeader; ciphertext: Uint8Array; signature: Uint8Array; + /** Current outbound topic to use for this message */ + topic: `0x${string}`; } /** diff --git a/packages/sdk/test/ratchet.test.ts b/packages/sdk/test/ratchet.test.ts index d222043..6064ed1 100644 --- a/packages/sdk/test/ratchet.test.ts +++ b/packages/sdk/test/ratchet.test.ts @@ -1,433 +1,445 @@ // packages/sdk/test/ratchet.test.ts -import { describe, it, expect, beforeEach } from "vitest"; -import nacl from "tweetnacl"; +import { describe, it, expect, beforeEach } from 'vitest'; +import nacl from 'tweetnacl'; + import { + deriveTopicFromDH, initSessionAsResponder, initSessionAsInitiator, - computeConversationId, ratchetEncrypt, ratchetDecrypt, - pruneExpiredSkippedKeys, - packageRatchetPayload, - parseRatchetPayload, - isRatchetPayload, - hexToBytes, - bytesToHex, - verifyMessageSignature, - generateDHKeyPair, - RatchetSession, -} from "../src/ratchet/index.js"; - - -function createTestTopics(): { topicOut: `0x${string}`; topicIn: `0x${string}` } { - const randomBytes = nacl.randomBytes(32); - const topicOut = bytesToHex(randomBytes) as `0x${string}`; - const topicIn = bytesToHex(nacl.randomBytes(32)) as `0x${string}`; - return { topicOut, topicIn }; -} - -function createSigningKeyPair() { - return nacl.sign.keyPair(); -} - -// ============================================================================= -// Tests -// ============================================================================= - -describe("Double Ratchet", () => { - describe("Session Initialization", () => { - it("should create matching sessions for responder and initiator", () => { - const aliceEphemeral = generateDHKeyPair(); - const bobEphemeral = generateDHKeyPair(); - const topics = createTestTopics(); - - // Bob (responder) creates session first - const bobSession = initSessionAsResponder({ - myAddress: "0xBob", - contactAddress: "0xAlice", - myResponderEphemeralSecret: bobEphemeral.secretKey, - myResponderEphemeralPublic: bobEphemeral.publicKey, - theirHandshakeEphemeralPubKey: aliceEphemeral.publicKey, - topicOutbound: topics.topicIn, // Bob's outbound = Alice's inbound - topicInbound: topics.topicOut, // Bob's inbound = Alice's outbound - }); - - // Alice (initiator) creates session after receiving response - const aliceSession = initSessionAsInitiator({ - myAddress: "0xAlice", - contactAddress: "0xBob", - myHandshakeEphemeralSecret: aliceEphemeral.secretKey, - theirResponderEphemeralPubKey: bobEphemeral.publicKey, - topicOutbound: topics.topicOut, - topicInbound: topics.topicIn, - }); - - // Verify conversation IDs match - expect(bobSession.conversationId).toBe(aliceSession.conversationId); - - // Verify both have sending chain keys (can send immediately) - expect(bobSession.sendingChainKey).not.toBeNull(); - expect(aliceSession.sendingChainKey).not.toBeNull(); - - // Verify Alice has receiving chain (for Bob's messages) - expect(aliceSession.receivingChainKey).not.toBeNull(); - }); + matchesSessionTopic, + TOPIC_TRANSITION_WINDOW_MS, + type RatchetSession, +} from '../src/ratchet/index.js'; + +describe('deriveTopicFromDH', () => { + it('derives deterministic topic from DH output', () => { + const dhOutput = nacl.randomBytes(32); + const salt = nacl.randomBytes(32); - it("should compute deterministic conversation ID", () => { - const topicA = "0xaaaa" as const; - const topicB = "0xbbbb" as const; + const topic1 = deriveTopicFromDH(dhOutput, 'outbound', salt); + const topic2 = deriveTopicFromDH(dhOutput, 'outbound', salt); + + expect(topic1).toBe(topic2); + expect(topic1).toMatch(/^0x[a-f0-9]{64}$/); + }); + + it('derives different topics for outbound vs inbound', () => { + const dhOutput = nacl.randomBytes(32); + const salt = nacl.randomBytes(32); + + const topicOut = deriveTopicFromDH(dhOutput, 'outbound', salt); + const topicIn = deriveTopicFromDH(dhOutput, 'inbound', salt); + + expect(topicOut).not.toBe(topicIn); + }); + + it('derives different topics for different DH outputs', () => { + const dhOutput1 = nacl.randomBytes(32); + const dhOutput2 = nacl.randomBytes(32); + const salt = nacl.randomBytes(32); + + const topic1 = deriveTopicFromDH(dhOutput1, 'outbound', salt); + const topic2 = deriveTopicFromDH(dhOutput2, 'outbound', salt); + + expect(topic1).not.toBe(topic2); + }); + + it('derives different topics for different salts', () => { + const dhOutput = nacl.randomBytes(32); + const salt1 = nacl.randomBytes(32); + const salt2 = nacl.randomBytes(32); + + const topic1 = deriveTopicFromDH(dhOutput, 'outbound', salt1); + const topic2 = deriveTopicFromDH(dhOutput, 'outbound', salt2); + + expect(topic1).not.toBe(topic2); + }); +}); - const id1 = computeConversationId(topicA, topicB); - const id2 = computeConversationId(topicB, topicA); +describe('initSessionAsResponder - topic ratcheting', () => { + let responderEphemeral: { secretKey: Uint8Array; publicKey: Uint8Array }; + let initiatorEphemeral: { secretKey: Uint8Array; publicKey: Uint8Array }; + const topicOutbound = '0x' + '1'.repeat(64) as `0x${string}`; + const topicInbound = '0x' + '2'.repeat(64) as `0x${string}`; - expect(id1).toBe(id2); // Order shouldn't matter + beforeEach(() => { + responderEphemeral = nacl.box.keyPair(); + initiatorEphemeral = nacl.box.keyPair(); + }); + + it('initializes at epoch 0 with handshake-derived topics', () => { + const session = initSessionAsResponder({ + myAddress: '0xResponder', + contactAddress: '0xInitiator', + myResponderEphemeralSecret: responderEphemeral.secretKey, + myResponderEphemeralPublic: responderEphemeral.publicKey, + theirHandshakeEphemeralPubKey: initiatorEphemeral.publicKey, + topicOutbound, + topicInbound, }); + + expect(session.topicEpoch).toBe(0); + expect(session.currentTopicOutbound).toBe(topicOutbound); + expect(session.currentTopicInbound).toBe(topicInbound); + expect(session.previousTopicInbound).toBeUndefined(); + expect(session.previousTopicExpiry).toBeUndefined(); }); - describe("Encrypt/Decrypt Round-Trip", () => { - let aliceSession: RatchetSession; - let bobSession: RatchetSession; - let aliceSigning: nacl.SignKeyPair; - let bobSigning: nacl.SignKeyPair; - - beforeEach(() => { - // Setup sessions - const aliceEphemeral = generateDHKeyPair(); - const bobEphemeral = generateDHKeyPair(); - const topics = createTestTopics(); - - bobSession = initSessionAsResponder({ - myAddress: "0xBob", - contactAddress: "0xAlice", - myResponderEphemeralSecret: bobEphemeral.secretKey, - myResponderEphemeralPublic: bobEphemeral.publicKey, - theirHandshakeEphemeralPubKey: aliceEphemeral.publicKey, - topicOutbound: topics.topicIn, - topicInbound: topics.topicOut, - }); - - aliceSession = initSessionAsInitiator({ - myAddress: "0xAlice", - contactAddress: "0xBob", - myHandshakeEphemeralSecret: aliceEphemeral.secretKey, - theirResponderEphemeralPubKey: bobEphemeral.publicKey, - topicOutbound: topics.topicOut, - topicInbound: topics.topicIn, - }); - - aliceSigning = createSigningKeyPair(); - bobSigning = createSigningKeyPair(); + it('preserves original handshake topics in topicOutbound/topicInbound', () => { + const session = initSessionAsResponder({ + myAddress: '0xResponder', + contactAddress: '0xInitiator', + myResponderEphemeralSecret: responderEphemeral.secretKey, + myResponderEphemeralPublic: responderEphemeral.publicKey, + theirHandshakeEphemeralPubKey: initiatorEphemeral.publicKey, + topicOutbound, + topicInbound, }); - it("should encrypt and decrypt a message (Bob to Alice)", () => { - const plaintext = new TextEncoder().encode("Hello Alice!"); - - // Bob encrypts - const { session: bobAfter, header, ciphertext, signature } = ratchetEncrypt( - bobSession, - plaintext, - bobSigning.secretKey - ); - - // Verify signature - const sigValid = verifyMessageSignature( - signature, - header, - ciphertext, - bobSigning.publicKey - ); - expect(sigValid).toBe(true); - - // Alice decrypts - const result = ratchetDecrypt(aliceSession, header, ciphertext); - - expect(result).not.toBeNull(); - expect(new TextDecoder().decode(result!.plaintext)).toBe("Hello Alice!"); - - // Verify session states advanced - expect(bobAfter.sendingMsgNumber).toBe(1); - expect(result!.session.receivingMsgNumber).toBe(1); + // Original topics preserved for reference + expect(session.topicOutbound).toBe(topicOutbound); + expect(session.topicInbound).toBe(topicInbound); + }); +}); + +describe('initSessionAsInitiator - topic ratcheting', () => { + let responderEphemeral: { secretKey: Uint8Array; publicKey: Uint8Array }; + let initiatorEphemeral: { secretKey: Uint8Array; publicKey: Uint8Array }; + const topicOutbound = '0x' + '1'.repeat(64) as `0x${string}`; + const topicInbound = '0x' + '2'.repeat(64) as `0x${string}`; + + beforeEach(() => { + responderEphemeral = nacl.box.keyPair(); + initiatorEphemeral = nacl.box.keyPair(); + }); + + it('initializes at epoch 1 with ratcheted topics', () => { + const session = initSessionAsInitiator({ + myAddress: '0xInitiator', + contactAddress: '0xResponder', + myHandshakeEphemeralSecret: initiatorEphemeral.secretKey, + theirResponderEphemeralPubKey: responderEphemeral.publicKey, + topicOutbound, + topicInbound, }); - it("should encrypt and decrypt a message (Alice to Bob)", () => { - const plaintext = new TextEncoder().encode("Hello Bob!"); - - // Alice encrypts - const { session: aliceAfter, header, ciphertext, signature } = ratchetEncrypt( - aliceSession, - plaintext, - aliceSigning.secretKey - ); - - // Verify signature - const sigValid = verifyMessageSignature( - signature, - header, - ciphertext, - aliceSigning.publicKey - ); - expect(sigValid).toBe(true); - - // Bob decrypts (triggers DH ratchet since Alice has new DH key) - const result = ratchetDecrypt(bobSession, header, ciphertext); - - expect(result).not.toBeNull(); - expect(new TextDecoder().decode(result!.plaintext)).toBe("Hello Bob!"); + expect(session.topicEpoch).toBe(1); + // Current topics should be ratcheted (different from handshake) + expect(session.currentTopicOutbound).not.toBe(topicOutbound); + expect(session.currentTopicInbound).not.toBe(topicInbound); + expect(session.currentTopicOutbound).toMatch(/^0x[a-f0-9]{64}$/); + expect(session.currentTopicInbound).toMatch(/^0x[a-f0-9]{64}$/); + }); + + it('sets previous topic with transition window', () => { + const now = Date.now(); + const session = initSessionAsInitiator({ + myAddress: '0xInitiator', + contactAddress: '0xResponder', + myHandshakeEphemeralSecret: initiatorEphemeral.secretKey, + theirResponderEphemeralPubKey: responderEphemeral.publicKey, + topicOutbound, + topicInbound, }); - it("should handle alternating messages (ping-pong)", () => { - // Bob -> Alice - const msg1 = new TextEncoder().encode("Message 1 from Bob"); - const enc1 = ratchetEncrypt(bobSession, msg1, bobSigning.secretKey); - const dec1 = ratchetDecrypt(aliceSession, enc1.header, enc1.ciphertext); - expect(dec1).not.toBeNull(); - - // Update sessions - bobSession = enc1.session; - aliceSession = dec1!.session; - - // Alice -> Bob - const msg2 = new TextEncoder().encode("Message 2 from Alice"); - const enc2 = ratchetEncrypt(aliceSession, msg2, aliceSigning.secretKey); - const dec2 = ratchetDecrypt(bobSession, enc2.header, enc2.ciphertext); - expect(dec2).not.toBeNull(); - - // Update sessions - aliceSession = enc2.session; - bobSession = dec2!.session; - - // Bob -> Alice again - const msg3 = new TextEncoder().encode("Message 3 from Bob"); - const enc3 = ratchetEncrypt(bobSession, msg3, bobSigning.secretKey); - const dec3 = ratchetDecrypt(aliceSession, enc3.header, enc3.ciphertext); - expect(dec3).not.toBeNull(); - - expect(new TextDecoder().decode(dec3!.plaintext)).toBe("Message 3 from Bob"); + expect(session.previousTopicInbound).toBe(topicInbound); + expect(session.previousTopicExpiry).toBeDefined(); + expect(session.previousTopicExpiry!).toBeGreaterThanOrEqual(now + TOPIC_TRANSITION_WINDOW_MS - 100); + expect(session.previousTopicExpiry!).toBeLessThanOrEqual(now + TOPIC_TRANSITION_WINDOW_MS + 100); + }); + + it('preserves original handshake topics in topicOutbound/topicInbound', () => { + const session = initSessionAsInitiator({ + myAddress: '0xInitiator', + contactAddress: '0xResponder', + myHandshakeEphemeralSecret: initiatorEphemeral.secretKey, + theirResponderEphemeralPubKey: responderEphemeral.publicKey, + topicOutbound, + topicInbound, }); - it("should handle multiple sequential messages from same sender", () => { - const messages = ["First", "Second", "Third"]; - let currentBobSession = bobSession; - let currentAliceSession = aliceSession; - - // Bob sends multiple messages - for (const msg of messages) { - const plaintext = new TextEncoder().encode(msg); - const encrypted = ratchetEncrypt(currentBobSession, plaintext, bobSigning.secretKey); - currentBobSession = encrypted.session; - - const decrypted = ratchetDecrypt(currentAliceSession, encrypted.header, encrypted.ciphertext); - expect(decrypted).not.toBeNull(); - expect(new TextDecoder().decode(decrypted!.plaintext)).toBe(msg); - currentAliceSession = decrypted!.session; - } - - expect(currentBobSession.sendingMsgNumber).toBe(3); - expect(currentAliceSession.receivingMsgNumber).toBe(3); + // Original topics preserved for reference/lookup + expect(session.topicOutbound).toBe(topicOutbound); + expect(session.topicInbound).toBe(topicInbound); + }); +}); + +describe('matchesSessionTopic', () => { + let session: RatchetSession; + + beforeEach(() => { + const responderEphemeral = nacl.box.keyPair(); + const initiatorEphemeral = nacl.box.keyPair(); + + session = initSessionAsInitiator({ + myAddress: '0xInitiator', + contactAddress: '0xResponder', + myHandshakeEphemeralSecret: initiatorEphemeral.secretKey, + theirResponderEphemeralPubKey: responderEphemeral.publicKey, + topicOutbound: '0x' + '1'.repeat(64) as `0x${string}`, + topicInbound: '0x' + '2'.repeat(64) as `0x${string}`, }); }); - describe("Binary Codec", () => { - it("should encode and decode payload correctly", () => { - const signature = nacl.randomBytes(64); - const header = { - dh: nacl.randomBytes(32), - pn: 42, - n: 123, - }; - const ciphertext = nacl.randomBytes(100); - - const payload = packageRatchetPayload(signature, header, ciphertext); - const parsed = parseRatchetPayload(payload); - - expect(parsed).not.toBeNull(); - expect(parsed!.version).toBe(0x01); - expect(Buffer.from(parsed!.signature)).toEqual(Buffer.from(signature)); - expect(Buffer.from(parsed!.header.dh)).toEqual(Buffer.from(header.dh)); - expect(parsed!.header.pn).toBe(42); - expect(parsed!.header.n).toBe(123); - expect(Buffer.from(parsed!.ciphertext)).toEqual(Buffer.from(ciphertext)); - }); + it('returns "current" for current inbound topic', () => { + const result = matchesSessionTopic(session, session.currentTopicInbound); + expect(result).toBe('current'); + }); + + it('returns "current" for current inbound topic (case insensitive)', () => { + const upperTopic = session.currentTopicInbound.toUpperCase() as `0x${string}`; + const result = matchesSessionTopic(session, upperTopic); + expect(result).toBe('current'); + }); - it("should detect ratchet payload format", () => { - const validPayload = new Uint8Array(110); - validPayload[0] = 0x01; // Version byte + it('returns "previous" for previous topic within grace period', () => { + expect(session.previousTopicInbound).toBeDefined(); + const result = matchesSessionTopic(session, session.previousTopicInbound!); + expect(result).toBe('previous'); + }); - expect(isRatchetPayload(validPayload)).toBe(true); + it('returns null for previous topic after expiry', () => { + // Manually expire the previous topic + const expiredSession = { + ...session, + previousTopicExpiry: Date.now() - 1000, // 1 second ago + }; - const jsonPayload = new TextEncoder().encode('{"v":1}'); - expect(isRatchetPayload(jsonPayload)).toBe(false); - }); + const result = matchesSessionTopic(expiredSession, expiredSession.previousTopicInbound!); + expect(result).toBeNull(); + }); - it("should reject truncated payloads", () => { - const truncated = new Uint8Array(50); - truncated[0] = 0x01; + it('returns null for unknown topic', () => { + const unknownTopic = '0x' + 'f'.repeat(64) as `0x${string}`; + const result = matchesSessionTopic(session, unknownTopic); + expect(result).toBeNull(); + }); - expect(parseRatchetPayload(truncated)).toBeNull(); + it('returns null when no previous topic exists', () => { + const sessionNoPrevious = { + ...session, + previousTopicInbound: undefined, + previousTopicExpiry: undefined, + }; + + const result = matchesSessionTopic(sessionNoPrevious, session.topicInbound); + expect(result).toBeNull(); + }); +}); + +describe('ratchetEncrypt - topic in result', () => { + let session: RatchetSession; + let signingKeyPair: nacl.SignKeyPair; + + beforeEach(() => { + const responderEphemeral = nacl.box.keyPair(); + const initiatorEphemeral = nacl.box.keyPair(); + signingKeyPair = nacl.sign.keyPair(); + + session = initSessionAsInitiator({ + myAddress: '0xInitiator', + contactAddress: '0xResponder', + myHandshakeEphemeralSecret: initiatorEphemeral.secretKey, + theirResponderEphemeralPubKey: responderEphemeral.publicKey, + topicOutbound: '0x' + '1'.repeat(64) as `0x${string}`, + topicInbound: '0x' + '2'.repeat(64) as `0x${string}`, }); }); - describe("Authentication", () => { - it("should reject invalid signatures", () => { - const header = { - dh: nacl.randomBytes(32), - pn: 0, - n: 0, - }; - const ciphertext = nacl.randomBytes(50); - const wrongSignature = nacl.randomBytes(64); - const signingKey = createSigningKeyPair(); - - const result = verifyMessageSignature( - wrongSignature, - header, - ciphertext, - signingKey.publicKey - ); - - expect(result).toBe(false); - }); + it('includes currentTopicOutbound in encrypt result', () => { + const plaintext = new TextEncoder().encode('Hello'); + const result = ratchetEncrypt(session, plaintext, signingKeyPair.secretKey); - it("should reject signatures from wrong key", () => { - const header = { - dh: nacl.randomBytes(32), - pn: 0, - n: 0, - }; - const ciphertext = nacl.randomBytes(50); - const realSigner = createSigningKeyPair(); - const wrongSigner = createSigningKeyPair(); - - // Sign with real key - const headerBytes = new Uint8Array(40); - headerBytes.set(header.dh, 0); - new DataView(headerBytes.buffer).setUint32(32, header.pn, false); - new DataView(headerBytes.buffer).setUint32(36, header.n, false); - - const dataToSign = new Uint8Array(headerBytes.length + ciphertext.length); - dataToSign.set(headerBytes, 0); - dataToSign.set(ciphertext, headerBytes.length); - - const signature = nacl.sign.detached(dataToSign, realSigner.secretKey); - - // Verify with wrong key - const result = verifyMessageSignature( - signature, - header, - ciphertext, - wrongSigner.publicKey // Wrong key! - ); - - expect(result).toBe(false); - }); + expect(result.topic).toBe(session.currentTopicOutbound); + expect(result.topic).toMatch(/^0x[a-f0-9]{64}$/); }); - describe("Skip Key Handling", () => { - it("should handle out-of-order messages", () => { - // Setup sessions - const aliceEphemeral = generateDHKeyPair(); - const bobEphemeral = generateDHKeyPair(); - const topics = createTestTopics(); - - let bobSession = initSessionAsResponder({ - myAddress: "0xBob", - contactAddress: "0xAlice", - myResponderEphemeralSecret: bobEphemeral.secretKey, - myResponderEphemeralPublic: bobEphemeral.publicKey, - theirHandshakeEphemeralPubKey: aliceEphemeral.publicKey, - topicOutbound: topics.topicIn, - topicInbound: topics.topicOut, - }); - - let aliceSession = initSessionAsInitiator({ - myAddress: "0xAlice", - contactAddress: "0xBob", - myHandshakeEphemeralSecret: aliceEphemeral.secretKey, - theirResponderEphemeralPubKey: bobEphemeral.publicKey, - topicOutbound: topics.topicOut, - topicInbound: topics.topicIn, - }); - - const bobSigning = createSigningKeyPair(); - - // Bob sends 3 messages - const enc1 = ratchetEncrypt(bobSession, new TextEncoder().encode("Msg 1"), bobSigning.secretKey); - bobSession = enc1.session; - - const enc2 = ratchetEncrypt(bobSession, new TextEncoder().encode("Msg 2"), bobSigning.secretKey); - bobSession = enc2.session; - - const enc3 = ratchetEncrypt(bobSession, new TextEncoder().encode("Msg 3"), bobSigning.secretKey); - bobSession = enc3.session; - - // Alice receives msg 3 first (out of order) - const dec3 = ratchetDecrypt(aliceSession, enc3.header, enc3.ciphertext); - expect(dec3).not.toBeNull(); - expect(new TextDecoder().decode(dec3!.plaintext)).toBe("Msg 3"); - aliceSession = dec3!.session; - - // Verify skip keys were created for msg 1 and 2 - expect(aliceSession.skippedKeys.length).toBe(2); - - // Alice receives msg 1 (using skip key) - const dec1 = ratchetDecrypt(aliceSession, enc1.header, enc1.ciphertext); - expect(dec1).not.toBeNull(); - expect(new TextDecoder().decode(dec1!.plaintext)).toBe("Msg 1"); - aliceSession = dec1!.session; - - // One skip key used - expect(aliceSession.skippedKeys.length).toBe(1); - - // Alice receives msg 2 (using skip key) - const dec2 = ratchetDecrypt(aliceSession, enc2.header, enc2.ciphertext); - expect(dec2).not.toBeNull(); - expect(new TextDecoder().decode(dec2!.plaintext)).toBe("Msg 2"); - aliceSession = dec2!.session; - - // All skip keys used - expect(aliceSession.skippedKeys.length).toBe(0); + it('returns ratcheted topic (not handshake topic) for initiator', () => { + const plaintext = new TextEncoder().encode('Hello'); + const result = ratchetEncrypt(session, plaintext, signingKeyPair.secretKey); + + // Initiator starts at epoch 1, so topic should be ratcheted + expect(result.topic).not.toBe(session.topicOutbound); + }); + + it('returns handshake topic for responder at epoch 0', () => { + const responderEphemeral = nacl.box.keyPair(); + const initiatorEphemeral = nacl.box.keyPair(); + const topicOutbound = '0x' + '3'.repeat(64) as `0x${string}`; + + const responderSession = initSessionAsResponder({ + myAddress: '0xResponder', + contactAddress: '0xInitiator', + myResponderEphemeralSecret: responderEphemeral.secretKey, + myResponderEphemeralPublic: responderEphemeral.publicKey, + theirHandshakeEphemeralPubKey: initiatorEphemeral.publicKey, + topicOutbound, + topicInbound: '0x' + '4'.repeat(64) as `0x${string}`, }); + + const plaintext = new TextEncoder().encode('Hello'); + const result = ratchetEncrypt(responderSession, plaintext, signingKeyPair.secretKey); + + // Responder at epoch 0 uses handshake topic + expect(result.topic).toBe(topicOutbound); }); +}); + +describe('DH ratchet step - topic rotation', () => { + let aliceSession: RatchetSession; + let bobSession: RatchetSession; + let aliceSigningKeyPair: nacl.SignKeyPair; + let bobSigningKeyPair: nacl.SignKeyPair; + + beforeEach(() => { + // Simulate handshake + const aliceEphemeral = nacl.box.keyPair(); + const bobEphemeral = nacl.box.keyPair(); + aliceSigningKeyPair = nacl.sign.keyPair(); + bobSigningKeyPair = nacl.sign.keyPair(); + + const topicAliceToBob = '0x' + 'a'.repeat(64) as `0x${string}`; + const topicBobToAlice = '0x' + 'b'.repeat(64) as `0x${string}`; + + // Bob is responder + bobSession = initSessionAsResponder({ + myAddress: '0xBob', + contactAddress: '0xAlice', + myResponderEphemeralSecret: bobEphemeral.secretKey, + myResponderEphemeralPublic: bobEphemeral.publicKey, + theirHandshakeEphemeralPubKey: aliceEphemeral.publicKey, + topicOutbound: topicBobToAlice, + topicInbound: topicAliceToBob, + }); - describe("Utility Functions", () => { - it("should prune expired skipped keys", () => { - const session: RatchetSession = { - conversationId: "test", - topicOutbound: "0xabc" as `0x${string}`, - topicInbound: "0xdef" as `0x${string}`, - myAddress: "0x1", - contactAddress: "0x2", - rootKey: new Uint8Array(32), - dhMySecretKey: new Uint8Array(32), - dhMyPublicKey: new Uint8Array(32), - dhTheirPublicKey: new Uint8Array(32), - sendingChainKey: new Uint8Array(32), - sendingMsgNumber: 0, - receivingChainKey: new Uint8Array(32), - receivingMsgNumber: 0, - previousChainLength: 0, - skippedKeys: [ - { dhPubKeyHex: "0x1", msgNumber: 0, messageKey: new Uint8Array(32), createdAt: Date.now() - 1000 }, // Fresh - { dhPubKeyHex: "0x1", msgNumber: 1, messageKey: new Uint8Array(32), createdAt: Date.now() - 100000000 }, // Expired - ], - createdAt: Date.now(), - updatedAt: Date.now(), - epoch: 0, - }; - - const pruned = pruneExpiredSkippedKeys(session, 50000); - - expect(pruned.skippedKeys.length).toBe(1); - expect(pruned.skippedKeys[0].msgNumber).toBe(0); + // Alice is initiator + aliceSession = initSessionAsInitiator({ + myAddress: '0xAlice', + contactAddress: '0xBob', + myHandshakeEphemeralSecret: aliceEphemeral.secretKey, + theirResponderEphemeralPubKey: bobEphemeral.publicKey, + topicOutbound: topicAliceToBob, + topicInbound: topicBobToAlice, }); + }); - it("should convert hex to bytes and back", () => { - const original = nacl.randomBytes(32); - const hex = bytesToHex(original); - const restored = hexToBytes(hex); + it('Alice starts at epoch 1, Bob starts at epoch 0', () => { + expect(aliceSession.topicEpoch).toBe(1); + expect(bobSession.topicEpoch).toBe(0); + }); - expect(Buffer.from(restored)).toEqual(Buffer.from(original)); + it('Bob advances to epoch 1 after receiving message from Alice', () => { + // Alice encrypts a message + const plaintext = new TextEncoder().encode('Hello Bob'); + const encryptResult = ratchetEncrypt(aliceSession, plaintext, aliceSigningKeyPair.secretKey); + aliceSession = encryptResult.session; + + // Bob decrypts - this triggers DH ratchet step + const decryptResult = ratchetDecrypt(bobSession, encryptResult.header, encryptResult.ciphertext); + expect(decryptResult).not.toBeNull(); + bobSession = decryptResult!.session; + + expect(bobSession.topicEpoch).toBe(1); + expect(bobSession.currentTopicOutbound).not.toBe(bobSession.topicOutbound); + expect(bobSession.currentTopicInbound).not.toBe(bobSession.topicInbound); + }); + + it('both parties derive matching topics after DH ratchet', () => { + // Alice encrypts a message + const plaintext = new TextEncoder().encode('Hello Bob'); + const encryptResult = ratchetEncrypt(aliceSession, plaintext, aliceSigningKeyPair.secretKey); + aliceSession = encryptResult.session; + + // Bob decrypts + const decryptResult = ratchetDecrypt(bobSession, encryptResult.header, encryptResult.ciphertext); + bobSession = decryptResult!.session; + + // Alice's outbound should match Bob's inbound + expect(aliceSession.currentTopicOutbound).toBe(bobSession.currentTopicInbound); + // Bob's outbound should match Alice's inbound + expect(bobSession.currentTopicOutbound).toBe(aliceSession.currentTopicInbound); + }); + + it('previous topic is preserved during transition window', () => { + // Alice encrypts a message + const plaintext = new TextEncoder().encode('Hello Bob'); + const encryptResult = ratchetEncrypt(aliceSession, plaintext, aliceSigningKeyPair.secretKey); + aliceSession = encryptResult.session; + + // Bob decrypts + const decryptResult = ratchetDecrypt(bobSession, encryptResult.header, encryptResult.ciphertext); + bobSession = decryptResult!.session; + + // Bob should have previous topic set + expect(bobSession.previousTopicInbound).toBeDefined(); + expect(bobSession.previousTopicExpiry).toBeDefined(); + expect(bobSession.previousTopicExpiry!).toBeGreaterThan(Date.now()); + }); + + it('full conversation rotates topics correctly', () => { + const epochs: { alice: number; bob: number }[] = []; + + // Track initial state + epochs.push({ alice: aliceSession.topicEpoch, bob: bobSession.topicEpoch }); + + // Alice -> Bob (Alice already at epoch 1) + let encryptResult = ratchetEncrypt(aliceSession, new TextEncoder().encode('msg1'), aliceSigningKeyPair.secretKey); + aliceSession = encryptResult.session; + let decryptResult = ratchetDecrypt(bobSession, encryptResult.header, encryptResult.ciphertext); + bobSession = decryptResult!.session; + epochs.push({ alice: aliceSession.topicEpoch, bob: bobSession.topicEpoch }); + + // Bob -> Alice (Bob now at epoch 1) + encryptResult = ratchetEncrypt(bobSession, new TextEncoder().encode('msg2'), bobSigningKeyPair.secretKey); + bobSession = encryptResult.session; + decryptResult = ratchetDecrypt(aliceSession, encryptResult.header, encryptResult.ciphertext); + aliceSession = decryptResult!.session; + epochs.push({ alice: aliceSession.topicEpoch, bob: bobSession.topicEpoch }); + + // Alice -> Bob (Alice now at epoch 2) + encryptResult = ratchetEncrypt(aliceSession, new TextEncoder().encode('msg3'), aliceSigningKeyPair.secretKey); + aliceSession = encryptResult.session; + decryptResult = ratchetDecrypt(bobSession, encryptResult.header, encryptResult.ciphertext); + bobSession = decryptResult!.session; + epochs.push({ alice: aliceSession.topicEpoch, bob: bobSession.topicEpoch }); + + // Verify epochs increment with each turn change + expect(epochs[0]).toEqual({ alice: 1, bob: 0 }); + expect(epochs[1]).toEqual({ alice: 1, bob: 1 }); + expect(epochs[2]).toEqual({ alice: 2, bob: 1 }); + expect(epochs[3]).toEqual({ alice: 2, bob: 2 }); + }); +}); + +describe('topic continuity', () => { + it('multiple messages in same direction use same topic', () => { + const responderEphemeral = nacl.box.keyPair(); + const initiatorEphemeral = nacl.box.keyPair(); + const signingKeyPair = nacl.sign.keyPair(); + + let session = initSessionAsInitiator({ + myAddress: '0xAlice', + contactAddress: '0xBob', + myHandshakeEphemeralSecret: initiatorEphemeral.secretKey, + theirResponderEphemeralPubKey: responderEphemeral.publicKey, + topicOutbound: '0x' + '1'.repeat(64) as `0x${string}`, + topicInbound: '0x' + '2'.repeat(64) as `0x${string}`, }); + + const topics: string[] = []; + + // Send multiple messages without receiving any + for (let i = 0; i < 5; i++) { + const result = ratchetEncrypt(session, new TextEncoder().encode(`msg${i}`), signingKeyPair.secretKey); + topics.push(result.topic); + session = result.session; + } + + // All messages should use the same topic (no DH ratchet without receiving) + expect(new Set(topics).size).toBe(1); + expect(session.topicEpoch).toBe(1); // Still epoch 1 }); }); \ No newline at end of file diff --git a/plan.md b/plan.md index ea99976..9df171f 100644 --- a/plan.md +++ b/plan.md @@ -2,9 +2,9 @@ ## Overview -This plan implements Signal-style Double Ratchet for bilateral forward secrecy. Compromising identity keys never allows decrypting past messagesโ€”not even message 0. +This plan implements Signal-style Double Ratchet for bilateral forward secrecy and topic unlinkability. Compromising identity keys never allows decrypting past messagesโ€”not even message 0. -**Scope**: Core Double Ratchet only. Topic ratcheting and post-quantum are separate future phases. +**Scope**: Core Double Ratchet only. Post-quantum are separate future phases. --- @@ -80,18 +80,6 @@ Lookup: `session where topicInbound === event.topic` ``` ### 1.6 Binary Encoding - -``` -Offset โ”‚ Size โ”‚ Field -โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ -0 โ”‚ 1 โ”‚ Version (0x01) -1 โ”‚ 64 โ”‚ Ed25519 signature -65 โ”‚ 32 โ”‚ DH ratchet public key -97 โ”‚ 4 โ”‚ pn (uint32 BE) -101 โ”‚ 4 โ”‚ n (uint32 BE) -105 โ”‚ var โ”‚ Ciphertext (nonce + AEAD) -``` - Fixed overhead: ~105 bytes (vs ~200+ for JSON+base64). ### 1.7 Skipped Keys: Reorg Tolerance, Not Offline Catch-Up @@ -149,71 +137,561 @@ Alice (lost state) โ†’ sendHandshake(bob) โ†’ Bob accepts โ†’ New session --- -## 3. Implementation Milestones +# DH-Synchronized Topic Ratcheting + +Static topics enable long-term correlation of conversations by on-chain observers. Even with encrypted content, the repeated `topic` parameter in `MessageSent` events creates a linkable pattern. + +## Solution: DH-Synchronized Topic Ratcheting + +Derive new topics whenever a DH ratchet step occurs. The DH public key in message headers provides natural synchronizationโ€”both parties know when to rotate topics without additional coordination. + +## Key Insight + +The existing Double Ratchet already: +- Generates new DH keypairs on each turn (in `dhRatchetStep()`) +- Tracks `dhMyPublicKey` and `dhTheirPublicKey` +- Triggers on first message after receiving a new DH public key + +**Topic epochs = DH epochs.** When `dhTheirPublicKey` changes, derive new topics. + +--- + +## Topic Transition Window (5 minutes) โ€” NOT a Wait Time + +The transition window is a **grace period**, not a delay. Messages flow instantly with zero UX impact. + +**What it means:** +- After a DH ratchet step, we listen on BOTH the old topic AND the new topic for 5 minutes +- Messages sent/received immediately on the new topic +- Old topic acceptance handles edge cases only + +**Why it's needed:** +1. **In-flight messages** โ€” A message encrypted before rotation may arrive after rotation +2. **Timing skew** โ€” Parties don't ratchet at the exact same millisecond +3. **Block propagation** โ€” On-chain message may be mined slightly out of order + +**Example timeline:** +``` +t=0:00 Alice sends msg#5, triggers DH ratchet โ†’ new topic T2 +t=0:01 Alice sends msg#6 on T2 โœ“ +t=0:03 Bob receives msg#5, triggers his DH ratchet โ†’ derives same T2 +t=0:04 Bob receives msg#6 on T2 โœ“ +t=0:05 Bob sends reply on T2 โœ“ +``` + +No waiting. The window just ensures we don't drop the rare out-of-order message. + +--- + +# Part 1: SDK Changes (`packages/sdk/`) + +## 1.1 Add `deriveTopicFromDH()` in `kdf.ts` + +```typescript +// packages/sdk/src/ratchet/kdf.ts + +import { keccak256 } from 'ethers'; + +/** + * Derive topic from DH shared secret. + * Called after each DH ratchet step. + */ +export function deriveTopicFromDH( + dhSharedSecret: Uint8Array, + direction: 'outbound' | 'inbound', + salt: Uint8Array // conversationId bytes +): `0x${string}` { + const info = `verbeth:topic-${direction}:v2`; + const okm = hkdf(sha256, dhSharedSecret, salt, info, 32); + return keccak256(okm) as `0x${string}`; +} +``` + +--- + +## 1.2 Extend `RatchetSession` in `types.ts` + +```typescript +// packages/sdk/src/ratchet/types.ts + +export const TOPIC_TRANSITION_WINDOW_MS = 5 * 60 * 1000; + +export interface RatchetSession { + // ... existing fields ... + + // === Topic Ratcheting === + /** Current outbound topic (ratcheted) */ + currentTopicOutbound: `0x${string}`; + /** Current inbound topic (ratcheted) */ + currentTopicInbound: `0x${string}`; + + /** Previous inbound topic (grace period) */ + previousTopicInbound?: `0x${string}`; + /** When to stop accepting on previous topic */ + previousTopicExpiry?: number; + + /** Topic epoch (increments with DH steps) */ + topicEpoch: number; +} +``` + +--- + +## 1.3 Update `initSessionAsResponder()` in `session.ts` + +```typescript +// packages/sdk/src/ratchet/session.ts + +export function initSessionAsResponder(params: InitResponderParams): RatchetSession { + // ... existing DH and chain key derivation ... + + return { + // ... existing fields ... + + // Epoch 0: use handshake-derived topics + currentTopicOutbound: topicOutbound, + currentTopicInbound: topicInbound, + previousTopicInbound: undefined, + previousTopicExpiry: undefined, + topicEpoch: 0, + }; +} +``` + +--- + +## 1.4 Update `initSessionAsInitiator()` in `session.ts` + +```typescript +// packages/sdk/src/ratchet/session.ts + +export function initSessionAsInitiator(params: InitInitiatorParams): RatchetSession { + // ... existing DH ratchet step (generates myDHKeyPair, computes dhSend) ... + + // Derive first ratcheted topics from dhSend + const saltBytes = getBytes(computeConversationId(topicOutbound, topicInbound)); + const ratchetedTopicOut = deriveTopicFromDH(dhSend, 'outbound', saltBytes); + const ratchetedTopicIn = deriveTopicFromDH(dhSend, 'inbound', saltBytes); + + return { + // ... existing fields ... + + // Epoch 1: initiator already did first DH step + currentTopicOutbound: ratchetedTopicOut, + currentTopicInbound: ratchetedTopicIn, + previousTopicInbound: topicInbound, + previousTopicExpiry: Date.now() + TOPIC_TRANSITION_WINDOW_MS, + topicEpoch: 1, + }; +} +``` + +--- + +## 1.5 Update `dhRatchetStep()` in `decrypt.ts` + +```typescript +// packages/sdk/src/ratchet/decrypt.ts + +function dhRatchetStep(session: RatchetSession, theirNewDHPub: Uint8Array): RatchetSession { + // ... existing: compute dhReceive, rootKey1, receivingChainKey ... + // ... existing: generate newDHKeyPair ... + // ... existing: compute dhSend, rootKey2, sendingChainKey ... + + // NEW: Derive ratcheted topics from dhSend + const saltBytes = getBytes(session.conversationId); + const newTopicOut = deriveTopicFromDH(dhSend, 'outbound', saltBytes); + const newTopicIn = deriveTopicFromDH(dhSend, 'inbound', saltBytes); + + return { + ...session, + rootKey: rootKey2, + dhMySecretKey: newDHKeyPair.secretKey, + dhMyPublicKey: newDHKeyPair.publicKey, + dhTheirPublicKey: theirNewDHPub, + receivingChainKey, + receivingMsgNumber: 0, + sendingChainKey, + sendingMsgNumber: 0, + previousChainLength: session.sendingMsgNumber, + + // Topic ratcheting + currentTopicOutbound: newTopicOut, + currentTopicInbound: newTopicIn, + previousTopicInbound: session.currentTopicInbound, + previousTopicExpiry: Date.now() + TOPIC_TRANSITION_WINDOW_MS, + topicEpoch: session.topicEpoch + 1, + }; +} +``` + +--- + +## 1.6 Add `matchesSessionTopic()` helper in `decrypt.ts` + +```typescript +// packages/sdk/src/ratchet/decrypt.ts + +/** + * Check if topic matches this session. + * Returns match type or null. + */ +export function matchesSessionTopic( + session: RatchetSession, + topic: `0x${string}` +): 'current' | 'previous' | null { + const t = topic.toLowerCase(); + + if (session.currentTopicInbound.toLowerCase() === t) { + return 'current'; + } + + if ( + session.previousTopicInbound?.toLowerCase() === t && + session.previousTopicExpiry && + Date.now() < session.previousTopicExpiry + ) { + return 'previous'; + } + + return null; +} +``` + +--- + +## 1.7 Update `ratchetEncrypt()` in `encrypt.ts` -### Milestone 1: SDK Ratchet Core โœ… COMPLETED -Pure crypto module, fully testable without blockchain/DB. +```typescript +// packages/sdk/src/ratchet/encrypt.ts + +export interface EncryptResult { + session: RatchetSession; + header: MessageHeader; + ciphertext: Uint8Array; + signature: Uint8Array; + topic: `0x${string}`; // NEW +} -### Milestone 2: Handshake + Persistence โœ… COMPLETED -Wire ratchet into handshake; sessions persist to IndexedDB. -Ratchet key comes from decrypted payload, NOT on-chain `responderEphemeralR`. +export function ratchetEncrypt( + session: RatchetSession, + plaintext: Uint8Array, + signingSecretKey: Uint8Array +): EncryptResult { + // ... existing encryption ... + + return { + session: newSession, + header, + ciphertext: encryptedPayload, + signature, + topic: session.currentTopicOutbound, // NEW: return current topic + }; +} +``` -### Milestone 3: Encrypted Messaging โœ… COMPLETED -Full send/receive with session caching and batch processing. +--- -**Implementation Details**: +## 1.8 Export new functions in `index.ts` -| Component | Status | Notes | -|-----------|--------|-------| -| `useMessageQueue.ts` | โœ… | Sequential message processing with optimistic UI | -| Session caching | โœ… | Per-conversation cache in `sessionCacheRef` | -| Immediate session commit | โœ… | DB save before tx send (skip-key resilient) | -| Batch incoming processing | โœ… | `processMessageLogWithCache()` with shared cache | -| Auth-first decryption | โœ… | `verifyMessageSignature()` before `ratchetDecrypt()` | -| Pending outbound tracking | โœ… | `PendingOutbound` table for tx confirmation matching | -| Retry failed messages | โœ… | Re-encrypts with current state (burns new slot) | +```typescript +// packages/sdk/src/ratchet/index.ts + +export { + // ... existing exports ... + deriveTopicFromDH, + matchesSessionTopic, + TOPIC_TRANSITION_WINDOW_MS, +} from './kdf.js'; +``` -**Test Cases Verified**: -- โœ… Send โ†’ pending created โ†’ confirmed โ†’ session committed -- โœ… Send failure โ†’ session already advanced, skip key handles gap -- โœ… Batch incoming โ†’ session cache ensures sequential decryption -- โœ… Invalid signature โ†’ rejected before ratchet work (DoS protection) +--- -### Milestone 4: Session Recovery UX +# Part 2: App Layer Changes -**Status**: Existing handshake flow (probably) handles reset naturally. +## 2.1 Update `StoredRatchetSession` in `types.ts` -#### 4.1 Why No Special Protocol Needed +```typescript +// src/types.ts + +export interface StoredRatchetSession { + // ... existing fields ... + + currentTopicOutbound: string; + currentTopicInbound: string; + previousTopicInbound?: string; + previousTopicExpiry?: number; + topicEpoch: number; +} +``` + +--- + +## 2.2 Update serialization in `types.ts` +```typescript +// src/types.ts + +export function serializeRatchetSession(session: RatchetSession): StoredRatchetSession { + return { + // ... existing ... + currentTopicOutbound: session.currentTopicOutbound, + currentTopicInbound: session.currentTopicInbound, + previousTopicInbound: session.previousTopicInbound, + previousTopicExpiry: session.previousTopicExpiry, + topicEpoch: session.topicEpoch, + }; +} + +export function deserializeRatchetSession(stored: StoredRatchetSession): RatchetSession { + return { + // ... existing ... + currentTopicOutbound: stored.currentTopicOutbound as `0x${string}`, + currentTopicInbound: stored.currentTopicInbound as `0x${string}`, + previousTopicInbound: stored.previousTopicInbound as `0x${string}` | undefined, + previousTopicExpiry: stored.previousTopicExpiry, + topicEpoch: stored.topicEpoch, + }; +} ``` -Alice (lost state) โ†’ sends new handshake โ†’ Bob accepts โ†’ new session created + +--- + +## 2.3 Update `schema.ts` โ€” Add indexes + +```typescript +// src/services/schema.ts + +this.version(2).stores({ + // ... existing ... + ratchetSessions: + "conversationId, topicInbound, topicOutbound, currentTopicInbound, previousTopicInbound, myAddress, contactAddress", +}); ``` -What happens: -1. Alice's contact record gets overwritten with `status: "handshake_sent"` -2. New ephemeral keys โ†’ new salt โ†’ new topics -3. Bob sees pending handshake, accepts it -4. New ratchet session created, old one orphaned (but harmless) +--- + +## 2.4 Update `RatchetDbService.ts` โ€” Multi-topic lookup + +```typescript +// src/services/RatchetDbService.ts + +/** + * Find session by any active inbound topic (current or previous). + */ +async getRatchetSessionByAnyInboundTopic(topic: string): Promise { + const topicLower = topic.toLowerCase(); + + // Try current topic first + let stored = await this.db.ratchetSessions + .where("currentTopicInbound") + .equals(topicLower) + .first(); + + if (stored) { + return deserializeRatchetSession(stored); + } + + // Try previous topic (check expiry in caller) + stored = await this.db.ratchetSessions + .where("previousTopicInbound") + .equals(topicLower) + .first(); + + if (stored && stored.previousTopicExpiry && Date.now() < stored.previousTopicExpiry) { + return deserializeRatchetSession(stored); + } + + return null; +} +/** + * Get all active inbound topics for a user (for event filtering). + */ +async getAllActiveInboundTopics(myAddress: string): Promise { + const sessions = await this.db.ratchetSessions + .where("myAddress") + .equals(myAddress.toLowerCase()) + .toArray(); + + const topics: string[] = []; + const now = Date.now(); + + for (const s of sessions) { + topics.push(s.currentTopicInbound); + if (s.previousTopicInbound && s.previousTopicExpiry && now < s.previousTopicExpiry) { + topics.push(s.previousTopicInbound); + } + } + + return [...new Set(topics)]; // dedupe +} +``` -#### 4.2 What's Actually Missing (Nice-to-Have UX) +--- -| Enhancement | Description | Priority | -|-------------|-------------|----------| -| Startup health check | Detect "contacts exist but sessions missing" | Low | -| Receiver hint | Bob sees "Alice (existing contact) requests new session" vs confusing duplicate | Medium | -| Orphan cleanup | Periodically delete ratchet sessions with no matching contact | Low | -| Chat boundary | Visual indicator "Session reset on [date]" | Low | +## 2.5 Update `EventProcessorService.ts` โ€” Use multi-topic lookup -#### 4.3 Current Behavior (Acceptable but improvable) +```typescript +// src/services/EventProcessorService.ts + +export async function processMessageEvent( + event: ProcessedEvent, + address: string, + emitterAddress: string | undefined, + sessionCache: Map, + onLog: (msg: string) => void +): Promise { + // ... existing setup ... + + const topic = log.topics[2]; + + // UPDATED: Check cache by topic, then fall back to multi-topic DB lookup + let session = sessionCache.get(topic); + + if (!session) { + session = await dbService.getRatchetSessionByAnyInboundTopic(topic) || undefined; + + if (session) { + sessionCache.set(topic, session); + } + } + + if (!session) { + onLog(`โ“ Unknown topic: ${topic.slice(0, 10)}...`); + return null; + } + + // ... rest unchanged (signature verify, decrypt, etc.) ... +} +``` + +--- + +## 2.6 Update `useMessageListener.ts` โ€” Query all active topics + +```typescript +// src/hooks/useMessageListener.ts + +const scanBlockRange = async (fromBlock: number, toBlock: number): Promise => { + // ... existing handshake scanning ... + + // UPDATED: Get ALL active inbound topics for this user + const activeTopics = await dbService.getAllActiveInboundTopics(address); + + if (activeTopics.length > 0) { + // Query each topic (or batch if RPC supports OR filters) + for (const topic of activeTopics) { + const messageFilter = { + address: LOGCHAIN_SINGLETON_ADDR, + topics: [EVENT_SIGNATURES.MessageSent, null, topic], + }; + const inboundLogs = await safeGetLogs(messageFilter, fromBlock, toBlock); + + for (const log of inboundLogs) { + const logKey = `${log.transactionHash}-${log.logIndex}`; + if (!processedLogs.current.has(logKey)) { + processedLogs.current.add(logKey); + allEvents.push({ + logKey, + eventType: "message", + rawLog: log, + blockNumber: log.blockNumber, + timestamp: Date.now(), + }); + } + } + } + } + + // .. existing outbound confirmation scanning (unchanged) ... +}; +``` + +--- + +## 2.7 Update `useMessageQueue.ts` (or equivalent) โ€” Use `EncryptResult.topic` + +```typescript +// In your message queue / sending logic + +const sendMessage = async (session: RatchetSession, plaintext: string) => { + const encryptResult = ratchetEncrypt( + session, + new TextEncoder().encode(plaintext), + identityKeyPair.signingSecretKey + ); + + const payload = packageRatchetPayload( + encryptResult.signature, + encryptResult.header, + encryptResult.ciphertext + ); + + // UPDATED: Use topic from encrypt result, not session.topicOutbound + await executor.sendMessage( + payload, + encryptResult.topic, // โ† ratcheted topic + Date.now(), + nonce + ); + + // Persist updated session + await dbService.saveRatchetSession(encryptResult.session); +}; +``` + +--- + +## 2.8 Update `useChatActions.ts` โ€” No direct changes needed + +The hook delegates to `useMessageQueue` which handles encryption. Ensure `useMessageQueue` passes through the `EncryptResult.topic` as shown above. + +--- + +## 2.9 Update `useMessageProcessor.ts` โ€” No direct changes needed + +The hook calls `processMessageEvent` from `EventProcessorService`, which now handles multi-topic lookup internally. + +--- + +# Implementation Order + +| # | Layer | File(s) | Change | +|---|-------|---------|--------| +| 1 | SDK | `kdf.ts` | Add `deriveTopicFromDH()` | +| 2 | SDK | `types.ts` | Extend `RatchetSession`, add constant | +| 3 | SDK | `session.ts` | Update both `initSession*` functions | +| 4 | SDK | `decrypt.ts` | Update `dhRatchetStep()`, add `matchesSessionTopic()` | +| 5 | SDK | `encrypt.ts` | Return `topic` in `EncryptResult` | +| 6 | SDK | `index.ts` | Export new functions | +| 7 | App | `types.ts` | Update `StoredRatchetSession`, serialization | +| 8 | App | `schema.ts` | Add `currentTopicInbound`, `previousTopicInbound` indexes | +| 9 | App | `RatchetDbService.ts` | Add `getRatchetSessionByAnyInboundTopic()`, `getAllActiveInboundTopics()` | +| 10 | App | `EventProcessorService.ts` | Use multi-topic lookup | +| 11 | App | `useMessageListener.ts` | Query all active topics | +| 12 | App | `useMessageQueue.ts` | Use `EncryptResult.topic` for sending | + +--- + +# Testing Checklist + +- [ ] New session (epoch 0): messages use handshake topics +- [ ] Initiator's first message: uses ratcheted topic (epoch 1) +- [ ] Responder receives on ratcheted topic after their DH step +- [ ] Both parties derive identical topics from same DH output +- [ ] Message on previous topic (within window) decrypts successfully +- [ ] Message on expired previous topic is rejected +- [ ] On-chain: observe topic changes after each conversational turn + +--- -| Scenario | What Happens | User Experience | -|----------|--------------|-----------------| -| Alice clears IndexedDB | Loses everything, must re-handshake all contacts | "Start fresh" - acceptable | -| Alice on new device | No data, must re-handshake | Same as new user - acceptable | -| Bob receives 2nd handshake from Alice | Sees new pending request | Slightly confusing but works | -| Old ratchet session | Orphaned in DB | No functional impact | +# Security Notes +1. **Deterministic** โ€” Both parties derive identical topics from `dhSend` +2. **No extra metadata** โ€” Epoch not transmitted; derived from DH state +3. **Unlinkable** โ€” After first DH step, new topic has no on-chain link to handshake +4. **Grace period** โ€” Prevents message loss without adding latency --- ## 4. Future Improvements From 67966ece5870cc747ccc843f59cda83836bdcf3e Mon Sep 17 00:00:00 2001 From: Marco Esposito Date: Thu, 15 Jan 2026 17:58:03 +0100 Subject: [PATCH 13/51] fix message reception failure + cleaning comments --- apps/demo/src/App.tsx | 15 ++- apps/demo/src/components/InitialForm.tsx | 2 +- apps/demo/src/hooks/useInitIdentity.ts | 14 +-- apps/demo/src/hooks/useMessageQueue.ts | 34 ++---- .../src/services/EventProcessorService.ts | 21 +--- apps/demo/src/services/RatchetDbService.ts | 68 ++++++----- apps/demo/src/services/safeAccount.ts | 2 +- apps/demo/src/services/schema.ts | 25 +--- apps/demo/src/types.ts | 17 +-- packages/sdk/src/ratchet/decrypt.ts | 20 ++-- packages/sdk/src/ratchet/session.ts | 16 +-- packages/sdk/test/ratchet.test.ts | 107 +++++------------- 12 files changed, 127 insertions(+), 214 deletions(-) diff --git a/apps/demo/src/App.tsx b/apps/demo/src/App.tsx index 8846258..d3db997 100644 --- a/apps/demo/src/App.tsx +++ b/apps/demo/src/App.tsx @@ -74,7 +74,7 @@ export default function App() { safeAddr, needsIdentityCreation, identityContext, - // Session state (owned by useInitIdentity) + // Session state sessionSignerAddr, needsSessionSetup, isSafeDeployed, @@ -165,16 +165,16 @@ export default function App() { sendHandshake, acceptHandshake, sendMessageToContact, - retryFailedMessage, // NEW: Retry action - cancelQueuedMessage, // NEW: Cancel action - getContactQueueStatus, // NEW: Queue status + retryFailedMessage, + cancelQueuedMessage, + getContactQueueStatus, } = useChatActions({ verbethClient, addLog, updateContact: async (contact: Contact) => { await updateContact(contact); }, addMessage: async (message: any) => { await addMessage(message); }, - updateMessageStatus, // NEW: Pass to useChatActions - removeMessage, // NEW: Pass to useChatActions + updateMessageStatus, + removeMessage, removePendingHandshake: async (id: string) => { await removePendingHandshake(id); }, setSelectedContact, setLoading, @@ -238,7 +238,6 @@ export default function App() { setShowHandshakeForm(!ready || !currentlyConnected || contacts.length === 0 || needsIdentityCreation); }, [ready, isConnected, contacts.length, needsIdentityCreation]); - // Helper to render message with status and retry/cancel actions const renderMessage = (msg: Message) => { const isOutgoing = msg.direction === 'outgoing'; const isFailed = msg.status === 'failed'; @@ -365,7 +364,7 @@ export default function App() { World Post
- powered by the World Computer + powered by Verbeth
{/* RIGHT: auth buttons - EOA only */} diff --git a/apps/demo/src/components/InitialForm.tsx b/apps/demo/src/components/InitialForm.tsx index f61800d..74b088a 100644 --- a/apps/demo/src/components/InitialForm.tsx +++ b/apps/demo/src/components/InitialForm.tsx @@ -78,7 +78,7 @@ export function InitialForm({ ) : (

- {isAnyConnected ? "Hi, start your first chat" : "Chat away with anyone"} + {isAnyConnected ? "Hi, start your first chat" : "Send a message ina block"}

diff --git a/apps/demo/src/hooks/useInitIdentity.ts b/apps/demo/src/hooks/useInitIdentity.ts index e4d414c..65f355e 100644 --- a/apps/demo/src/hooks/useInitIdentity.ts +++ b/apps/demo/src/hooks/useInitIdentity.ts @@ -67,7 +67,7 @@ export function useInitIdentity({ const [isModuleEnabled, setIsModuleEnabled] = useState(false); const [signingStep, setSigningStep] = useState<1 | 2 | null>(null); - // NEW: Execution mode state + // Execution mode state const [executionMode, setExecutionMode] = useState(null); const [needsModeSelection, setNeedsModeSelection] = useState(false); const [emitterAddress, setEmitterAddress] = useState(null); @@ -75,7 +75,7 @@ export function useInitIdentity({ const rpId = globalThis.location?.host ?? ''; const identityContext = useMemo(() => ({ chainId, rpId }), [chainId, rpId]); - // NEW: Check if fast mode is available on this chain + // Check if fast mode is available on this chain const fastModeAvailable = useMemo(() => isHelperAvailable(chainId), [chainId]); const resetState = useCallback(() => { @@ -110,7 +110,7 @@ export function useInitIdentity({ if (storedIdentity && storedIdentity.sessionPrivateKey) { setIdentityKeyPair(storedIdentity.keyPair); setIdentityProof(storedIdentity.proof ?? null); - // NEW: Restore mode from storage + // Restore mode from storage setExecutionMode(storedIdentity.executionMode ?? 'fast'); // default to fast for legacy setEmitterAddress(storedIdentity.emitterAddress ?? null); setNeedsIdentityCreation(false); @@ -120,7 +120,7 @@ export function useInitIdentity({ setNeedsModeSelection(true); addLog(`Identity upgrade required`); } else { - // NEW: Need mode selection before identity creation + // Need mode selection before identity creation setNeedsModeSelection(true); } }, [addLog]); @@ -188,7 +188,7 @@ export function useInitIdentity({ sessionSigner: sessionAddr, target: LOGCHAIN_SINGLETON_ADDR, }, - // NEW: Never use API for fast mode + // Never use API for fast mode useApiLookup: false, }); @@ -318,7 +318,7 @@ export function useInitIdentity({ proof: proof, sessionPrivateKey: derivedKeys.sessionPrivateKey, sessionAddress: derivedKeys.sessionAddress, - // NEW: Store mode and emitter + // Store mode and emitter executionMode: selectedMode, emitterAddress: emitter, }; @@ -386,7 +386,7 @@ export function useInitIdentity({ identityContext, signingStep, - // NEW: Mode state + // Mode state executionMode, needsModeSelection, emitterAddress, diff --git a/apps/demo/src/hooks/useMessageQueue.ts b/apps/demo/src/hooks/useMessageQueue.ts index 77bc792..8a72ac8 100644 --- a/apps/demo/src/hooks/useMessageQueue.ts +++ b/apps/demo/src/hooks/useMessageQueue.ts @@ -29,11 +29,11 @@ import { export type QueuedMessageStatus = - | "queued" // In queue, waiting for previous to complete - | "sending" // Currently being sent - | "pending" // Tx submitted, waiting for confirmation - | "confirmed" // On-chain confirmed - | "failed"; // Failed, can retry + | "queued" + | "sending" + | "pending" + | "confirmed" + | "failed"; export interface QueuedMessage { id: string; @@ -154,14 +154,8 @@ export const useMessageQueue = ({ const { session: nextSession, header, ciphertext, signature, topic: ratchetedTopic } = encryptResult; // ===================================================================== - // Update BOTH in-memory cache AND DB immediately after encryption - // I.e., we commit the session state BEFORE sending the tx - // - // Why this is safe: - // 1. If tx succeeds: receiver gets message, session states are in sync - // 2. If tx fails: the ratchet "slot" is burned, but receiver's skip-key - // mechanism will handle the gap when they receive subsequent messages - // 3. This matches how Signal handles message failures + // Update both in-memory cache and DB immediately after encryption + // I.e., we commit the session state before sending the tx // ===================================================================== currentSession = nextSession; sessionCacheRef.current.set(conversationId, nextSession); @@ -169,11 +163,10 @@ export const useMessageQueue = ({ await dbService.saveRatchetSession(nextSession); addLog(`๐Ÿ’พ Session state committed (sendingMsgNumber=${nextSession.sendingMsgNumber}, topicEpoch=${nextSession.topicEpoch})`); - // Package binary payload const payload = packageRatchetPayload(signature, header, ciphertext); const payloadHex = hexlify(payload); - // Create pending record for confirmation matching (simplified - no session state) + // Create pending record for confirmation matching const pending: PendingOutbound = { id: message.id, conversationId, @@ -190,11 +183,10 @@ export const useMessageQueue = ({ // Send transaction const timestamp = Math.floor(Date.now() / 1000); - const nonce = nextSession.sendingMsgNumber - 1; // The message number we just used + const nonce = nextSession.sendingMsgNumber - 1; await dbService.updatePendingOutboundStatus(message.id, "submitted"); - // Use ratcheted topic from EncryptResult for on-chain message const tx = await verbethClient.executorInstance.sendMessage( payload, ratchetedTopic, @@ -230,10 +222,8 @@ export const useMessageQueue = ({ message.error = errorMessage; // ===================================================================== - // On failure, we do NOT roll back session state - // The ratchet slot is "burned" - the encryption already advanced the - // chain. If we rolled back, we'd reuse the same key which is a security - // violation. Instead, we let the slot be skipped - the receiver will + // On failure, we do not roll back session state + // Instead, we let the slot be skipped, and the receiver will // handle this via their skip-key mechanism. // // This is intentional and matches Signal's behavior. @@ -341,7 +331,7 @@ export const useMessageQueue = ({ /** * Retry a failed message. * - * IMPORTANT: The original ratchet slot was burned. Retry creates a NEW + * The original ratchet slot was burned. Retry creates a new * encryption with the current (advanced) session state. This means the * message number will be different from the original attempt. */ diff --git a/apps/demo/src/services/EventProcessorService.ts b/apps/demo/src/services/EventProcessorService.ts index 5313ced..41c2ba2 100644 --- a/apps/demo/src/services/EventProcessorService.ts +++ b/apps/demo/src/services/EventProcessorService.ts @@ -29,7 +29,6 @@ import { } from "@verbeth/sdk"; import { dbService } from "./DbService.js"; -import { RatchetDbService } from "./RatchetDbService.js"; import { Contact, Message, @@ -72,11 +71,8 @@ export interface HandshakeResponseResult { } export interface MessageResult { - /** New message to add */ newMessage?: Message; - /** Message update: [originalId, partialUpdates] - will be merged with existing message */ messageUpdate?: [string, Partial]; - /** Contact to update */ contactUpdate?: Contact; } @@ -208,7 +204,6 @@ export async function processHandshakeEvent( verified: isVerified, }; - // Persist to DB await dbService.savePendingHandshake(pendingHandshake); await dbService.saveMessage(systemMessage); @@ -355,7 +350,6 @@ export async function processHandshakeResponseEvent( topicInbound, }); - // Use ratcheted topics from session for contact storage const updatedContact: Contact = { ...contact, status: "established" as ContactStatus, @@ -389,7 +383,6 @@ export async function processHandshakeResponseEvent( verified: true, }; - // Persist to DB await dbService.saveRatchetSession(ratchetSession); await dbService.saveContact(updatedContact); await dbService.saveMessage(systemMessage); @@ -472,7 +465,7 @@ export async function processMessageEvent( ); if (pending && pending.status === "submitted") { - // Finalize: clean up the pending record (session already committed during encryption) + // clean up the pending record (session already committed during encryption) const finalized = await dbService.finalizePendingOutbound(pending.id); if (!finalized) { @@ -516,7 +509,6 @@ export async function processMessageEvent( }; } - // No matching pending record - this shouldn't happen in normal flow onLog( `โš ๏ธ Outgoing message on-chain but no pending record found (tx: ${log.transactionHash.slice( 0, @@ -530,7 +522,7 @@ export async function processMessageEvent( // INCOMING MESSAGE - Use multi-topic lookup for ratchet session // ========================================================================= - // Multi-topic lookup: handles both current and previous (grace period) topics + // multi-topic lookup: handles both current and previous (grace period) topics const session = await dbService.getRatchetSessionByAnyInboundTopic(topic); if (!session) { @@ -547,9 +539,6 @@ export async function processMessageEvent( let cachedSession = sessionCache.get(session.conversationId); let workingSession = cachedSession || session; - // ========================================================================= - // Promuovi next โ†’ current se riceviamo su nextTopicInbound - // ========================================================================= const topicLower = (topic as string).toLowerCase(); if ( workingSession.nextTopicInbound && @@ -563,13 +552,13 @@ export async function processMessageEvent( workingSession = { ...workingSession, - // Salva current come previous (grace period) + previousTopicInbound: workingSession.currentTopicInbound, previousTopicExpiry: Date.now() + 5 * 60 * 1000, // 5 min grace - // Promuovi next โ†’ current + currentTopicInbound: workingSession.nextTopicInbound, currentTopicOutbound: workingSession.nextTopicOutbound!, - // Cancella next (verrร  ricalcolato da dhRatchetStep) + nextTopicInbound: undefined, nextTopicOutbound: undefined, topicEpoch: workingSession.topicEpoch + 1, diff --git a/apps/demo/src/services/RatchetDbService.ts b/apps/demo/src/services/RatchetDbService.ts index b3402a8..f607b5d 100644 --- a/apps/demo/src/services/RatchetDbService.ts +++ b/apps/demo/src/services/RatchetDbService.ts @@ -30,13 +30,13 @@ export class RatchetDbService { } /** - * Find session by any active inbound topic (current or previous). - * Handles topic ratcheting grace period. + * Find session by any active inbound topic (current, next, or previous). + * Handles topic ratcheting grace period and pre-computed next topics. */ async getRatchetSessionByAnyInboundTopic(topic: string): Promise { const topicLower = topic.toLowerCase(); - // Try current topic first + // try current topic first let stored = await this.db.ratchetSessions .where("currentTopicInbound") .equals(topicLower) @@ -51,6 +51,22 @@ export class RatchetDbService { return pruned; } + // try next topic (pre-computed for incoming DH ratchet) + stored = await this.db.ratchetSessions + .where("nextTopicInbound") + .equals(topicLower) + .first(); + + if (stored) { + console.log(`๐Ÿ”„ Found session via nextTopicInbound for topic ${topicLower.slice(0, 10)}...`); + const session = deserializeRatchetSession(stored); + const pruned = pruneExpiredSkippedKeys(session); + if (pruned.skippedKeys.length !== session.skippedKeys.length) { + await this.saveRatchetSession(pruned); + } + return pruned; + } + // Try previous topic (check expiry) stored = await this.db.ratchetSessions .where("previousTopicInbound") @@ -71,34 +87,34 @@ export class RatchetDbService { /** * Get all active inbound topics for a user (for event filtering). - * Returns both current and non-expired previous topics. + * Returns current, next, and non-expired previous topics. */ async getAllActiveInboundTopics(myAddress: string): Promise { - const sessions = await this.db.ratchetSessions - .where("myAddress") - .equals(myAddress.toLowerCase()) - .toArray(); + const sessions = await this.db.ratchetSessions + .where("myAddress") + .equals(myAddress.toLowerCase()) + .toArray(); + + const topics: string[] = []; + const now = Date.now(); - const topics: string[] = []; - const now = Date.now(); - - for (const s of sessions) { - // Current topic - if (s.currentTopicInbound) { - topics.push(s.currentTopicInbound); - } - // Next topic (pre-computed) - if (s.nextTopicInbound) { - topics.push(s.nextTopicInbound); - } - // Previous topic (grace period) - if (s.previousTopicInbound && s.previousTopicExpiry && now < s.previousTopicExpiry) { - topics.push(s.previousTopicInbound); + for (const s of sessions) { + // Current topic + if (s.currentTopicInbound) { + topics.push(s.currentTopicInbound); + } + // Next topic (pre-computed for incoming DH ratchet) + if (s.nextTopicInbound) { + topics.push(s.nextTopicInbound); + } + // Previous topic (grace period) + if (s.previousTopicInbound && s.previousTopicExpiry && now < s.previousTopicExpiry) { + topics.push(s.previousTopicInbound); + } } + + return [...new Set(topics)]; } - - return [...new Set(topics)]; -} async deleteRatchetSession(conversationId: string): Promise { await this.db.ratchetSessions.delete(conversationId); diff --git a/apps/demo/src/services/safeAccount.ts b/apps/demo/src/services/safeAccount.ts index 910daad..8bd935f 100644 --- a/apps/demo/src/services/safeAccount.ts +++ b/apps/demo/src/services/safeAccount.ts @@ -98,7 +98,7 @@ export async function getOrCreateSafeForOwner(params: { sessionConfig: SessionConfig contractNetworks?: any /** - * NEW: Only set to true for "custom" mode (import existing Safe) + * Only set to true for "custom" mode (import existing Safe) * Default: false (deterministic VerbEth Safe only) */ useApiLookup?: boolean diff --git a/apps/demo/src/services/schema.ts b/apps/demo/src/services/schema.ts index bb1dc34..e41f27f 100644 --- a/apps/demo/src/services/schema.ts +++ b/apps/demo/src/services/schema.ts @@ -19,7 +19,7 @@ export class VerbEthDatabase extends Dexie { settings!: Table; dedup!: Table<{ key: string; messageId: string; txHash: string; blockNumber: number }, string>; - // Ratchet tables + // ratchet tables ratchetSessions!: Table; pendingOutbound!: Table; @@ -35,28 +35,7 @@ export class VerbEthDatabase extends Dexie { dedup: "key, messageId, txHash, blockNumber", pendingHandshakes: "id, ownerAddress, sender, timestamp, verified, emitterAddress", settings: "name", - - // Ratchet session storage - ratchetSessions: "conversationId, topicInbound, topicOutbound, status, myAddress, contactAddress", - - // Pending outbound for two-phase commit - pendingOutbound: "id, conversationId, txHash, status, createdAt", - }); - - this.version(1).stores({ - identity: "address", - contacts: - "[address+ownerAddress], ownerAddress, lastTimestamp, status, topicOutbound, topicInbound, emitterAddress, conversationId", - messages: - "id, ownerAddress, sender, recipient, topic, nonce, timestamp, blockTimestamp, read, status, [ownerAddress+sender+status], [ownerAddress+sender+topic+nonce+status]", - dedup: "key, messageId, txHash, blockNumber", - pendingHandshakes: "id, ownerAddress, sender, timestamp, verified, emitterAddress", - settings: "name", - - // Ratchet session storage - added currentTopicInbound and previousTopicInbound indexes - ratchetSessions: "conversationId, topicInbound, topicOutbound, currentTopicInbound, previousTopicInbound, myAddress, contactAddress", - - // Pending outbound for two-phase commit + ratchetSessions: "conversationId, topicInbound, topicOutbound, currentTopicInbound, nextTopicInbound, previousTopicInbound, myAddress, contactAddress", pendingOutbound: "id, conversationId, txHash, status, createdAt", }); } diff --git a/apps/demo/src/types.ts b/apps/demo/src/types.ts index 31539ec..294b9f9 100644 --- a/apps/demo/src/types.ts +++ b/apps/demo/src/types.ts @@ -89,22 +89,11 @@ export interface PendingHandshake { export type ExecutionMode = 'classic' | 'fast' | 'custom'; export interface StoredIdentity { - /** EOA address */ address: string; - /** VerbEth identity key pair (X25519 + Ed25519) */ keyPair: IdentityKeyPair; - /** Timestamp when identity was derived */ derivedAt: number; - /** Binding proof (ties keys to Safe address) */ proof?: IdentityProof; - /** - * Hex-encoded secp256k1 private key for session signer. - * Derived deterministically from the same seed signature as identity keys. - */ - sessionPrivateKey?: string; - /** - * Ethereum address of the session signer. - */ + sessionPrivateKey?: string; // Derived deterministically from the same seed signature as identity keys. sessionAddress?: string; executionMode?: ExecutionMode; emitterAddress?: string; // EOA for classic, Safe for fast/custom @@ -269,6 +258,8 @@ export function serializeRatchetSession(session: SDKRatchetSession): StoredRatch // Topic Ratcheting currentTopicOutbound: session.currentTopicOutbound.toLowerCase(), currentTopicInbound: session.currentTopicInbound.toLowerCase(), + nextTopicOutbound: session.nextTopicOutbound?.toLowerCase(), + nextTopicInbound: session.nextTopicInbound?.toLowerCase(), previousTopicInbound: session.previousTopicInbound?.toLowerCase(), previousTopicExpiry: session.previousTopicExpiry, topicEpoch: session.topicEpoch, @@ -311,6 +302,8 @@ export function deserializeRatchetSession(stored: StoredRatchetSession): SDKRatc // Topic Ratcheting currentTopicOutbound: stored.currentTopicOutbound as `0x${string}`, currentTopicInbound: stored.currentTopicInbound as `0x${string}`, + nextTopicOutbound: stored.nextTopicOutbound as `0x${string}` | undefined, + nextTopicInbound: stored.nextTopicInbound as `0x${string}` | undefined, previousTopicInbound: stored.previousTopicInbound as `0x${string}` | undefined, previousTopicExpiry: stored.previousTopicExpiry, topicEpoch: stored.topicEpoch, diff --git a/packages/sdk/src/ratchet/decrypt.ts b/packages/sdk/src/ratchet/decrypt.ts index 0b26660..d74675d 100644 --- a/packages/sdk/src/ratchet/decrypt.ts +++ b/packages/sdk/src/ratchet/decrypt.ts @@ -108,12 +108,14 @@ export function ratchetDecrypt( } /** - * Perform a DH ratchet step when receiving a message with a new DH public key. - * - * This advances both the receiving and sending chains and derives new ratcheted topics + * DH ratchet on receipt of a message that carries a new remote DH public key. + * + * Topic derivation is sender centric: `deriveTopicFromDH(x, 'outbound')` denotes the topic used + * by the party who *sent* the DH pubkey for their sending direction. Therefore, when we ratchet + * on receive, we swap labels for the topics derived from `dhReceive`. */ function dhRatchetStep(session: RatchetSession, theirNewDHPub: Uint8Array): RatchetSession { - // Receiving DH is shared secret from my secret and their new public + // advance receiving chain (based on our current DH secret and their new DH pubkey) const dhReceive = dh(session.dhMySecretKey, theirNewDHPub); const { rootKey: rootKey1, chainKey: receivingChainKey } = kdfRootKey( session.rootKey, @@ -125,13 +127,13 @@ function dhRatchetStep(session: RatchetSession, theirNewDHPub: Uint8Array): Ratc const dhSend = dh(newDHKeyPair.secretKey, theirNewDHPub); const { rootKey: rootKey2, chainKey: sendingChainKey } = kdfRootKey(rootKey1, dhSend); - // derive new topics from dhReceive const saltBytes = getBytes(session.conversationId); - const newTopicOut = deriveTopicFromDH(dhReceive, 'outbound', saltBytes); - const newTopicIn = deriveTopicFromDH(dhReceive, 'inbound', saltBytes); - + + // Current topics (post ratchet) are swapped since we're the receiver of dhReceive + const newTopicOut = deriveTopicFromDH(dhReceive, 'inbound', saltBytes); + const newTopicIn = deriveTopicFromDH(dhReceive, 'outbound', saltBytes); - // Deriva i PROSSIMI topics da dhSend (che l'altra parte riceverร  come dhReceive) + // Next topics (for our next DH pubkey): normal labels because we will be the sender. const nextTopicOut = deriveTopicFromDH(dhSend, 'outbound', saltBytes); const nextTopicIn = deriveTopicFromDH(dhSend, 'inbound', saltBytes); diff --git a/packages/sdk/src/ratchet/session.ts b/packages/sdk/src/ratchet/session.ts index da034c7..284c7bd 100644 --- a/packages/sdk/src/ratchet/session.ts +++ b/packages/sdk/src/ratchet/session.ts @@ -27,7 +27,7 @@ export function computeConversationId(topicA: string, topicB: string): string { * The responder must persist myResponderEphemeralSecret immediately. * This becomes dhMySecretKey and is required for all future ratchet operations. * - * Epoch 0: uses handshake-derived topics (no ratcheting yet). + * Responder starts at epoch 0 (handshake topics). * * @param params - Initialization parameters * @returns Initialized ratchet session @@ -93,11 +93,9 @@ export function initSessionAsResponder(params: InitResponderParams): RatchetSess /** * Called after receiving and validating handshake response. * - * NB: theirResponderEphemeralPubKey comes from inside the decrypted - * HandshakeResponse payload, NOT from the on-chain responderEphemeralR field. - * The on-chain R is only used for tag verification and is different for unlinkability. - * - * Epoch 1: initiator already does first DH step, so topics are ratcheted immediately. + * Initiator precomputes epoch 1 topics from its first post handshake DH step. + * Outbound should use epoch 1 as soon as we introduce a new DH pubkey. + * Inbound stays on epoch 0 until the responder ratchets. * * @param params - Initialization parameters * @returns Initialized ratchet session @@ -129,8 +127,6 @@ export function initSessionAsInitiator(params: InitInitiatorParams): RatchetSess dhSend ); - // โœ… Deriva epoch 1 topics da dhSend - // Questo sarร  uguale a dhReceive quando Bob fa il suo primo ratchet const conversationId = computeConversationId(topicOutbound, topicInbound); const saltBytes = getBytes(conversationId); const epoch1TopicOut = deriveTopicFromDH(dhSend, 'outbound', saltBytes); @@ -158,11 +154,9 @@ export function initSessionAsInitiator(params: InitInitiatorParams): RatchetSess previousChainLength: 0, skippedKeys: [], - // โœ… FIX: Inizia a epoch 0, ma pre-calcola epoch 1 topics - // E ascolta su ENTRAMBI i topic inbound currentTopicOutbound: topicOutbound, currentTopicInbound: topicInbound, - // Aggiungi questi nuovi campi per il "next" topic + nextTopicOutbound: epoch1TopicOut, nextTopicInbound: epoch1TopicIn, topicEpoch: 0, diff --git a/packages/sdk/test/ratchet.test.ts b/packages/sdk/test/ratchet.test.ts index 6064ed1..082a041 100644 --- a/packages/sdk/test/ratchet.test.ts +++ b/packages/sdk/test/ratchet.test.ts @@ -116,7 +116,7 @@ describe('initSessionAsInitiator - topic ratcheting', () => { initiatorEphemeral = nacl.box.keyPair(); }); - it('initializes at epoch 1 with ratcheted topics', () => { + it('initializes at epoch 0 with handshake topics as current, pre-computes next topics', () => { const session = initSessionAsInitiator({ myAddress: '0xInitiator', contactAddress: '0xResponder', @@ -126,29 +126,16 @@ describe('initSessionAsInitiator - topic ratcheting', () => { topicInbound, }); - expect(session.topicEpoch).toBe(1); - // Current topics should be ratcheted (different from handshake) - expect(session.currentTopicOutbound).not.toBe(topicOutbound); - expect(session.currentTopicInbound).not.toBe(topicInbound); - expect(session.currentTopicOutbound).toMatch(/^0x[a-f0-9]{64}$/); - expect(session.currentTopicInbound).toMatch(/^0x[a-f0-9]{64}$/); - }); - - it('sets previous topic with transition window', () => { - const now = Date.now(); - const session = initSessionAsInitiator({ - myAddress: '0xInitiator', - contactAddress: '0xResponder', - myHandshakeEphemeralSecret: initiatorEphemeral.secretKey, - theirResponderEphemeralPubKey: responderEphemeral.publicKey, - topicOutbound, - topicInbound, - }); - - expect(session.previousTopicInbound).toBe(topicInbound); - expect(session.previousTopicExpiry).toBeDefined(); - expect(session.previousTopicExpiry!).toBeGreaterThanOrEqual(now + TOPIC_TRANSITION_WINDOW_MS - 100); - expect(session.previousTopicExpiry!).toBeLessThanOrEqual(now + TOPIC_TRANSITION_WINDOW_MS + 100); + // Initiator starts at epoch 0 + expect(session.topicEpoch).toBe(0); + // Current topics are handshake-derived + expect(session.currentTopicOutbound).toBe(topicOutbound); + expect(session.currentTopicInbound).toBe(topicInbound); + // Next topics are pre-computed for when responder does DH ratchet + expect(session.nextTopicOutbound).toBeDefined(); + expect(session.nextTopicInbound).toBeDefined(); + expect(session.nextTopicOutbound).not.toBe(topicOutbound); + expect(session.nextTopicInbound).not.toBe(topicInbound); }); it('preserves original handshake topics in topicOutbound/topicInbound', () => { @@ -195,39 +182,11 @@ describe('matchesSessionTopic', () => { expect(result).toBe('current'); }); - it('returns "previous" for previous topic within grace period', () => { - expect(session.previousTopicInbound).toBeDefined(); - const result = matchesSessionTopic(session, session.previousTopicInbound!); - expect(result).toBe('previous'); - }); - - it('returns null for previous topic after expiry', () => { - // Manually expire the previous topic - const expiredSession = { - ...session, - previousTopicExpiry: Date.now() - 1000, // 1 second ago - }; - - const result = matchesSessionTopic(expiredSession, expiredSession.previousTopicInbound!); - expect(result).toBeNull(); - }); - it('returns null for unknown topic', () => { const unknownTopic = '0x' + 'f'.repeat(64) as `0x${string}`; const result = matchesSessionTopic(session, unknownTopic); expect(result).toBeNull(); }); - - it('returns null when no previous topic exists', () => { - const sessionNoPrevious = { - ...session, - previousTopicInbound: undefined, - previousTopicExpiry: undefined, - }; - - const result = matchesSessionTopic(sessionNoPrevious, session.topicInbound); - expect(result).toBeNull(); - }); }); describe('ratchetEncrypt - topic in result', () => { @@ -257,14 +216,6 @@ describe('ratchetEncrypt - topic in result', () => { expect(result.topic).toMatch(/^0x[a-f0-9]{64}$/); }); - it('returns ratcheted topic (not handshake topic) for initiator', () => { - const plaintext = new TextEncoder().encode('Hello'); - const result = ratchetEncrypt(session, plaintext, signingKeyPair.secretKey); - - // Initiator starts at epoch 1, so topic should be ratcheted - expect(result.topic).not.toBe(session.topicOutbound); - }); - it('returns handshake topic for responder at epoch 0', () => { const responderEphemeral = nacl.box.keyPair(); const initiatorEphemeral = nacl.box.keyPair(); @@ -326,8 +277,8 @@ describe('DH ratchet step - topic rotation', () => { }); }); - it('Alice starts at epoch 1, Bob starts at epoch 0', () => { - expect(aliceSession.topicEpoch).toBe(1); + it('both parties start at epoch 0', () => { + expect(aliceSession.topicEpoch).toBe(0); expect(bobSession.topicEpoch).toBe(0); }); @@ -353,17 +304,17 @@ describe('DH ratchet step - topic rotation', () => { const encryptResult = ratchetEncrypt(aliceSession, plaintext, aliceSigningKeyPair.secretKey); aliceSession = encryptResult.session; - // Bob decrypts + // Bob decrypts (triggers his DH ratchet) const decryptResult = ratchetDecrypt(bobSession, encryptResult.header, encryptResult.ciphertext); bobSession = decryptResult!.session; - // Alice's outbound should match Bob's inbound - expect(aliceSession.currentTopicOutbound).toBe(bobSession.currentTopicInbound); - // Bob's outbound should match Alice's inbound - expect(bobSession.currentTopicOutbound).toBe(aliceSession.currentTopicInbound); + // Bob's new outbound should match Alice's pre-computed nextTopicInbound + expect(bobSession.currentTopicOutbound).toBe(aliceSession.nextTopicInbound); + // Bob's new inbound should match Alice's pre-computed nextTopicOutbound + expect(bobSession.currentTopicInbound).toBe(aliceSession.nextTopicOutbound); }); - it('previous topic is preserved during transition window', () => { + it('previous topic is preserved during transition window after DH ratchet', () => { // Alice encrypts a message const plaintext = new TextEncoder().encode('Hello Bob'); const encryptResult = ratchetEncrypt(aliceSession, plaintext, aliceSigningKeyPair.secretKey); @@ -373,7 +324,7 @@ describe('DH ratchet step - topic rotation', () => { const decryptResult = ratchetDecrypt(bobSession, encryptResult.header, encryptResult.ciphertext); bobSession = decryptResult!.session; - // Bob should have previous topic set + // Bob should have previous topic set (after DH ratchet, not at init) expect(bobSession.previousTopicInbound).toBeDefined(); expect(bobSession.previousTopicExpiry).toBeDefined(); expect(bobSession.previousTopicExpiry!).toBeGreaterThan(Date.now()); @@ -382,24 +333,24 @@ describe('DH ratchet step - topic rotation', () => { it('full conversation rotates topics correctly', () => { const epochs: { alice: number; bob: number }[] = []; - // Track initial state + // Track initial state - both at epoch 0 epochs.push({ alice: aliceSession.topicEpoch, bob: bobSession.topicEpoch }); - // Alice -> Bob (Alice already at epoch 1) + // Alice -> Bob (Alice at epoch 0, Bob will ratchet to 1) let encryptResult = ratchetEncrypt(aliceSession, new TextEncoder().encode('msg1'), aliceSigningKeyPair.secretKey); aliceSession = encryptResult.session; let decryptResult = ratchetDecrypt(bobSession, encryptResult.header, encryptResult.ciphertext); bobSession = decryptResult!.session; epochs.push({ alice: aliceSession.topicEpoch, bob: bobSession.topicEpoch }); - // Bob -> Alice (Bob now at epoch 1) + // Bob -> Alice (Bob at epoch 1, Alice will ratchet to 1) encryptResult = ratchetEncrypt(bobSession, new TextEncoder().encode('msg2'), bobSigningKeyPair.secretKey); bobSession = encryptResult.session; decryptResult = ratchetDecrypt(aliceSession, encryptResult.header, encryptResult.ciphertext); aliceSession = decryptResult!.session; epochs.push({ alice: aliceSession.topicEpoch, bob: bobSession.topicEpoch }); - // Alice -> Bob (Alice now at epoch 2) + // Alice -> Bob (Alice at epoch 1, Bob will ratchet to 2) encryptResult = ratchetEncrypt(aliceSession, new TextEncoder().encode('msg3'), aliceSigningKeyPair.secretKey); aliceSession = encryptResult.session; decryptResult = ratchetDecrypt(bobSession, encryptResult.header, encryptResult.ciphertext); @@ -407,10 +358,10 @@ describe('DH ratchet step - topic rotation', () => { epochs.push({ alice: aliceSession.topicEpoch, bob: bobSession.topicEpoch }); // Verify epochs increment with each turn change - expect(epochs[0]).toEqual({ alice: 1, bob: 0 }); - expect(epochs[1]).toEqual({ alice: 1, bob: 1 }); - expect(epochs[2]).toEqual({ alice: 2, bob: 1 }); - expect(epochs[3]).toEqual({ alice: 2, bob: 2 }); + expect(epochs[0]).toEqual({ alice: 0, bob: 0 }); + expect(epochs[1]).toEqual({ alice: 0, bob: 1 }); + expect(epochs[2]).toEqual({ alice: 1, bob: 1 }); + expect(epochs[3]).toEqual({ alice: 1, bob: 2 }); }); }); @@ -440,6 +391,6 @@ describe('topic continuity', () => { // All messages should use the same topic (no DH ratchet without receiving) expect(new Set(topics).size).toBe(1); - expect(session.topicEpoch).toBe(1); // Still epoch 1 + expect(session.topicEpoch).toBe(0); // Still epoch 0 }); }); \ No newline at end of file From 610c0dd24b2bf0a50faa2a5a3d779dd213083184 Mon Sep 17 00:00:00 2001 From: Marco Esposito Date: Fri, 16 Jan 2026 18:43:07 +0100 Subject: [PATCH 14/51] add session storage adapters --- apps/demo/src/App.tsx | 46 +- apps/demo/src/hooks/index.ts | 12 + apps/demo/src/hooks/useChatActions.ts | 55 +- apps/demo/src/hooks/useMessageProcessor.ts | 91 +- apps/demo/src/hooks/useMessageQueue(old).ts | 488 +++++++ apps/demo/src/hooks/useMessageQueue.ts | 327 ++--- .../services/EventProcessorService(old).ts | 718 ++++++++++ .../src/services/EventProcessorService.ts | 420 ++---- apps/demo/src/services/StorageAdapters.ts | 175 +++ apps/demo/src/services/index.ts | 14 + apps/docs/metadata-privacy.md | 63 + apps/docs/topic-ratcheting.md | 155 +++ packages/sdk/src/client/PendingManager.ts | 134 ++ packages/sdk/src/client/SessionManager.ts | 188 +++ packages/sdk/src/client/VerbethClient.ts | 470 +++++-- packages/sdk/src/client/index.ts | 19 +- packages/sdk/src/client/types.ts | 126 +- packages/sdk/src/index.ts | 25 +- packages/sdk/src/ratchet/auth.ts | 3 +- packages/sdk/src/ratchet/codec.ts | 7 + packages/sdk/src/ratchet/decrypt.ts | 32 +- packages/sdk/src/ratchet/encrypt.ts | 8 +- packages/sdk/src/ratchet/kdf.ts | 4 + packages/sdk/src/ratchet/session.ts | 26 +- packages/sdk/src/ratchet/types.ts | 16 +- plan(done).md | 241 ++++ plan.md | 771 ---------- verbeth-client-plan.md | 1236 +++++++++++++++++ 28 files changed, 4374 insertions(+), 1496 deletions(-) create mode 100644 apps/demo/src/hooks/index.ts create mode 100644 apps/demo/src/hooks/useMessageQueue(old).ts create mode 100644 apps/demo/src/services/EventProcessorService(old).ts create mode 100644 apps/demo/src/services/StorageAdapters.ts create mode 100644 apps/demo/src/services/index.ts create mode 100644 apps/docs/metadata-privacy.md create mode 100644 apps/docs/topic-ratcheting.md create mode 100644 packages/sdk/src/client/PendingManager.ts create mode 100644 packages/sdk/src/client/SessionManager.ts create mode 100644 plan(done).md delete mode 100644 plan.md create mode 100644 verbeth-client-plan.md diff --git a/apps/demo/src/App.tsx b/apps/demo/src/App.tsx index d3db997..e29378f 100644 --- a/apps/demo/src/App.tsx +++ b/apps/demo/src/App.tsx @@ -24,6 +24,8 @@ import { useSessionSetup } from './hooks/useSessionSetup.js'; import { useInitIdentity } from './hooks/useInitIdentity.js'; import { usePendingSessionReset } from './hooks/usePendingSessionReset.js'; import { PinnedResetRequest } from './components/PinnedResetRequest.js'; +// NEW: Import storage adapter configuration +import { configureClientStorage } from './services/StorageAdapters.js'; export default function App() { const { ethers: readProvider, viem: viemClient } = useRpcClients(); @@ -124,6 +126,30 @@ export default function App() { executionMode, }); + // =========================================================================== + // UPDATED: Create and configure VerbethClient with storage adapters + // =========================================================================== + useEffect(() => { + const currentAddress = address; + + if (executor && identityKeyPair && identityProof && identitySigner && currentAddress) { + const client = new VerbethClient({ + executor, + identityKeyPair, + identityProof, + signer: identitySigner, + address: currentAddress, + }); + + configureClientStorage(client); + + setVerbethClient(client); + addLog(`VerbethClient initialized for ${currentAddress.slice(0, 8)}...`); + } else { + setVerbethClient(null); + } + }, [executor, identityKeyPair, identityProof, identitySigner, address, addLog]); + const { messages, pendingHandshakes, @@ -141,9 +167,9 @@ export default function App() { address: address ?? undefined, emitterAddress: emitterAddress ?? undefined, identityKeyPair, + verbethClient, // NEW: Pass the configured client onLog: addLog }); - const { hasPendingReset, pendingHandshake: pendingResetHandshake, limboAfterTimestamp } = usePendingSessionReset(selectedContact, pendingHandshakes); @@ -183,24 +209,6 @@ export default function App() { markMessagesLost, }); - useEffect(() => { - const currentAddress = address; - - if (executor && identityKeyPair && identityProof && identitySigner && currentAddress) { - const client = new VerbethClient({ - executor, - identityKeyPair, - identityProof, - signer: identitySigner, - address: currentAddress, - }); - setVerbethClient(client); - addLog(`VerbethClient initialized for ${currentAddress.slice(0, 8)}...`); - } else { - setVerbethClient(null); - } - }, [executor, identityKeyPair, identityProof, identitySigner, address, addLog]); - // sync handshakeToasts useEffect(() => { const currentlyConnected = isConnected; diff --git a/apps/demo/src/hooks/index.ts b/apps/demo/src/hooks/index.ts new file mode 100644 index 0000000..d131140 --- /dev/null +++ b/apps/demo/src/hooks/index.ts @@ -0,0 +1,12 @@ +// src/hooks/index.ts + +/** + * Hooks for VerbEth messaging app. + */ + +export { useMessageProcessor } from './useMessageProcessor.js'; +export { useMessageQueue } from './useMessageQueue.js'; +export { useChatActions } from './useChatActions.js'; +export { usePendingSessionReset } from './usePendingSessionReset.js'; + +export type { QueuedMessage, QueuedMessageStatus } from './useMessageQueue.js'; \ No newline at end of file diff --git a/apps/demo/src/hooks/useChatActions.ts b/apps/demo/src/hooks/useChatActions.ts index aa844ff..f4f7fe3 100644 --- a/apps/demo/src/hooks/useChatActions.ts +++ b/apps/demo/src/hooks/useChatActions.ts @@ -1,5 +1,15 @@ // src/hooks/useChatActions.ts +/** + * Chat Actions Hook. + * + * Provides high-level chat actions: + * - sendHandshake / acceptHandshake + * - sendMessageToContact + * - Retry/cancel failed messages + * - Queue status management + */ + import { useCallback } from "react"; import { hexlify } from "ethers"; import { @@ -60,6 +70,10 @@ export const useChatActions = ({ updateContact, }); + // =========================================================================== + // Handshake Operations + // =========================================================================== + /** * Send a handshake to initiate contact. * Stores ephemeral secret for ratchet session init when response arrives. @@ -124,9 +138,7 @@ export const useChatActions = ({ } catch (error) { console.error("Failed to send handshake:", error); addLog( - `โœ— Failed to send handshake: ${ - error instanceof Error ? error.message : "Unknown error" - }` + `โœ— Failed to send handshake: ${error instanceof Error ? error.message : "Unknown error"}` ); } finally { setLoading(false); @@ -144,7 +156,10 @@ export const useChatActions = ({ ] ); - + /** + * Accept a handshake from another user. + * Creates ratchet session and establishes contact. + */ const acceptHandshake = useCallback( async (handshake: any, responseMessage: string) => { if (!verbethClient) { @@ -177,9 +192,9 @@ export const useChatActions = ({ topicInbound, }); + // Save session - SDK will pick it up via SessionStore adapter await dbService.saveRatchetSession(ratchetSession); - // Use ratcheted topics from session for contact storage const newContact: Contact = { address: handshake.sender, ownerAddress: verbethClient.userAddress, @@ -194,12 +209,15 @@ export const useChatActions = ({ }; await updateContact(newContact); + + // Mark messages as lost if this is a session reset if (handshake.isExistingContact && handshake.timestamp) { - const lostCount = await markMessagesLost(handshake.sender, handshake.timestamp); - if (lostCount > 0) { - addLog(`โš ๏ธ ${lostCount} messages marked as lost`); - } + const lostCount = await markMessagesLost(handshake.sender, handshake.timestamp); + if (lostCount > 0) { + addLog(`โš ๏ธ ${lostCount} messages marked as lost`); } + } + await removePendingHandshake(handshake.id); setSelectedContact(newContact); @@ -230,9 +248,7 @@ export const useChatActions = ({ } catch (error) { console.error("Failed to accept handshake:", error); addLog( - `โœ— Failed to accept handshake: ${ - error instanceof Error ? error.message : "Unknown error" - }` + `โœ— Failed to accept handshake: ${error instanceof Error ? error.message : "Unknown error"}` ); } }, @@ -243,9 +259,18 @@ export const useChatActions = ({ removePendingHandshake, addMessage, setSelectedContact, + markMessagesLost, ] ); + // =========================================================================== + // Message Operations + // =========================================================================== + + /** + * Send a message to a contact. + * Uses the message queue for sequential processing. + */ const sendMessageToContact = useCallback( async (contact: Contact, messageText: string) => { if (!verbethClient) { @@ -267,8 +292,10 @@ export const useChatActions = ({ [verbethClient, addLog, queueMessage, setMessage] ); - - // here the message number will be different from the original attempt. + /** + * Retry a failed message. + * Note: The message number will be different from the original attempt. + */ const retryFailedMessage = useCallback( async (messageId: string) => { const success = await retryMessage(messageId); diff --git a/apps/demo/src/hooks/useMessageProcessor.ts b/apps/demo/src/hooks/useMessageProcessor.ts index 7b447c0..7ec75ce 100644 --- a/apps/demo/src/hooks/useMessageProcessor.ts +++ b/apps/demo/src/hooks/useMessageProcessor.ts @@ -1,19 +1,23 @@ // src/hooks/useMessageProcessor.ts /** + * Message Processor Hook. + * * Manages messaging state (messages, contacts, pendingHandshakes) and * orchestrates event processing via EventProcessorService. + * + * SIMPLIFIED: Event processing now uses VerbethClient which handles + * session management internally. */ import { useState, useEffect, useCallback } from "react"; -import { type IdentityContext, type IdentityKeyPair, type RatchetSession } from "@verbeth/sdk"; +import type { IdentityContext, IdentityKeyPair, VerbethClient } from "@verbeth/sdk"; import { dbService } from "../services/DbService.js"; import { processHandshakeEvent, processHandshakeResponseEvent, processMessageEvent, - persistSessionCache, } from "../services/EventProcessorService.js"; import { Contact, @@ -29,6 +33,7 @@ interface UseMessageProcessorProps { emitterAddress: string | undefined; identityKeyPair: IdentityKeyPair | null; identityContext: IdentityContext; + verbethClient: VerbethClient | null; onLog: (message: string) => void; } @@ -38,6 +43,7 @@ export const useMessageProcessor = ({ emitterAddress, identityKeyPair, identityContext, + verbethClient, onLog, }: UseMessageProcessorProps): MessageProcessorResult => { @@ -45,6 +51,10 @@ export const useMessageProcessor = ({ const [pendingHandshakes, setPendingHandshakes] = useState([]); const [contacts, setContacts] = useState([]); + // =========================================================================== + // Load Data from Database + // =========================================================================== + const loadFromDatabase = useCallback(async () => { if (!address) return; @@ -68,15 +78,13 @@ export const useMessageProcessor = ({ }, [address, onLog]); // =========================================================================== - // Event Processing Orchestration + // Event Processing - SIMPLIFIED // =========================================================================== + const processEvents = useCallback( async (events: ProcessedEvent[]) => { if (!address) return; - // Session cache keyed by conversationId (not topic) for topic ratcheting support - const batchSessionCache = new Map(); - const messageEvents = events.filter((e) => e.eventType === "message"); if (messageEvents.length > 1) { onLog(`๐Ÿ“จ Processing batch of ${messageEvents.length} messages...`); @@ -97,7 +105,6 @@ export const useMessageProcessor = ({ ); if (result) { - // Update React state setPendingHandshakes((prev) => { const existing = prev.find((h) => h.id === result.pendingHandshake.id); if (existing) return prev; @@ -127,7 +134,6 @@ export const useMessageProcessor = ({ ); if (result) { - // Update React state setContacts((prev) => prev.map((c) => c.address.toLowerCase() === result.updatedContact.address.toLowerCase() @@ -141,19 +147,23 @@ export const useMessageProcessor = ({ } // ----------------------------------------------------------------- - // MESSAGE + // MESSAGE - Uses VerbethClient for decryption // ----------------------------------------------------------------- case "message": { + if (!verbethClient) { + onLog(`โŒ Cannot process message: VerbethClient not configured`); + break; + } + const result = await processMessageEvent( event, address, emitterAddress, - batchSessionCache, + verbethClient, onLog ); if (result) { - // Apply state updates if (result.newMessage) { setMessages((prev) => { const existing = prev.find((m) => m.id === result.newMessage!.id); @@ -184,10 +194,9 @@ export const useMessageProcessor = ({ } } - // Persist all updated sessions to DB after batch completes - await persistSessionCache(batchSessionCache, onLog); + // Note: No need to persist session cache anymore - SDK handles it internally }, - [address, readProvider, identityKeyPair, identityContext, emitterAddress, onLog] + [address, readProvider, identityKeyPair, identityContext, emitterAddress, verbethClient, onLog] ); // =========================================================================== @@ -229,32 +238,32 @@ export const useMessageProcessor = ({ }, []); const markMessagesLost = useCallback( - async (contactAddress: string, afterTimestamp: number): Promise => { - if (!address) return 0; - - const count = await dbService.markMessagesAsLost(address, contactAddress, afterTimestamp); - - if (count > 0) { - const normalizedContact = contactAddress.toLowerCase(); - setMessages((prev) => - prev.map((m) => { - if ( - m.direction === 'outgoing' && - m.recipient?.toLowerCase() === normalizedContact && - m.timestamp > afterTimestamp && - m.type !== 'system' - ) { - return { ...m, isLost: true }; - } - return m; - }) - ); - } + async (contactAddress: string, afterTimestamp: number): Promise => { + if (!address) return 0; + + const count = await dbService.markMessagesAsLost(address, contactAddress, afterTimestamp); + + if (count > 0) { + const normalizedContact = contactAddress.toLowerCase(); + setMessages((prev) => + prev.map((m) => { + if ( + m.direction === 'outgoing' && + m.recipient?.toLowerCase() === normalizedContact && + m.timestamp > afterTimestamp && + m.type !== 'system' + ) { + return { ...m, isLost: true }; + } + return m; + }) + ); + } - return count; - }, - [address] -); + return count; + }, + [address] + ); const removePendingHandshake = useCallback(async (id: string) => { await dbService.deletePendingHandshake(id); @@ -273,6 +282,10 @@ export const useMessageProcessor = ({ [address] ); + // =========================================================================== + // Effects + // =========================================================================== + useEffect(() => { if (address) { setMessages([]); diff --git a/apps/demo/src/hooks/useMessageQueue(old).ts b/apps/demo/src/hooks/useMessageQueue(old).ts new file mode 100644 index 0000000..8a72ac8 --- /dev/null +++ b/apps/demo/src/hooks/useMessageQueue(old).ts @@ -0,0 +1,488 @@ +// src/hooks/useMessageQueue.ts + +/** + * Message Queue Hook for Sequential Processing with Optimistic UI. + * + * 1. Session state is cached per conversation and persists across processQueue calls + * 2. After encryption, session state is immediately saved to DB (not waiting for confirmation) + * 3. Failed messages don't corrupt session state - the ratchet slot is "burned" + * 4. Confirmations now just clean up pending records, not commit session state + * + */ + +import { useCallback, useRef, useEffect } from "react"; +import { hexlify } from "ethers"; +import { + VerbethClient, + ratchetEncrypt, + packageRatchetPayload, + RatchetSession, +} from "@verbeth/sdk"; +import { dbService } from "../services/DbService.js"; +import { + Contact, + Message, + PendingOutbound, + generateTempMessageId, + serializeRatchetSession, +} from "../types.js"; + + +export type QueuedMessageStatus = + | "queued" + | "sending" + | "pending" + | "confirmed" + | "failed"; + +export interface QueuedMessage { + id: string; + conversationId: string; + contact: Contact; + plaintext: string; + status: QueuedMessageStatus; + error?: string; + txHash?: string; + createdAt: number; +} + +interface ConversationQueue { + messages: QueuedMessage[]; + isProcessing: boolean; +} + +interface UseMessageQueueProps { + verbethClient: VerbethClient | null; + addLog: (message: string) => void; + addMessage: (message: Message) => Promise; + updateMessageStatus: (id: string, status: Message["status"], error?: string) => Promise; + removeMessage: (id: string) => Promise; + updateContact: (contact: Contact) => Promise; +} + + +export const useMessageQueue = ({ + verbethClient, + addLog, + addMessage, + updateMessageStatus, + removeMessage, + updateContact, +}: UseMessageQueueProps) => { + + const queuesRef = useRef>(new Map()); + + // persistent session cache across processQueue invocations + // This ensures we never lose track of the latest session state + const sessionCacheRef = useRef>(new Map()); + + const failedMessagesRef = useRef>(new Map()); + // Track mounted state to prevent updates after unmount + const mountedRef = useRef(true); + + useEffect(() => { + mountedRef.current = true; + return () => { + mountedRef.current = false; + }; + }, []); + + // =========================================================================== + // Queue Processor + // =========================================================================== + + const processQueue = useCallback(async (conversationId: string) => { + if (!verbethClient || !mountedRef.current) return; + + const queue = queuesRef.current.get(conversationId); + if (!queue || queue.isProcessing || queue.messages.length === 0) return; + + queue.isProcessing = true; + + // Check session cache first, only fall back to DB if not cached + // This ensures we always use the most recently advanced session state + let currentSession: RatchetSession | null = sessionCacheRef.current.get(conversationId) ?? null; + + if (!currentSession) { + try { + currentSession = await dbService.getRatchetSessionByConversation(conversationId); + if (currentSession) { + sessionCacheRef.current.set(conversationId, currentSession); + addLog(`๐Ÿ“‚ Loaded session from DB for ${conversationId.slice(0, 10)}...`); + } + } catch (error) { + addLog(`โœ— Failed to load ratchet session for ${conversationId.slice(0, 10)}...`); + queue.isProcessing = false; + return; + } + } + + if (!currentSession) { + addLog(`โœ— No ratchet session found for ${conversationId.slice(0, 10)}...`); + queue.isProcessing = false; + return; + } + + while (queue.messages.length > 0 && mountedRef.current) { + const message = queue.messages[0]; + + if (message.status === "confirmed" || message.status === "pending") { + queue.messages.shift(); + continue; + } + + if (message.status === "failed") { + queue.messages.shift(); + continue; + } + + try { + message.status = "sending"; + + // use the cached in-memory session state + const sessionBefore = currentSession; + + const plaintext = new TextEncoder().encode(message.plaintext); + + // ratchetEncrypt now returns topic in the result (ratcheted topic) + const encryptResult = ratchetEncrypt( + sessionBefore, + plaintext, + verbethClient.identityKeyPairInstance.signingSecretKey + ); + + const { session: nextSession, header, ciphertext, signature, topic: ratchetedTopic } = encryptResult; + + // ===================================================================== + // Update both in-memory cache and DB immediately after encryption + // I.e., we commit the session state before sending the tx + // ===================================================================== + currentSession = nextSession; + sessionCacheRef.current.set(conversationId, nextSession); + + await dbService.saveRatchetSession(nextSession); + addLog(`๐Ÿ’พ Session state committed (sendingMsgNumber=${nextSession.sendingMsgNumber}, topicEpoch=${nextSession.topicEpoch})`); + + const payload = packageRatchetPayload(signature, header, ciphertext); + const payloadHex = hexlify(payload); + + // Create pending record for confirmation matching + const pending: PendingOutbound = { + id: message.id, + conversationId, + topic: ratchetedTopic, // Use ratcheted topic from EncryptResult + payloadHex, + plaintext: message.plaintext, + sessionStateBefore: JSON.stringify(serializeRatchetSession(sessionBefore)), + sessionStateAfter: JSON.stringify(serializeRatchetSession(nextSession)), + createdAt: message.createdAt, + txHash: null, + status: "preparing", + }; + await dbService.savePendingOutbound(pending); + + // Send transaction + const timestamp = Math.floor(Date.now() / 1000); + const nonce = nextSession.sendingMsgNumber - 1; + + await dbService.updatePendingOutboundStatus(message.id, "submitted"); + + const tx = await verbethClient.executorInstance.sendMessage( + payload, + ratchetedTopic, + timestamp, + BigInt(nonce) + ); + + // Update with txHash + message.txHash = tx.hash; + message.status = "pending"; + await dbService.updatePendingOutboundStatus(message.id, "submitted", tx.hash); + + addLog(`๐Ÿ“ค Message sent: "${message.plaintext.slice(0, 30)}..." (tx: ${tx.hash.slice(0, 10)}..., n=${nonce})`); + + // Update contact with current topic + const updatedContact: Contact = { + ...message.contact, + topicOutbound: nextSession.currentTopicOutbound, + topicInbound: nextSession.currentTopicInbound, + lastMessage: message.plaintext, + lastTimestamp: Date.now(), + }; + await updateContact(updatedContact); + + // Remove from queue (confirmation will be handled by useMessageProcessor) + queue.messages.shift(); + + } catch (error) { + const errorMessage = error instanceof Error ? error.message : "Unknown error"; + + // Mark as failed + message.status = "failed"; + message.error = errorMessage; + + // ===================================================================== + // On failure, we do not roll back session state + // Instead, we let the slot be skipped, and the receiver will + // handle this via their skip-key mechanism. + // + // This is intentional and matches Signal's behavior. + // ===================================================================== + + + try { + await dbService.deletePendingOutbound(message.id); + } catch { + } + + await updateMessageStatus(message.id, "failed", errorMessage); + + addLog(`โœ— Failed to send (slot burned): "${message.plaintext.slice(0, 20)}..." - ${errorMessage}`); + + // Store failed message for retry/cancel + failedMessagesRef.current.set(message.id, { ...message }); + + // Remove from active queue + queue.messages.shift(); + + // Continue processing remaining messages with the advanced session state + // (currentSession is already updated, which is correct) + } + } + + queue.isProcessing = false; + }, [verbethClient, addLog, updateContact, updateMessageStatus]); + + // =========================================================================== + // Public API + // =========================================================================== + + /** + * Queue a message for sending. + * Shows optimistically in UI immediately, processes sequentially. + */ + const queueMessage = useCallback(async ( + contact: Contact, + messageText: string + ): Promise => { + if (!verbethClient) { + addLog("โœ— Client not initialized"); + return null; + } + + if (!contact.conversationId) { + addLog("โœ— Contact doesn't have a ratchet session"); + return null; + } + + const messageId = generateTempMessageId(); + const conversationId = contact.conversationId; + + // Create queued message + const queuedMessage: QueuedMessage = { + id: messageId, + conversationId, + contact, + plaintext: messageText, + status: "queued", + createdAt: Date.now(), + }; + + // Get or create queue for this conversation + let queue = queuesRef.current.get(conversationId); + if (!queue) { + queue = { messages: [], isProcessing: false }; + queuesRef.current.set(conversationId, queue); + } + + // Add to queue + queue.messages.push(queuedMessage); + + // Show optimistic UI message immediately + const optimisticMessage: Message = { + id: messageId, + topic: contact.topicOutbound || "", + sender: verbethClient.userAddress, + recipient: contact.address, + ciphertext: "", + timestamp: Date.now(), + blockTimestamp: Date.now(), + blockNumber: 0, + direction: "outgoing", + decrypted: messageText, + read: true, + nonce: 0, + dedupKey: `pending-${messageId}`, + type: "text", + ownerAddress: verbethClient.userAddress, + status: "pending", + }; + + await addMessage(optimisticMessage); + + addLog(`๐Ÿ“ Message queued: "${messageText.slice(0, 30)}..."`); + + // Trigger queue processing (non-blocking) + setTimeout(() => processQueue(conversationId), 0); + + return messageId; + }, [verbethClient, addLog, addMessage, processQueue]); + + /** + * Retry a failed message. + * + * The original ratchet slot was burned. Retry creates a new + * encryption with the current (advanced) session state. This means the + * message number will be different from the original attempt. + */ + const retryMessage = useCallback(async (messageId: string): Promise => { + // Check the failed messages map first + const failedMessage = failedMessagesRef.current.get(messageId); + + if (failedMessage) { + const conversationId = failedMessage.conversationId; + + // Remove from failed messages map + failedMessagesRef.current.delete(messageId); + + // Reset status for retry + failedMessage.status = "queued"; + failedMessage.error = undefined; + failedMessage.createdAt = Date.now(); + + // Get or create queue + let queue = queuesRef.current.get(conversationId); + if (!queue) { + queue = { messages: [], isProcessing: false }; + queuesRef.current.set(conversationId, queue); + } + + // Add to end of queue + queue.messages.push(failedMessage); + + // Update UI status back to pending + await updateMessageStatus(messageId, "pending"); + + addLog(`๐Ÿ”„ Retrying message (new slot): "${failedMessage.plaintext.slice(0, 30)}..."`); + + // Trigger processing + setTimeout(() => processQueue(conversationId), 0); + + return true; + } + + // Fallback: check if still in active queue (shouldn't happen normally) + for (const [conversationId, queue] of queuesRef.current.entries()) { + const messageIndex = queue.messages.findIndex( + m => m.id === messageId && m.status === "failed" + ); + + if (messageIndex !== -1) { + const message = queue.messages[messageIndex]; + + message.status = "queued"; + message.error = undefined; + message.createdAt = Date.now(); + + // Move to end of queue + queue.messages.splice(messageIndex, 1); + queue.messages.push(message); + + await updateMessageStatus(messageId, "pending"); + + addLog(`๐Ÿ”„ Retrying message: "${message.plaintext.slice(0, 30)}..."`); + + setTimeout(() => processQueue(conversationId), 0); + + return true; + } + } + + addLog(`โœ— Could not find message ${messageId} to retry`); + return false; + }, [addLog, updateMessageStatus, processQueue]); + + /** + * Cancel/delete a failed or queued message. + */ + const cancelMessage = useCallback(async (messageId: string): Promise => { + // Check failed messages map first + const failedMessage = failedMessagesRef.current.get(messageId); + + if (failedMessage) { + failedMessagesRef.current.delete(messageId); + + // Remove from DB and UI + await removeMessage(messageId); + + addLog(`๐Ÿ—‘๏ธ Deleted message: "${failedMessage.plaintext.slice(0, 30)}..."`); + return true; + } + + // Fallback: check active queues + for (const [, queue] of queuesRef.current.entries()) { + const messageIndex = queue.messages.findIndex( + m => m.id === messageId && (m.status === "queued" || m.status === "failed") + ); + + if (messageIndex !== -1) { + const message = queue.messages[messageIndex]; + queue.messages.splice(messageIndex, 1); + + await removeMessage(messageId); + + addLog(`๐Ÿ—‘๏ธ Deleted message: "${message.plaintext.slice(0, 30)}..."`); + return true; + } + } + + addLog(`โœ— Could not find message ${messageId} to delete`); + return false; + }, [addLog, removeMessage]); + + /** + * Get queue status for a conversation. + */ + const getQueueStatus = useCallback((conversationId: string): { + queueLength: number; + isProcessing: boolean; + pendingMessages: QueuedMessage[]; + } => { + const queue = queuesRef.current.get(conversationId); + if (!queue) { + return { queueLength: 0, isProcessing: false, pendingMessages: [] }; + } + return { + queueLength: queue.messages.length, + isProcessing: queue.isProcessing, + pendingMessages: [...queue.messages], + }; + }, []); + + /** + * Invalidate cached session for a conversation. + * Call this when session is reset or updated externally. + */ + const invalidateSessionCache = useCallback((conversationId: string) => { + sessionCacheRef.current.delete(conversationId); + addLog(`๐Ÿ”„ Session cache invalidated for ${conversationId.slice(0, 10)}...`); + }, [addLog]); + + /** + * Clear all queues (e.g., on logout). + */ + const clearAllQueues = useCallback(() => { + queuesRef.current.clear(); + failedMessagesRef.current.clear(); + sessionCacheRef.current.clear(); + }, []); + + return { + queueMessage, + retryMessage, + cancelMessage, + getQueueStatus, + invalidateSessionCache, + clearAllQueues, + }; +}; \ No newline at end of file diff --git a/apps/demo/src/hooks/useMessageQueue.ts b/apps/demo/src/hooks/useMessageQueue.ts index 8a72ac8..40b9092 100644 --- a/apps/demo/src/hooks/useMessageQueue.ts +++ b/apps/demo/src/hooks/useMessageQueue.ts @@ -3,37 +3,28 @@ /** * Message Queue Hook for Sequential Processing with Optimistic UI. * - * 1. Session state is cached per conversation and persists across processQueue calls - * 2. After encryption, session state is immediately saved to DB (not waiting for confirmation) - * 3. Failed messages don't corrupt session state - the ratchet slot is "burned" - * 4. Confirmations now just clean up pending records, not commit session state + * Uses VerbethClient's two-phase commit pattern: + * 1. prepareMessage() - get ID and encrypted payload + * 2. Submit tx manually + * 3. confirmTx() on chain confirmation * + * The key insight: we use prepareMessage()'s ID for BOTH the optimistic + * message AND the pending record, so confirmTx() can find the right message. */ import { useCallback, useRef, useEffect } from "react"; import { hexlify } from "ethers"; -import { - VerbethClient, - ratchetEncrypt, - packageRatchetPayload, - RatchetSession, -} from "@verbeth/sdk"; +import type { VerbethClient } from "@verbeth/sdk"; +import { Contact, Message } from "../types.js"; import { dbService } from "../services/DbService.js"; -import { - Contact, - Message, - PendingOutbound, - generateTempMessageId, - serializeRatchetSession, -} from "../types.js"; export type QueuedMessageStatus = - | "queued" - | "sending" - | "pending" - | "confirmed" - | "failed"; + | "queued" // In queue, waiting to be sent + | "sending" // Currently being encrypted/submitted + | "pending" // Submitted, awaiting confirmation + | "confirmed" // Confirmed on-chain + | "failed"; // Failed to send export interface QueuedMessage { id: string; @@ -60,6 +51,9 @@ interface UseMessageQueueProps { updateContact: (contact: Contact) => Promise; } +// ============================================================================= +// Hook Implementation +// ============================================================================= export const useMessageQueue = ({ verbethClient, @@ -71,13 +65,7 @@ export const useMessageQueue = ({ }: UseMessageQueueProps) => { const queuesRef = useRef>(new Map()); - - // persistent session cache across processQueue invocations - // This ensures we never lose track of the latest session state - const sessionCacheRef = useRef>(new Map()); - const failedMessagesRef = useRef>(new Map()); - // Track mounted state to prevent updates after unmount const mountedRef = useRef(true); useEffect(() => { @@ -88,7 +76,7 @@ export const useMessageQueue = ({ }, []); // =========================================================================== - // Queue Processor + // Queue Processor - Uses prepareMessage() for ID-first approach // =========================================================================== const processQueue = useCallback(async (conversationId: string) => { @@ -99,159 +87,137 @@ export const useMessageQueue = ({ queue.isProcessing = true; - // Check session cache first, only fall back to DB if not cached - // This ensures we always use the most recently advanced session state - let currentSession: RatchetSession | null = sessionCacheRef.current.get(conversationId) ?? null; - - if (!currentSession) { - try { - currentSession = await dbService.getRatchetSessionByConversation(conversationId); - if (currentSession) { - sessionCacheRef.current.set(conversationId, currentSession); - addLog(`๐Ÿ“‚ Loaded session from DB for ${conversationId.slice(0, 10)}...`); - } - } catch (error) { - addLog(`โœ— Failed to load ratchet session for ${conversationId.slice(0, 10)}...`); - queue.isProcessing = false; - return; - } - } - - if (!currentSession) { - addLog(`โœ— No ratchet session found for ${conversationId.slice(0, 10)}...`); - queue.isProcessing = false; - return; - } - while (queue.messages.length > 0 && mountedRef.current) { - const message = queue.messages[0]; + const queuedMsg = queue.messages[0]; - if (message.status === "confirmed" || message.status === "pending") { + // Skip already processed messages + if (queuedMsg.status === "confirmed" || queuedMsg.status === "pending") { queue.messages.shift(); continue; } - if (message.status === "failed") { + if (queuedMsg.status === "failed") { queue.messages.shift(); continue; } try { - message.status = "sending"; - - // use the cached in-memory session state - const sessionBefore = currentSession; - - const plaintext = new TextEncoder().encode(message.plaintext); + queuedMsg.status = "sending"; - // ratchetEncrypt now returns topic in the result (ratcheted topic) - const encryptResult = ratchetEncrypt( - sessionBefore, - plaintext, - verbethClient.identityKeyPairInstance.signingSecretKey + // ===================================================================== + // Step 1: Prepare message - this gives us the ID and encrypted payload + // Session is committed immediately for forward secrecy + // ===================================================================== + const prepared = await verbethClient.prepareMessage( + conversationId, + queuedMsg.plaintext ); - - const { session: nextSession, header, ciphertext, signature, topic: ratchetedTopic } = encryptResult; // ===================================================================== - // Update both in-memory cache and DB immediately after encryption - // I.e., we commit the session state before sending the tx + // Step 2: Create optimistic message with the SAME ID as prepared + // This is the key fix - both share prepared.id // ===================================================================== - currentSession = nextSession; - sessionCacheRef.current.set(conversationId, nextSession); - - await dbService.saveRatchetSession(nextSession); - addLog(`๐Ÿ’พ Session state committed (sendingMsgNumber=${nextSession.sendingMsgNumber}, topicEpoch=${nextSession.topicEpoch})`); + const optimisticMessage: Message = { + id: prepared.id, // USE THE PREPARED ID! + topic: prepared.topic, + sender: verbethClient.userAddress, + recipient: queuedMsg.contact.address, + ciphertext: "", + timestamp: prepared.createdAt, + blockTimestamp: prepared.createdAt, + blockNumber: 0, + direction: "outgoing", + decrypted: queuedMsg.plaintext, + read: true, + nonce: prepared.messageNumber, + dedupKey: `pending-${prepared.id}`, + type: "text", + ownerAddress: verbethClient.userAddress, + status: "pending", + }; - const payload = packageRatchetPayload(signature, header, ciphertext); - const payloadHex = hexlify(payload); + await addMessage(optimisticMessage); - // Create pending record for confirmation matching - const pending: PendingOutbound = { - id: message.id, + // ===================================================================== + // Step 3: Create pending record (SDK's PendingStore via StorageAdapter) + // ===================================================================== + await dbService.savePendingOutbound({ + id: prepared.id, conversationId, - topic: ratchetedTopic, // Use ratcheted topic from EncryptResult - payloadHex, - plaintext: message.plaintext, - sessionStateBefore: JSON.stringify(serializeRatchetSession(sessionBefore)), - sessionStateAfter: JSON.stringify(serializeRatchetSession(nextSession)), - createdAt: message.createdAt, + topic: prepared.topic, + payloadHex: hexlify(prepared.payload), + plaintext: queuedMsg.plaintext, + sessionStateBefore: JSON.stringify({ epoch: prepared.sessionBefore.topicEpoch }), + sessionStateAfter: JSON.stringify({ epoch: prepared.sessionAfter.topicEpoch }), + createdAt: prepared.createdAt, txHash: null, - status: "preparing", - }; - await dbService.savePendingOutbound(pending); + status: 'preparing', + }); - // Send transaction + // ===================================================================== + // Step 4: Submit transaction + // ===================================================================== const timestamp = Math.floor(Date.now() / 1000); - const nonce = nextSession.sendingMsgNumber - 1; - - await dbService.updatePendingOutboundStatus(message.id, "submitted"); - const tx = await verbethClient.executorInstance.sendMessage( - payload, - ratchetedTopic, + prepared.payload, + prepared.topic, timestamp, - BigInt(nonce) + BigInt(prepared.messageNumber) ); - // Update with txHash - message.txHash = tx.hash; - message.status = "pending"; - await dbService.updatePendingOutboundStatus(message.id, "submitted", tx.hash); + // ===================================================================== + // Step 5: Update pending with txHash + // ===================================================================== + await dbService.updatePendingOutboundStatus(prepared.id, 'submitted', tx.hash); - addLog(`๐Ÿ“ค Message sent: "${message.plaintext.slice(0, 30)}..." (tx: ${tx.hash.slice(0, 10)}..., n=${nonce})`); + // Update our tracking + queuedMsg.id = prepared.id; + queuedMsg.txHash = tx.hash; + queuedMsg.status = "pending"; - // Update contact with current topic - const updatedContact: Contact = { - ...message.contact, - topicOutbound: nextSession.currentTopicOutbound, - topicInbound: nextSession.currentTopicInbound, - lastMessage: message.plaintext, - lastTimestamp: Date.now(), - }; - await updateContact(updatedContact); + addLog( + `๐Ÿ“ค Message sent: "${queuedMsg.plaintext.slice(0, 30)}..." (tx: ${tx.hash.slice(0, 10)}..., n=${prepared.messageNumber})` + ); + + // Update contact with current topic (may have ratcheted) + const session = await verbethClient.getSession(conversationId); + if (session) { + const updatedContact: Contact = { + ...queuedMsg.contact, + topicOutbound: session.currentTopicOutbound, + topicInbound: session.currentTopicInbound, + lastMessage: queuedMsg.plaintext, + lastTimestamp: Date.now(), + }; + await updateContact(updatedContact); + } - // Remove from queue (confirmation will be handled by useMessageProcessor) + // Remove from queue (confirmation will be handled by event processor) queue.messages.shift(); } catch (error) { const errorMessage = error instanceof Error ? error.message : "Unknown error"; // Mark as failed - message.status = "failed"; - message.error = errorMessage; + queuedMsg.status = "failed"; + queuedMsg.error = errorMessage; - // ===================================================================== - // On failure, we do not roll back session state - // Instead, we let the slot be skipped, and the receiver will - // handle this via their skip-key mechanism. - // - // This is intentional and matches Signal's behavior. - // ===================================================================== - - - try { - await dbService.deletePendingOutbound(message.id); - } catch { - } + // Note: Ratchet slot may already be burned (session was committed in prepareMessage) - await updateMessageStatus(message.id, "failed", errorMessage); + await updateMessageStatus(queuedMsg.id, "failed", errorMessage); - addLog(`โœ— Failed to send (slot burned): "${message.plaintext.slice(0, 20)}..." - ${errorMessage}`); + addLog(`โœ— Failed to send: "${queuedMsg.plaintext.slice(0, 20)}..." - ${errorMessage}`); // Store failed message for retry/cancel - failedMessagesRef.current.set(message.id, { ...message }); + failedMessagesRef.current.set(queuedMsg.id, { ...queuedMsg }); // Remove from active queue queue.messages.shift(); - - // Continue processing remaining messages with the advanced session state - // (currentSession is already updated, which is correct) } } queue.isProcessing = false; - }, [verbethClient, addLog, updateContact, updateMessageStatus]); + }, [verbethClient, addLog, addMessage, updateContact, updateMessageStatus]); // =========================================================================== // Public API @@ -259,7 +225,8 @@ export const useMessageQueue = ({ /** * Queue a message for sending. - * Shows optimistically in UI immediately, processes sequentially. + * Note: The actual optimistic message is created in processQueue after prepareMessage + * so we can use the correct ID. */ const queueMessage = useCallback(async ( contact: Contact, @@ -275,12 +242,14 @@ export const useMessageQueue = ({ return null; } - const messageId = generateTempMessageId(); const conversationId = contact.conversationId; + + // Use a temporary ID for queue tracking only (will be replaced with prepared.id) + const tempId = `queue-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`; - // Create queued message + // Create queued message (optimistic UI created later with correct ID) const queuedMessage: QueuedMessage = { - id: messageId, + id: tempId, conversationId, contact, plaintext: messageText, @@ -298,45 +267,18 @@ export const useMessageQueue = ({ // Add to queue queue.messages.push(queuedMessage); - // Show optimistic UI message immediately - const optimisticMessage: Message = { - id: messageId, - topic: contact.topicOutbound || "", - sender: verbethClient.userAddress, - recipient: contact.address, - ciphertext: "", - timestamp: Date.now(), - blockTimestamp: Date.now(), - blockNumber: 0, - direction: "outgoing", - decrypted: messageText, - read: true, - nonce: 0, - dedupKey: `pending-${messageId}`, - type: "text", - ownerAddress: verbethClient.userAddress, - status: "pending", - }; - - await addMessage(optimisticMessage); - addLog(`๐Ÿ“ Message queued: "${messageText.slice(0, 30)}..."`); // Trigger queue processing (non-blocking) setTimeout(() => processQueue(conversationId), 0); - return messageId; - }, [verbethClient, addLog, addMessage, processQueue]); + return tempId; + }, [verbethClient, addLog, processQueue]); /** * Retry a failed message. - * - * The original ratchet slot was burned. Retry creates a new - * encryption with the current (advanced) session state. This means the - * message number will be different from the original attempt. */ const retryMessage = useCallback(async (messageId: string): Promise => { - // Check the failed messages map first const failedMessage = failedMessagesRef.current.get(messageId); if (failedMessage) { @@ -345,7 +287,11 @@ export const useMessageQueue = ({ // Remove from failed messages map failedMessagesRef.current.delete(messageId); - // Reset status for retry + // Delete the old failed message from DB + await removeMessage(messageId); + + // Reset status for retry (will get new ID in processQueue) + failedMessage.id = `queue-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`; failedMessage.status = "queued"; failedMessage.error = undefined; failedMessage.createdAt = Date.now(); @@ -360,47 +306,17 @@ export const useMessageQueue = ({ // Add to end of queue queue.messages.push(failedMessage); - // Update UI status back to pending - await updateMessageStatus(messageId, "pending"); - - addLog(`๐Ÿ”„ Retrying message (new slot): "${failedMessage.plaintext.slice(0, 30)}..."`); + addLog(`๐Ÿ”„ Retrying message: "${failedMessage.plaintext.slice(0, 30)}..."`); // Trigger processing setTimeout(() => processQueue(conversationId), 0); return true; } - - // Fallback: check if still in active queue (shouldn't happen normally) - for (const [conversationId, queue] of queuesRef.current.entries()) { - const messageIndex = queue.messages.findIndex( - m => m.id === messageId && m.status === "failed" - ); - - if (messageIndex !== -1) { - const message = queue.messages[messageIndex]; - - message.status = "queued"; - message.error = undefined; - message.createdAt = Date.now(); - - // Move to end of queue - queue.messages.splice(messageIndex, 1); - queue.messages.push(message); - - await updateMessageStatus(messageId, "pending"); - - addLog(`๐Ÿ”„ Retrying message: "${message.plaintext.slice(0, 30)}..."`); - - setTimeout(() => processQueue(conversationId), 0); - - return true; - } - } addLog(`โœ— Could not find message ${messageId} to retry`); return false; - }, [addLog, updateMessageStatus, processQueue]); + }, [addLog, removeMessage, processQueue]); /** * Cancel/delete a failed or queued message. @@ -461,12 +377,11 @@ export const useMessageQueue = ({ /** * Invalidate cached session for a conversation. - * Call this when session is reset or updated externally. */ const invalidateSessionCache = useCallback((conversationId: string) => { - sessionCacheRef.current.delete(conversationId); + verbethClient?.invalidateSessionCache(conversationId); addLog(`๐Ÿ”„ Session cache invalidated for ${conversationId.slice(0, 10)}...`); - }, [addLog]); + }, [verbethClient, addLog]); /** * Clear all queues (e.g., on logout). @@ -474,8 +389,8 @@ export const useMessageQueue = ({ const clearAllQueues = useCallback(() => { queuesRef.current.clear(); failedMessagesRef.current.clear(); - sessionCacheRef.current.clear(); - }, []); + verbethClient?.clearSessionCache(); + }, [verbethClient]); return { queueMessage, diff --git a/apps/demo/src/services/EventProcessorService(old).ts b/apps/demo/src/services/EventProcessorService(old).ts new file mode 100644 index 0000000..41c2ba2 --- /dev/null +++ b/apps/demo/src/services/EventProcessorService(old).ts @@ -0,0 +1,718 @@ +// src/services/EventProcessorService.ts + +/** + * Event Processing Service. + * + * Handles decoding, verification, decryption, and persistence of blockchain events. + * Returns only what's needed for React state updates. + */ + +import { AbiCoder, getBytes } from "ethers"; +import { + type IdentityContext, + type IdentityKeyPair, + type RatchetSession, + parseHandshakePayload, + parseBindingMessage, + verifyHandshakeIdentity, + decodeUnifiedPubKeys, + verifyAndExtractHandshakeResponseKeys, + deriveDuplexTopics, + verifyDerivedDuplexTopics, + computeTagFromInitiator, + pickOutboundTopic, + initSessionAsInitiator, + ratchetDecrypt, + parseRatchetPayload, + isRatchetPayload, + verifyMessageSignature, +} from "@verbeth/sdk"; + +import { dbService } from "./DbService.js"; +import { + Contact, + Message, + PendingHandshake, + ProcessedEvent, + MessageDirection, + MessageType, + ContactStatus, + generateTempMessageId, +} from "../types.js"; + +export function hexToUint8Array(hex: string): Uint8Array { + const cleanHex = hex.replace("0x", ""); + return new Uint8Array( + cleanHex.match(/.{1,2}/g)?.map((byte) => parseInt(byte, 16)) || [] + ); +} + +export function generateMessageId( + txHash: string, + log: { logIndex?: number; index?: number } +): string { + const idx = + typeof log.logIndex !== "undefined" + ? log.logIndex + : typeof log.index !== "undefined" + ? log.index + : 0; + return `${txHash}-${idx}`; +} + +export interface HandshakeResult { + pendingHandshake: PendingHandshake; + systemMessage: Message; +} + +export interface HandshakeResponseResult { + updatedContact: Contact; + systemMessage: Message; +} + +export interface MessageResult { + newMessage?: Message; + messageUpdate?: [string, Partial]; + contactUpdate?: Contact; +} + +// ============================================================================= +// Handshake Processing +// ============================================================================= + +export async function processHandshakeEvent( + event: ProcessedEvent, + address: string, + readProvider: any, + identityContext: IdentityContext, + onLog: (msg: string) => void +): Promise { + try { + const log = event.rawLog; + const abiCoder = new AbiCoder(); + const decoded = abiCoder.decode(["bytes", "bytes", "bytes"], log.data); + const [identityPubKeyBytes, ephemeralPubKeyBytes, plaintextPayloadBytes] = + decoded; + + const unifiedPubKeys = hexToUint8Array(identityPubKeyBytes); + const decodedKeys = decodeUnifiedPubKeys(unifiedPubKeys); + + if (!decodedKeys) { + onLog("โœ— Failed to decode unified public keys"); + return null; + } + + const identityPubKey = decodedKeys.identityPubKey; + const signingPubKey = decodedKeys.signingPubKey; + const ephemeralPubKey = hexToUint8Array(ephemeralPubKeyBytes); + const plaintextPayload = new TextDecoder().decode( + hexToUint8Array(plaintextPayloadBytes) + ); + + const cleanSenderAddress = "0x" + log.topics[2].slice(-40); + const recipientHash = log.topics[1]; + + let handshakeContent; + let hasValidIdentityProof = false; + + try { + handshakeContent = parseHandshakePayload(plaintextPayload); + hasValidIdentityProof = true; + } catch (error) { + handshakeContent = { + plaintextPayload: plaintextPayload, + identityProof: null, + }; + hasValidIdentityProof = false; + } + + let isVerified = false; + if (hasValidIdentityProof) { + try { + const handshakeEvent = { + recipientHash, + sender: cleanSenderAddress, + pubKeys: identityPubKeyBytes, + ephemeralPubKey: ephemeralPubKeyBytes, + plaintextPayload: plaintextPayload, + }; + + isVerified = await verifyHandshakeIdentity( + handshakeEvent, + readProvider, + identityContext + ); + } catch (error) { + onLog(`Failed to verify handshake identity: ${error}`); + } + } + + let identityAddress = cleanSenderAddress; + if (hasValidIdentityProof && handshakeContent.identityProof?.message) { + try { + const parsed = parseBindingMessage( + handshakeContent.identityProof.message + ); + if (parsed.address) { + identityAddress = parsed.address; + } + } catch (e) {} + } + + const existingContact = await dbService.getContact( + identityAddress, + address + ); + const isExistingEstablished = existingContact?.status === "established"; + + const pendingHandshake: PendingHandshake = { + id: log.transactionHash, + ownerAddress: address, + sender: identityAddress, + emitterAddress: cleanSenderAddress, + identityPubKey, + signingPubKey, + ephemeralPubKey, + message: handshakeContent.plaintextPayload, + timestamp: Date.now(), + blockNumber: log.blockNumber, + verified: isVerified, + isExistingContact: isExistingEstablished, + }; + + const messagePrefix = pendingHandshake.isExistingContact + ? "Session reset request received" + : "Request received"; + + const systemMessage: Message = { + id: generateTempMessageId(), + topic: "", + sender: identityAddress, + recipient: address, + ciphertext: "", + timestamp: Date.now(), + blockTimestamp: Date.now(), + blockNumber: log.blockNumber, + direction: "incoming" as const, + decrypted: `${messagePrefix}: "${handshakeContent.plaintextPayload}"`, + read: true, + nonce: 0, + dedupKey: `handshake-received-${log.transactionHash}`, + type: "system" as const, + ownerAddress: address, + status: "confirmed" as const, + verified: isVerified, + }; + + await dbService.savePendingHandshake(pendingHandshake); + await dbService.saveMessage(systemMessage); + + const logSuffix = isExistingEstablished ? " (session reset)" : ""; + onLog( + `๐Ÿ“จ Handshake received from ${identityAddress.slice( + 0, + 8 + )}...${logSuffix} ${isVerified ? "โœ…" : "โš ๏ธ"}: "${ + handshakeContent.plaintextPayload + }"` + ); + + return { pendingHandshake, systemMessage }; + } catch (error) { + onLog(`โœ— Failed to process handshake log: ${error}`); + return null; + } +} + +// ============================================================================= +// Handshake Response Processing +// ============================================================================= + +export async function processHandshakeResponseEvent( + event: ProcessedEvent, + address: string, + readProvider: any, + identityKeyPair: IdentityKeyPair, + identityContext: IdentityContext, + onLog: (msg: string) => void +): Promise { + try { + const log = event.rawLog; + const abiCoder = new AbiCoder(); + const [responderEphemeralRBytes, ciphertextBytes] = abiCoder.decode( + ["bytes32", "bytes"], + log.data + ); + + const ciphertextJson = new TextDecoder().decode( + hexToUint8Array(ciphertextBytes) + ); + + const responder = "0x" + log.topics[2].slice(-40); + const inResponseTo = log.topics[1]; + + const currentContacts = await dbService.getAllContacts(address); + + onLog( + `๐Ÿ” Debug: Loaded ${currentContacts.length} contacts from DB for handshake response` + ); + + const contact = currentContacts.find( + (c) => + c.address.toLowerCase() === + event.matchedContactAddress?.toLowerCase() && + c.status === "handshake_sent" + ); + + if (!contact || !contact.handshakeEphemeralSecret) { + onLog( + `โ“ Received handshake response but no matching pending contact found (responder: ${responder.slice( + 0, + 8 + )}...)` + ); + return null; + } + + const responseEvent = { + inResponseTo, + responder, + responderEphemeralR: responderEphemeralRBytes, + ciphertext: ciphertextJson, + }; + + const result = await verifyAndExtractHandshakeResponseKeys( + responseEvent, + getBytes(contact.handshakeEphemeralSecret!), + readProvider, + identityContext + ); + + if (!result.isValid || !result.keys) { + onLog( + `โŒ Failed to verify handshake response from ${contact.address.slice( + 0, + 8 + )}... - invalid signature or tag mismatch` + ); + return null; + } + + const { identityPubKey, signingPubKey, ephemeralPubKey, note } = + result.keys; + + const saltHex = computeTagFromInitiator( + getBytes(contact.handshakeEphemeralSecret!), + hexToUint8Array(responderEphemeralRBytes) + ); + const salt = Uint8Array.from(Buffer.from(saltHex.slice(2), "hex")); + + const duplexTopics = deriveDuplexTopics( + identityKeyPair.secretKey, + identityPubKey, + salt + ); + + const isValidTopics = verifyDerivedDuplexTopics({ + myIdentitySecretKey: identityKeyPair.secretKey, + theirIdentityPubKey: identityPubKey, + topicInfo: { + out: duplexTopics.topicOut, + in: duplexTopics.topicIn, + chk: duplexTopics.checksum, + }, + salt, + }); + + if (!isValidTopics) { + onLog( + `โŒ Invalid duplex topics checksum for ${contact.address.slice( + 0, + 8 + )}...` + ); + return null; + } + + onLog( + `โœ… Handshake response verified from ${contact.address.slice(0, 8)}...` + ); + + const topicOutbound = pickOutboundTopic(true, duplexTopics); + const topicInbound = pickOutboundTopic(false, duplexTopics); + + const ratchetSession = initSessionAsInitiator({ + myAddress: address, + contactAddress: contact.address, + myHandshakeEphemeralSecret: getBytes(contact.handshakeEphemeralSecret!), + theirResponderEphemeralPubKey: ephemeralPubKey, + topicOutbound, + topicInbound, + }); + + const updatedContact: Contact = { + ...contact, + status: "established" as ContactStatus, + identityPubKey, + signingPubKey, + handshakeEphemeralSecret: undefined, + topicOutbound: ratchetSession.currentTopicOutbound, + topicInbound: ratchetSession.currentTopicInbound, + conversationId: ratchetSession.conversationId, + lastMessage: note || "Handshake accepted", + lastTimestamp: Date.now(), + }; + + const systemMessage: Message = { + id: generateTempMessageId(), + topic: updatedContact.topicInbound || "", + sender: contact.address, + recipient: address, + ciphertext: "", + timestamp: Date.now(), + blockTimestamp: Date.now(), + blockNumber: 0, + direction: "incoming" as const, + decrypted: `Request accepted: "${note || "No message"}"`, + read: true, + nonce: 0, + dedupKey: `handshake-response-${inResponseTo}`, + type: "system" as const, + ownerAddress: address, + status: "confirmed" as const, + verified: true, + }; + + await dbService.saveRatchetSession(ratchetSession); + await dbService.saveContact(updatedContact); + await dbService.saveMessage(systemMessage); + + onLog( + `๐Ÿค Handshake completed with ${contact.address.slice(0, 8)}... : "${ + note || "No message" + }"` + ); + + return { updatedContact, systemMessage }; + } catch (error) { + onLog(`โœ— Failed to process handshake response log: ${error}`); + return null; + } +} + +// ============================================================================= +// Message Processing (Outgoing Confirmation + Incoming Decryption) +// ============================================================================= + +/** + * Process a message event. + * Session cache is keyed by conversationId (not topic) to handle topic ratcheting. + */ +export async function processMessageEvent( + event: ProcessedEvent, + address: string, + emitterAddress: string | undefined, + sessionCache: Map, + onLog: (msg: string) => void +): Promise { + try { + const log = event.rawLog; + const abiCoder = new AbiCoder(); + const decoded = abiCoder.decode(["bytes", "uint256", "uint256"], log.data); + const [ciphertextBytes, timestamp, nonce] = decoded; + const topic = log.topics[2]; + const sender = "0x" + log.topics[1].slice(-40); + const dedupKey = `${address.toLowerCase()}:${generateMessageId( + log.transactionHash, + log + )}`; + + const ciphertextHex = ciphertextBytes as string; + const ciphertextRaw = hexToUint8Array(ciphertextHex); + const emitter = emitterAddress || address; + const isOurMessage = + emitter && sender.toLowerCase() === emitter.toLowerCase(); + + if (!isOurMessage) { + const already = await dbService.getByDedupKey(dedupKey); + if (already) return null; + } + + onLog( + `๐Ÿ” Processing message log: sender=${sender.slice( + 0, + 8 + )}..., isOurMessage=${isOurMessage}, topic=${topic.slice( + 0, + 10 + )}..., nonce=${Number(nonce)}` + ); + + // ========================================================================= + // OUTGOING MESSAGE CONFIRMATION (Ratchet two-phase commit) + // ========================================================================= + if (isOurMessage) { + onLog( + `๐Ÿ”„ Confirming our outgoing message: topic=${topic.slice( + 0, + 10 + )}..., nonce=${Number(nonce)}` + ); + + // Match by txHash + const pending = await dbService.getPendingOutboundByTxHash( + log.transactionHash + ); + + if (pending && pending.status === "submitted") { + // clean up the pending record (session already committed during encryption) + const finalized = await dbService.finalizePendingOutbound(pending.id); + + if (!finalized) { + onLog( + `โš ๏ธ Failed to finalize pending outbound ${pending.id.slice( + 0, + 8 + )}...` + ); + return null; + } + + const newId = generateMessageId(log.transactionHash, log); + const updates: Partial = { + id: newId, + status: "confirmed", + blockNumber: log.blockNumber, + blockTimestamp: Date.now(), + ciphertext: ciphertextHex, + nonce: Number(nonce), + dedupKey, + }; + + await dbService.updateMessage(pending.id, updates); + await dbService.upsertDedup({ + key: dedupKey, + messageId: newId, + txHash: log.transactionHash, + blockNumber: log.blockNumber, + }); + + onLog( + `โœ… Message confirmed: "${finalized.plaintext.slice( + 0, + 30 + )}..." (${pending.id.slice(0, 8)} โ†’ ${newId.slice(0, 8)})` + ); + + return { + messageUpdate: [pending.id, updates], + }; + } + + onLog( + `โš ๏ธ Outgoing message on-chain but no pending record found (tx: ${log.transactionHash.slice( + 0, + 10 + )}...)` + ); + return null; + } + + // ========================================================================= + // INCOMING MESSAGE - Use multi-topic lookup for ratchet session + // ========================================================================= + + // multi-topic lookup: handles both current and previous (grace period) topics + const session = await dbService.getRatchetSessionByAnyInboundTopic(topic); + + if (!session) { + onLog( + `โ“ Received message on unknown topic: ${topic.slice( + 0, + 10 + )}... from ${sender.slice(0, 8)}...` + ); + return null; + } + + // Check session cache by conversationId (not topic, since topic can change) + let cachedSession = sessionCache.get(session.conversationId); + let workingSession = cachedSession || session; + + const topicLower = (topic as string).toLowerCase(); + if ( + workingSession.nextTopicInbound && + topicLower === workingSession.nextTopicInbound.toLowerCase() + ) { + onLog( + `๐Ÿ“ˆ Promoting next topics to current (epoch ${ + workingSession.topicEpoch + } โ†’ ${workingSession.topicEpoch + 1})` + ); + + workingSession = { + ...workingSession, + + previousTopicInbound: workingSession.currentTopicInbound, + previousTopicExpiry: Date.now() + 5 * 60 * 1000, // 5 min grace + + currentTopicInbound: workingSession.nextTopicInbound, + currentTopicOutbound: workingSession.nextTopicOutbound!, + + nextTopicInbound: undefined, + nextTopicOutbound: undefined, + topicEpoch: workingSession.topicEpoch + 1, + }; + + // Aggiorna la cache con la sessione promossa + sessionCache.set(workingSession.conversationId, workingSession); + } + // ========================================================================= + + // Find contact for signing key verification + const contact = await dbService.getContact( + workingSession.contactAddress, + address + ); + if (!contact?.signingPubKey) { + onLog( + `โœ— No signing key for contact ${workingSession.contactAddress.slice( + 0, + 8 + )}...` + ); + return null; + } + + // Check if ratchet format + if (!isRatchetPayload(ciphertextRaw)) { + onLog( + `โœ— Message not in ratchet format from ${contact.address.slice(0, 8)}...` + ); + return null; + } + + const parsed = parseRatchetPayload(ciphertextRaw); + if (!parsed) { + onLog( + `โœ— Failed to parse ratchet payload from ${contact.address.slice( + 0, + 8 + )}...` + ); + return null; + } + + // AUTH-FIRST: Verify signature BEFORE any ratchet operations (DoS protection) + const sigValid = verifyMessageSignature( + parsed.signature, + parsed.header, + parsed.ciphertext, + contact.signingPubKey + ); + + if (!sigValid) { + onLog( + `โœ— Invalid signature on message from ${contact.address.slice( + 0, + 8 + )}..., ignoring` + ); + return null; + } + + // Decrypt with ratchet (signature verified) + const decryptResult = ratchetDecrypt( + workingSession, + parsed.header, + parsed.ciphertext + ); + + if (!decryptResult) { + onLog( + `โœ— Ratchet decryption failed from ${contact.address.slice(0, 8)}...` + ); + return null; + } + + // Update session cache by conversationId (topic may have changed due to DH ratchet) + sessionCache.set( + decryptResult.session.conversationId, + decryptResult.session + ); + + const decryptedText = new TextDecoder().decode(decryptResult.plaintext); + + const message: Message = { + id: generateMessageId(log.transactionHash, log), + topic: topic, + sender: contact.address, + recipient: address, + ciphertext: ciphertextHex, + timestamp: Number(timestamp) * 1000, + blockTimestamp: Date.now(), + blockNumber: log.blockNumber, + direction: "incoming" as MessageDirection, + decrypted: decryptedText, + read: false, + nonce: Number(nonce), + dedupKey, + type: "text" as MessageType, + ownerAddress: address, + status: "confirmed", + }; + + // Update contact with current topic (may have ratcheted) + const updatedContact: Contact = { + ...contact, + topicInbound: decryptResult.session.currentTopicInbound, + topicOutbound: decryptResult.session.currentTopicOutbound, + lastMessage: decryptedText, + lastTimestamp: Date.now(), + }; + + // Persist to DB + const saved = await dbService.saveMessage(message); + if (saved) { + await dbService.upsertDedup({ + key: dedupKey, + messageId: message.id, + txHash: log.transactionHash, + blockNumber: log.blockNumber, + }); + await dbService.saveContact(updatedContact); + } + + onLog( + `๐Ÿ“ฉ Message from ${contact.address.slice(0, 8)}...: "${decryptedText}"` + ); + + return saved + ? { newMessage: message, contactUpdate: updatedContact } + : null; + } catch (error) { + onLog(`โœ— Failed to process message log: ${error}`); + return null; + } +} + +export async function persistSessionCache( + sessionCache: Map, + onLog: (msg: string) => void +): Promise { + if (sessionCache.size === 0) return; + + for (const [conversationId, session] of sessionCache) { + try { + await dbService.saveRatchetSession(session); + onLog(`๐Ÿ’พ Persisted session state for ${conversationId.slice(0, 10)}...`); + } catch (error) { + onLog( + `โœ— Failed to persist session for ${conversationId.slice( + 0, + 10 + )}...: ${error}` + ); + } + } +} diff --git a/apps/demo/src/services/EventProcessorService.ts b/apps/demo/src/services/EventProcessorService.ts index 41c2ba2..5dbcac7 100644 --- a/apps/demo/src/services/EventProcessorService.ts +++ b/apps/demo/src/services/EventProcessorService.ts @@ -4,28 +4,21 @@ * Event Processing Service. * * Handles decoding, verification, decryption, and persistence of blockchain events. - * Returns only what's needed for React state updates. + * Uses VerbethClient SDK methods for simplified session management. */ import { AbiCoder, getBytes } from "ethers"; import { type IdentityContext, type IdentityKeyPair, - type RatchetSession, + type VerbethClient, parseHandshakePayload, parseBindingMessage, verifyHandshakeIdentity, decodeUnifiedPubKeys, verifyAndExtractHandshakeResponseKeys, - deriveDuplexTopics, - verifyDerivedDuplexTopics, - computeTagFromInitiator, pickOutboundTopic, initSessionAsInitiator, - ratchetDecrypt, - parseRatchetPayload, - isRatchetPayload, - verifyMessageSignature, } from "@verbeth/sdk"; import { dbService } from "./DbService.js"; @@ -34,18 +27,9 @@ import { Message, PendingHandshake, ProcessedEvent, - MessageDirection, - MessageType, - ContactStatus, generateTempMessageId, } from "../types.js"; -export function hexToUint8Array(hex: string): Uint8Array { - const cleanHex = hex.replace("0x", ""); - return new Uint8Array( - cleanHex.match(/.{1,2}/g)?.map((byte) => parseInt(byte, 16)) || [] - ); -} export function generateMessageId( txHash: string, @@ -60,6 +44,10 @@ export function generateMessageId( return `${txHash}-${idx}`; } +// ============================================================================= +// Result Types +// ============================================================================= + export interface HandshakeResult { pendingHandshake: PendingHandshake; systemMessage: Message; @@ -77,7 +65,7 @@ export interface MessageResult { } // ============================================================================= -// Handshake Processing +// Handshake Processing (unchanged - doesn't use ratchet) // ============================================================================= export async function processHandshakeEvent( @@ -91,10 +79,9 @@ export async function processHandshakeEvent( const log = event.rawLog; const abiCoder = new AbiCoder(); const decoded = abiCoder.decode(["bytes", "bytes", "bytes"], log.data); - const [identityPubKeyBytes, ephemeralPubKeyBytes, plaintextPayloadBytes] = - decoded; + const [identityPubKeyBytes, ephemeralPubKeyBytes, plaintextPayloadBytes] = decoded; - const unifiedPubKeys = hexToUint8Array(identityPubKeyBytes); + const unifiedPubKeys = getBytes(identityPubKeyBytes); const decodedKeys = decodeUnifiedPubKeys(unifiedPubKeys); if (!decodedKeys) { @@ -104,9 +91,9 @@ export async function processHandshakeEvent( const identityPubKey = decodedKeys.identityPubKey; const signingPubKey = decodedKeys.signingPubKey; - const ephemeralPubKey = hexToUint8Array(ephemeralPubKeyBytes); + const ephemeralPubKey = getBytes(ephemeralPubKeyBytes); const plaintextPayload = new TextDecoder().decode( - hexToUint8Array(plaintextPayloadBytes) + getBytes(plaintextPayloadBytes) ); const cleanSenderAddress = "0x" + log.topics[2].slice(-40); @@ -150,19 +137,14 @@ export async function processHandshakeEvent( let identityAddress = cleanSenderAddress; if (hasValidIdentityProof && handshakeContent.identityProof?.message) { try { - const parsed = parseBindingMessage( - handshakeContent.identityProof.message - ); + const parsed = parseBindingMessage(handshakeContent.identityProof.message); if (parsed.address) { identityAddress = parsed.address; } } catch (e) {} } - const existingContact = await dbService.getContact( - identityAddress, - address - ); + const existingContact = await dbService.getContact(identityAddress, address); const isExistingEstablished = existingContact?.status === "established"; const pendingHandshake: PendingHandshake = { @@ -193,14 +175,14 @@ export async function processHandshakeEvent( timestamp: Date.now(), blockTimestamp: Date.now(), blockNumber: log.blockNumber, - direction: "incoming" as const, + direction: "incoming", decrypted: `${messagePrefix}: "${handshakeContent.plaintextPayload}"`, read: true, nonce: 0, dedupKey: `handshake-received-${log.transactionHash}`, - type: "system" as const, + type: "system", ownerAddress: address, - status: "confirmed" as const, + status: "confirmed", verified: isVerified, }; @@ -209,12 +191,9 @@ export async function processHandshakeEvent( const logSuffix = isExistingEstablished ? " (session reset)" : ""; onLog( - `๐Ÿ“จ Handshake received from ${identityAddress.slice( - 0, - 8 - )}...${logSuffix} ${isVerified ? "โœ…" : "โš ๏ธ"}: "${ - handshakeContent.plaintextPayload - }"` + `๐Ÿ“จ Handshake received from ${identityAddress.slice(0, 8)}...${logSuffix} ${ + isVerified ? "โœ…" : "โš ๏ธ" + }: "${handshakeContent.plaintextPayload}"` ); return { pendingHandshake, systemMessage }; @@ -225,7 +204,7 @@ export async function processHandshakeEvent( } // ============================================================================= -// Handshake Response Processing +// Handshake Response Processing (unchanged - creates new session) // ============================================================================= export async function processHandshakeResponseEvent( @@ -244,32 +223,21 @@ export async function processHandshakeResponseEvent( log.data ); - const ciphertextJson = new TextDecoder().decode( - hexToUint8Array(ciphertextBytes) - ); - + const ciphertextJson = new TextDecoder().decode(getBytes(ciphertextBytes)); const responder = "0x" + log.topics[2].slice(-40); const inResponseTo = log.topics[1]; const currentContacts = await dbService.getAllContacts(address); - onLog( - `๐Ÿ” Debug: Loaded ${currentContacts.length} contacts from DB for handshake response` - ); - const contact = currentContacts.find( (c) => - c.address.toLowerCase() === - event.matchedContactAddress?.toLowerCase() && + c.address.toLowerCase() === event.matchedContactAddress?.toLowerCase() && c.status === "handshake_sent" ); if (!contact || !contact.handshakeEphemeralSecret) { onLog( - `โ“ Received handshake response but no matching pending contact found (responder: ${responder.slice( - 0, - 8 - )}...)` + `โ“ Received handshake response but no matching pending contact found (responder: ${responder.slice(0, 8)}...)` ); return null; } @@ -281,138 +249,113 @@ export async function processHandshakeResponseEvent( ciphertext: ciphertextJson, }; + const initiatorEphemeralSecret = getBytes(contact.handshakeEphemeralSecret); + const result = await verifyAndExtractHandshakeResponseKeys( responseEvent, - getBytes(contact.handshakeEphemeralSecret!), + initiatorEphemeralSecret, readProvider, identityContext ); if (!result.isValid || !result.keys) { - onLog( - `โŒ Failed to verify handshake response from ${contact.address.slice( - 0, - 8 - )}... - invalid signature or tag mismatch` - ); + onLog(`โœ— Invalid handshake response from ${responder.slice(0, 8)}...`); return null; } - const { identityPubKey, signingPubKey, ephemeralPubKey, note } = - result.keys; - - const saltHex = computeTagFromInitiator( - getBytes(contact.handshakeEphemeralSecret!), - hexToUint8Array(responderEphemeralRBytes) - ); - const salt = Uint8Array.from(Buffer.from(saltHex.slice(2), "hex")); - - const duplexTopics = deriveDuplexTopics( - identityKeyPair.secretKey, - identityPubKey, - salt - ); - - const isValidTopics = verifyDerivedDuplexTopics({ + // Derive duplex topics + const { verifyDerivedDuplexTopics } = await import("@verbeth/sdk"); + const { topics, ok } = verifyDerivedDuplexTopics({ myIdentitySecretKey: identityKeyPair.secretKey, - theirIdentityPubKey: identityPubKey, - topicInfo: { - out: duplexTopics.topicOut, - in: duplexTopics.topicIn, - chk: duplexTopics.checksum, - }, - salt, + theirIdentityPubKey: result.keys.identityPubKey, + tag: inResponseTo as `0x${string}`, }); - if (!isValidTopics) { - onLog( - `โŒ Invalid duplex topics checksum for ${contact.address.slice( - 0, - 8 - )}...` - ); + if (ok === false) { + onLog(`โœ— Topic checksum mismatch in handshake response`); return null; } - onLog( - `โœ… Handshake response verified from ${contact.address.slice(0, 8)}...` - ); - - const topicOutbound = pickOutboundTopic(true, duplexTopics); - const topicInbound = pickOutboundTopic(false, duplexTopics); + const topicOutbound = pickOutboundTopic(true, topics); + const topicInbound = pickOutboundTopic(false, topics); + // Initialize ratchet session as initiator const ratchetSession = initSessionAsInitiator({ myAddress: address, contactAddress: contact.address, - myHandshakeEphemeralSecret: getBytes(contact.handshakeEphemeralSecret!), - theirResponderEphemeralPubKey: ephemeralPubKey, + myHandshakeEphemeralSecret: initiatorEphemeralSecret, + theirResponderEphemeralPubKey: result.keys.ephemeralPubKey, topicOutbound, topicInbound, }); + // Save session to DB (SDK will pick it up via SessionStore) + await dbService.saveRatchetSession(ratchetSession); + const updatedContact: Contact = { ...contact, - status: "established" as ContactStatus, - identityPubKey, - signingPubKey, - handshakeEphemeralSecret: undefined, + status: "established", + identityPubKey: result.keys.identityPubKey, + signingPubKey: result.keys.signingPubKey, topicOutbound: ratchetSession.currentTopicOutbound, topicInbound: ratchetSession.currentTopicInbound, conversationId: ratchetSession.conversationId, - lastMessage: note || "Handshake accepted", + handshakeEphemeralSecret: undefined, // Clear after use + lastMessage: result.keys.note || "Connection established", lastTimestamp: Date.now(), }; + await dbService.saveContact(updatedContact); + const systemMessage: Message = { id: generateTempMessageId(), - topic: updatedContact.topicInbound || "", + topic: ratchetSession.currentTopicOutbound, sender: contact.address, recipient: address, ciphertext: "", timestamp: Date.now(), blockTimestamp: Date.now(), - blockNumber: 0, - direction: "incoming" as const, - decrypted: `Request accepted: "${note || "No message"}"`, + blockNumber: log.blockNumber, + direction: "incoming", + decrypted: `Connection established: "${result.keys.note || "Hello!"}"`, read: true, nonce: 0, - dedupKey: `handshake-response-${inResponseTo}`, - type: "system" as const, + dedupKey: `handshake-response-${log.transactionHash}`, + type: "system", ownerAddress: address, - status: "confirmed" as const, - verified: true, + status: "confirmed", }; - await dbService.saveRatchetSession(ratchetSession); - await dbService.saveContact(updatedContact); await dbService.saveMessage(systemMessage); onLog( - `๐Ÿค Handshake completed with ${contact.address.slice(0, 8)}... : "${ - note || "No message" - }"` + `โœ… Handshake response verified from ${contact.address.slice(0, 8)}... - ratchet session created` ); return { updatedContact, systemMessage }; } catch (error) { - onLog(`โœ— Failed to process handshake response log: ${error}`); + onLog(`โœ— Failed to process handshake response: ${error}`); return null; } } // ============================================================================= -// Message Processing (Outgoing Confirmation + Incoming Decryption) +// Message Processing - FIXED: Uses txHash lookup like old code // ============================================================================= /** - * Process a message event. - * Session cache is keyed by conversationId (not topic) to handle topic ratcheting. + * Process a message event using VerbethClient's decryptMessage. + * + * For outgoing messages: + * - Look up pending record by txHash (same as old code) + * - Finalize the pending record + * - Use pending.id to update the message (which IS the optimistic message ID) */ export async function processMessageEvent( event: ProcessedEvent, address: string, emitterAddress: string | undefined, - sessionCache: Map, + verbethClient: VerbethClient, onLog: (msg: string) => void ): Promise { try { @@ -421,63 +364,45 @@ export async function processMessageEvent( const decoded = abiCoder.decode(["bytes", "uint256", "uint256"], log.data); const [ciphertextBytes, timestamp, nonce] = decoded; const topic = log.topics[2]; - const sender = "0x" + log.topics[1].slice(-40); - const dedupKey = `${address.toLowerCase()}:${generateMessageId( - log.transactionHash, - log - )}`; + const sender = "0x" + log.topics[1].slice(-40); const ciphertextHex = ciphertextBytes as string; - const ciphertextRaw = hexToUint8Array(ciphertextHex); - const emitter = emitterAddress || address; + const ciphertextRaw = getBytes(ciphertextHex); + const dedupKey = `${address.toLowerCase()}:${generateMessageId(log.transactionHash, log)}`; + const isOurMessage = - emitter && sender.toLowerCase() === emitter.toLowerCase(); + sender.toLowerCase() === address.toLowerCase() || + (emitterAddress && sender.toLowerCase() === emitterAddress.toLowerCase()); + // Check dedup for incoming messages if (!isOurMessage) { const already = await dbService.getByDedupKey(dedupKey); if (already) return null; } onLog( - `๐Ÿ” Processing message log: sender=${sender.slice( - 0, - 8 - )}..., isOurMessage=${isOurMessage}, topic=${topic.slice( - 0, - 10 - )}..., nonce=${Number(nonce)}` + `๐Ÿ” Processing message: sender=${sender.slice(0, 8)}..., isOurMessage=${isOurMessage}, topic=${topic.slice(0, 10)}...` ); // ========================================================================= - // OUTGOING MESSAGE CONFIRMATION (Ratchet two-phase commit) + // OUTGOING MESSAGE CONFIRMATION - Use txHash lookup like old code // ========================================================================= if (isOurMessage) { - onLog( - `๐Ÿ”„ Confirming our outgoing message: topic=${topic.slice( - 0, - 10 - )}..., nonce=${Number(nonce)}` - ); + onLog(`๐Ÿ”„ Confirming outgoing message: tx=${log.transactionHash.slice(0, 10)}...`); - // Match by txHash - const pending = await dbService.getPendingOutboundByTxHash( - log.transactionHash - ); + // Look up pending by txHash (same as old code!) + const pending = await dbService.getPendingOutboundByTxHash(log.transactionHash); if (pending && pending.status === "submitted") { - // clean up the pending record (session already committed during encryption) + // Finalize the pending record (clean up) const finalized = await dbService.finalizePendingOutbound(pending.id); if (!finalized) { - onLog( - `โš ๏ธ Failed to finalize pending outbound ${pending.id.slice( - 0, - 8 - )}...` - ); + onLog(`โš ๏ธ Failed to finalize pending outbound ${pending.id.slice(0, 8)}...`); return null; } + // Update the message using pending.id (which IS the optimistic message ID) const newId = generateMessageId(log.transactionHash, log); const updates: Partial = { id: newId, @@ -497,152 +422,48 @@ export async function processMessageEvent( blockNumber: log.blockNumber, }); - onLog( - `โœ… Message confirmed: "${finalized.plaintext.slice( - 0, - 30 - )}..." (${pending.id.slice(0, 8)} โ†’ ${newId.slice(0, 8)})` - ); + onLog(`โœ… Message confirmed: "${finalized.plaintext.slice(0, 30)}..." (${pending.id.slice(0, 8)}... โ†’ ${newId.slice(0, 8)}...)`); return { messageUpdate: [pending.id, updates], }; } - onLog( - `โš ๏ธ Outgoing message on-chain but no pending record found (tx: ${log.transactionHash.slice( - 0, - 10 - )}...)` - ); + onLog(`โš ๏ธ Outgoing message on-chain but no pending record found`); return null; } // ========================================================================= - // INCOMING MESSAGE - Use multi-topic lookup for ratchet session + // INCOMING MESSAGE - Use SDK's decryptMessage // ========================================================================= - // multi-topic lookup: handles both current and previous (grace period) topics + // Get contact for signing key const session = await dbService.getRatchetSessionByAnyInboundTopic(topic); - if (!session) { - onLog( - `โ“ Received message on unknown topic: ${topic.slice( - 0, - 10 - )}... from ${sender.slice(0, 8)}...` - ); + onLog(`โ“ Received message on unknown topic: ${topic.slice(0, 10)}...`); return null; } - // Check session cache by conversationId (not topic, since topic can change) - let cachedSession = sessionCache.get(session.conversationId); - let workingSession = cachedSession || session; - - const topicLower = (topic as string).toLowerCase(); - if ( - workingSession.nextTopicInbound && - topicLower === workingSession.nextTopicInbound.toLowerCase() - ) { - onLog( - `๐Ÿ“ˆ Promoting next topics to current (epoch ${ - workingSession.topicEpoch - } โ†’ ${workingSession.topicEpoch + 1})` - ); - - workingSession = { - ...workingSession, - - previousTopicInbound: workingSession.currentTopicInbound, - previousTopicExpiry: Date.now() + 5 * 60 * 1000, // 5 min grace - - currentTopicInbound: workingSession.nextTopicInbound, - currentTopicOutbound: workingSession.nextTopicOutbound!, - - nextTopicInbound: undefined, - nextTopicOutbound: undefined, - topicEpoch: workingSession.topicEpoch + 1, - }; - - // Aggiorna la cache con la sessione promossa - sessionCache.set(workingSession.conversationId, workingSession); - } - // ========================================================================= - - // Find contact for signing key verification - const contact = await dbService.getContact( - workingSession.contactAddress, - address - ); + const contact = await dbService.getContact(session.contactAddress, address); if (!contact?.signingPubKey) { - onLog( - `โœ— No signing key for contact ${workingSession.contactAddress.slice( - 0, - 8 - )}...` - ); - return null; - } - - // Check if ratchet format - if (!isRatchetPayload(ciphertextRaw)) { - onLog( - `โœ— Message not in ratchet format from ${contact.address.slice(0, 8)}...` - ); + onLog(`โœ— No signing key for contact ${session.contactAddress.slice(0, 8)}...`); return null; } - const parsed = parseRatchetPayload(ciphertextRaw); - if (!parsed) { - onLog( - `โœ— Failed to parse ratchet payload from ${contact.address.slice( - 0, - 8 - )}...` - ); - return null; - } - - // AUTH-FIRST: Verify signature BEFORE any ratchet operations (DoS protection) - const sigValid = verifyMessageSignature( - parsed.signature, - parsed.header, - parsed.ciphertext, - contact.signingPubKey + // Decrypt using SDK (handles session lookup, signature verification, topic promotion) + const decrypted = await verbethClient.decryptMessage( + topic, + ciphertextRaw, + contact.signingPubKey, + false // not our message ); - if (!sigValid) { - onLog( - `โœ— Invalid signature on message from ${contact.address.slice( - 0, - 8 - )}..., ignoring` - ); - return null; - } - - // Decrypt with ratchet (signature verified) - const decryptResult = ratchetDecrypt( - workingSession, - parsed.header, - parsed.ciphertext - ); - - if (!decryptResult) { - onLog( - `โœ— Ratchet decryption failed from ${contact.address.slice(0, 8)}...` - ); + if (!decrypted) { + onLog(`โœ— Failed to decrypt message from ${contact.address.slice(0, 8)}...`); return null; } - // Update session cache by conversationId (topic may have changed due to DH ratchet) - sessionCache.set( - decryptResult.session.conversationId, - decryptResult.session - ); - - const decryptedText = new TextDecoder().decode(decryptResult.plaintext); - + // Create message record const message: Message = { id: generateMessageId(log.transactionHash, log), topic: topic, @@ -652,26 +473,26 @@ export async function processMessageEvent( timestamp: Number(timestamp) * 1000, blockTimestamp: Date.now(), blockNumber: log.blockNumber, - direction: "incoming" as MessageDirection, - decrypted: decryptedText, + direction: "incoming", + decrypted: decrypted.plaintext, read: false, nonce: Number(nonce), dedupKey, - type: "text" as MessageType, + type: "text", ownerAddress: address, status: "confirmed", }; - // Update contact with current topic (may have ratcheted) + // Update contact with current topics (may have ratcheted) const updatedContact: Contact = { ...contact, - topicInbound: decryptResult.session.currentTopicInbound, - topicOutbound: decryptResult.session.currentTopicOutbound, - lastMessage: decryptedText, + topicInbound: decrypted.session.currentTopicInbound, + topicOutbound: decrypted.session.currentTopicOutbound, + lastMessage: decrypted.plaintext, lastTimestamp: Date.now(), }; - // Persist to DB + // Persist const saved = await dbService.saveMessage(message); if (saved) { await dbService.upsertDedup({ @@ -683,36 +504,11 @@ export async function processMessageEvent( await dbService.saveContact(updatedContact); } - onLog( - `๐Ÿ“ฉ Message from ${contact.address.slice(0, 8)}...: "${decryptedText}"` - ); + onLog(`๐Ÿ“ฉ Message from ${contact.address.slice(0, 8)}...: "${decrypted.plaintext}"`); - return saved - ? { newMessage: message, contactUpdate: updatedContact } - : null; + return saved ? { newMessage: message, contactUpdate: updatedContact } : null; } catch (error) { - onLog(`โœ— Failed to process message log: ${error}`); + onLog(`โœ— Failed to process message: ${error}`); return null; } } - -export async function persistSessionCache( - sessionCache: Map, - onLog: (msg: string) => void -): Promise { - if (sessionCache.size === 0) return; - - for (const [conversationId, session] of sessionCache) { - try { - await dbService.saveRatchetSession(session); - onLog(`๐Ÿ’พ Persisted session state for ${conversationId.slice(0, 10)}...`); - } catch (error) { - onLog( - `โœ— Failed to persist session for ${conversationId.slice( - 0, - 10 - )}...: ${error}` - ); - } - } -} diff --git a/apps/demo/src/services/StorageAdapters.ts b/apps/demo/src/services/StorageAdapters.ts new file mode 100644 index 0000000..e4f6f5f --- /dev/null +++ b/apps/demo/src/services/StorageAdapters.ts @@ -0,0 +1,175 @@ +// src/services/StorageAdapters.ts + +/** + * Storage Adapters for VerbethClient SDK. + * + * These adapters implement the SDK's SessionStore and PendingStore interfaces, + * connecting the VerbethClient to the app's IndexedDB persistence layer. + * + * Usage: + * ```typescript + * import { configureClientStorage } from './StorageAdapters'; + * + * const client = new VerbethClient(config); + * configureClientStorage(client); + * ``` + */ + +import type { + SessionStore, + PendingStore, + PendingMessage, + PendingStatus, + RatchetSession, +} from '@verbeth/sdk'; +import { dbService } from './DbService.js'; +import type { PendingOutbound } from '../types.js'; + +// ============================================================================= +// Session Store Adapter +// ============================================================================= + +/** + * Adapts DbService to the SDK's SessionStore interface. + * Handles session persistence with automatic topic lookup. + */ +class SessionStoreAdapter implements SessionStore { + /** + * Get session by conversation ID (primary key). + */ + async get(conversationId: string): Promise { + return dbService.getRatchetSessionByConversation(conversationId); + } + + /** + * Find session by any active inbound topic. + * Checks current, next, and previous (within grace period) topics. + */ + async getByInboundTopic(topic: string): Promise { + return dbService.getRatchetSessionByAnyInboundTopic(topic); + } + + /** + * Persist session state. + */ + async save(session: RatchetSession): Promise { + return dbService.saveRatchetSession(session); + } +} + +// ============================================================================= +// Pending Store Adapter +// ============================================================================= + +/** + * Adapts DbService to the SDK's PendingStore interface. + * Handles pending outbound message lifecycle. + */ +class PendingStoreAdapter implements PendingStore { + /** + * Save a new pending message. + */ + async save(pending: PendingMessage): Promise { + const dbPending: PendingOutbound = { + id: pending.id, + conversationId: pending.conversationId, + topic: pending.topic, + payloadHex: pending.payloadHex, + plaintext: pending.plaintext, + sessionStateBefore: pending.sessionStateBefore, + sessionStateAfter: pending.sessionStateAfter, + createdAt: pending.createdAt, + txHash: pending.txHash, + status: pending.status, + }; + return dbService.savePendingOutbound(dbPending); + } + + /** + * Get pending message by ID. + */ + async get(id: string): Promise { + const pending = await dbService.getPendingOutbound(id); + return pending ? this.toPendingMessage(pending) : null; + } + + /** + * Get pending message by transaction hash. + */ + async getByTxHash(txHash: string): Promise { + const pending = await dbService.getPendingOutboundByTxHash(txHash); + return pending ? this.toPendingMessage(pending) : null; + } + + /** + * Update pending message status. + */ + async updateStatus(id: string, status: PendingStatus, txHash?: string): Promise { + return dbService.updatePendingOutboundStatus(id, status, txHash); + } + + /** + * Delete pending message. + */ + async delete(id: string): Promise { + return dbService.deletePendingOutbound(id); + } + + /** + * Get all pending messages for a conversation. + */ + async getByConversation(conversationId: string): Promise { + const pending = await dbService.getPendingOutboundByConversation(conversationId); + return pending.map(p => this.toPendingMessage(p)); + } + + /** + * Convert DB format to SDK format. + */ + private toPendingMessage(pending: PendingOutbound): PendingMessage { + return { + id: pending.id, + conversationId: pending.conversationId, + topic: pending.topic, + payloadHex: pending.payloadHex, + plaintext: pending.plaintext, + sessionStateBefore: pending.sessionStateBefore, + sessionStateAfter: pending.sessionStateAfter, + createdAt: pending.createdAt, + txHash: pending.txHash, + status: pending.status as PendingStatus, + }; + } +} + +// ============================================================================= +// Singleton Instances +// ============================================================================= + +const sessionStoreInstance = new SessionStoreAdapter(); +const pendingStoreInstance = new PendingStoreAdapter(); + +// ============================================================================= +// Client Configuration Helper +// ============================================================================= + +/** + * Configure a VerbethClient with storage adapters. + * Uses the singleton dbService internally. + * + * @param client - VerbethClient instance to configure + * + * @example + * ```typescript + * const client = new VerbethClient(config); + * configureClientStorage(client); + * + * // Now client is ready to use sendMessage/decryptMessage + * ``` + */ +export function configureClientStorage( + client: { setSessionStore: (s: SessionStore) => void; setPendingStore: (p: PendingStore) => void } +): void { + client.setSessionStore(sessionStoreInstance); + client.setPendingStore(pendingStoreInstance); +} \ No newline at end of file diff --git a/apps/demo/src/services/index.ts b/apps/demo/src/services/index.ts new file mode 100644 index 0000000..ed6a951 --- /dev/null +++ b/apps/demo/src/services/index.ts @@ -0,0 +1,14 @@ +// src/services/index.ts + +/** + * Services for VerbEth messaging app. + */ + +export { dbService } from './DbService.js'; +export { configureClientStorage } from './StorageAdapters.js'; +export { + processHandshakeEvent, + processHandshakeResponseEvent, + processMessageEvent, + generateMessageId, +} from './EventProcessorService.js'; \ No newline at end of file diff --git a/apps/docs/metadata-privacy.md b/apps/docs/metadata-privacy.md new file mode 100644 index 0000000..b16890f --- /dev/null +++ b/apps/docs/metadata-privacy.md @@ -0,0 +1,63 @@ +# Verbeth Metadata Privacy Model + +## On-Chain Data (Public) + +| Event | Visible Fields | Links Participants? | +|-------|---------------|---------------------| +| **Handshake** | sender, `recipientHash` | โš ๏ธ Confirmable only (requires guessing recipient) | +| **HandshakeResponse** | responder, `inResponseTo` tag | โŒ No (tag is ephemeral-derived) | +| **MessageSent** | sender, `topic`, ciphertext | โŒ No (topic is one-directional) | + +## What Passive Chain Observers Learn + +โœ… **Can determine:** +- Address X uses Verbeth +- Address X sends messages to topic T +- Address X initiated a handshake with *someone* (if recipientHash matched to a guessed address) + +โŒ **Cannot determine:** +- Who receives messages on topic T +- Whether a handshake was accepted (response tag unlinkable) +- That Alice and Bob are conversing (their topics are cryptographically independent) + +## The RPC Problem + +The RPC endpoint sees query parameters, not just on-chain data. + +```typescript +// Alice's RPC sees: +eth_getLogs({ topics: [MessageSent, null, [topicA, topicB, ...]] }) +``` + +| Query Type | RPC Learns | +|------------|------------| +| Handshakes | User's `recipientHash` (trivially reversible) | +| Messages | All active inbound topics for this user | + +**Correlation attack (same RPC):** +``` +Alice queries for topic_X โ†’ RPC logs this +Bob sends to topic_X โ†’ RPC logs this +Conclusion: Bob โ†’ Alice conversation exists +``` + +## Trust Requirements + +| Entity | Trust Level | Justification | +|--------|-------------|---------------| +| Blockchain / Indexers | None required | Cannot link conversations | +| Your RPC provider | **Full trust** | Sees all your topic queries | +| Counterparty's RPC | Independent | Only risks their privacy, not yours | + +## Summary + +Verbeth provides **strong on-chain privacy**: passive observers cannot link conversation participants. The metadata leak is concentrated at the **RPC layer**, which sees topic queries and can correlate them with senders. + +### Mitigation Options + +| Approach | Effectiveness | +|----------|---------------| +| Self-hosted node | Eliminates RPC trust entirely | +| Tor for RPC calls | Hides IP, RPC still sees query content | +| Decoy topic queries | Adds noise, increases bandwidth | +| Rotate RPC endpoints | Dilutes correlation, doesn't eliminate | \ No newline at end of file diff --git a/apps/docs/topic-ratcheting.md b/apps/docs/topic-ratcheting.md new file mode 100644 index 0000000..c46b68f --- /dev/null +++ b/apps/docs/topic-ratcheting.md @@ -0,0 +1,155 @@ +# Topic Ratcheting Mechanism + +This document explains how Verbeth synchronizes topic rotation with the Double Ratchet DH steps, providing forward secrecy at the network layer. + +## Core Principle + +Topics rotate alongside DH ratchet steps. Each new DH shared secret deterministically derives new topics via HKDF, ensuring that compromising a topic reveals nothing about past or future topics. + +``` +DH Ratchet Step โ†’ New DH Shared Secret โ†’ deriveTopicFromDH() โ†’ New Topics +``` + +--- + +## SDK Layer + +### Session State (RatchetSession) + +| Field | Purpose | +|-------|---------| +| `currentTopicOutbound` | Topic for sending messages now | +| `currentTopicInbound` | Topic for receiving messages now | +| `nextTopicOutbound/Inbound` | Pre-computed topics for incoming DH ratchet | +| `previousTopicInbound` | Grace period topic (5 min) | +| `previousTopicExpiry` | Timestamp when previous topic expires | +| `topicEpoch` | Counter for debugging | + +### Topic Derivation (`kdf.ts`) + +```typescript +deriveTopicFromDH(dhSharedSecret, direction, salt) โ†’ bytes32 topic +``` + +Direction labels (`'outbound'`/`'inbound'`) ensure asymmetric topics. The sender's outbound is the receiver's inbound. + +### On Encrypt (`encrypt.ts`) + +Uses `session.currentTopicOutbound`. No topic changes on sendโ€”topics only rotate on DH ratchet (when receiving). + +### On Decrypt (`decrypt.ts` โ†’ `dhRatchetStep`) + +When a message carries a new DH public key: + +1. Compute `dhReceive = DH(mySecret, theirNewPub)` +2. Derive new receiving chain from `dhReceive` +3. Generate new DH keypair for response +4. Compute `dhSend = DH(newSecret, theirNewPub)` +5. **Derive topics from `dhReceive`** (labels swapped since we're receiver): + - `newTopicOut = deriveTopicFromDH(dhReceive, 'inbound', salt)` + - `newTopicIn = deriveTopicFromDH(dhReceive, 'outbound', salt)` +6. **Pre-compute next topics from `dhSend`** (for when peer ratchets): + - `nextTopicOut = deriveTopicFromDH(dhSend, 'outbound', salt)` + - `nextTopicIn = deriveTopicFromDH(dhSend, 'inbound', salt)` +7. Archive current inbound as `previousTopicInbound` with 5-min expiry + +--- + +## App Layer + +### Sending (`useMessageQueue.ts`) + +```typescript +const { topic: ratchetedTopic } = ratchetEncrypt(session, plaintext, signingKey); +await executor.sendMessage(payload, ratchetedTopic, timestamp, nonce); +``` + +The topic comes from `EncryptResult.topic`, which is `session.currentTopicOutbound`. + +### Receiving (`EventProcessorService.ts`) + +1. **Multi-topic lookup**: `getRatchetSessionByAnyInboundTopic(topic)` queries: + - `currentTopicInbound` (primary) + - `nextTopicInbound` (pre-computed for incoming ratchet) + - `previousTopicInbound` (if within grace period) + +2. **Topic promotion**: If message arrives on `nextTopicInbound`: + ```typescript + previousTopicInbound = currentTopicInbound; + previousTopicExpiry = now + 5min; + currentTopicInbound = nextTopicInbound; + currentTopicOutbound = nextTopicOutbound; + nextTopicInbound = undefined; + topicEpoch++; + ``` + +3. **Decryption**: `ratchetDecrypt()` may trigger another DH ratchet step internally, updating topics again. + +### Event Filtering (`useMessageListener.ts`) + +```typescript +const activeTopics = await dbService.getAllActiveInboundTopics(address); +// Returns: current + next + non-expired previous topics for all sessions +``` + +Blockchain log queries filter by all active topics to catch messages during transitions. + +### Database Indexing (`schema.ts`) + +```typescript +ratchetSessions: "conversationId, ..., currentTopicInbound, nextTopicInbound, previousTopicInbound, ..." +``` + +Enables O(1) lookups by any topic variant. + +--- + +## Scenario Handling + +| Scenario | Mechanism | +|----------|-----------| +| **Sequential messages** | Same topic, no ratchet needed | +| **Peer ratchets** | Message on `nextTopicInbound` โ†’ promote topics | +| **Late message on old topic** | `previousTopicInbound` with grace period | +| **Out-of-order within epoch** | Skip keys (topic unchanged) | +| **Session reset** | New handshake โ†’ fresh epoch 0 topics | + +--- + +## Developer Conventions + +1. **Session persistence**: Always save after `ratchetDecrypt()` returnsโ€”topics may have changed. + +2. **Cache by conversationId, not topic**: Topics change; `conversationId` is stable. + +3. **Immediate session commit on encrypt**: Persist before sending tx (two-phase commit protects against slot loss). + +4. **Contact sync**: After processing, update `contact.topicOutbound/Inbound` from session state. + +5. **Grace period**: 5 minutes (`TOPIC_TRANSITION_WINDOW_MS`). Don't rely on longer windows. + +6. **Never filter by single topic**: Always use `getAllActiveInboundTopics()` for event queries. + +--- + +## Typical Flow + +``` +Alice (Initiator) Bob (Responder) +โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ +Epoch 0: handshake topics Epoch 0: handshake topics + +Send msg on topicOutโ‚€ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–บ Receive on topicInโ‚€ + DH ratchet โ†’ Epoch 1 + (next topics pre-computed) + + โ—„โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ Send msg on topicOutโ‚ +Receive on nextTopicIn +Promote โ†’ Epoch 1 +DH ratchet โ†’ pre-compute Epoch 2 + +Send msg on topicOutโ‚ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–บ Receive on topicInโ‚ + ... +``` + +Each direction independently advances its topic epoch when receiving a new DH public key. \ No newline at end of file diff --git a/packages/sdk/src/client/PendingManager.ts b/packages/sdk/src/client/PendingManager.ts new file mode 100644 index 0000000..f973c0b --- /dev/null +++ b/packages/sdk/src/client/PendingManager.ts @@ -0,0 +1,134 @@ +// packages/sdk/src/client/PendingManager.ts + +/** + * Internal Pending Message Coordinator. + * + * Manages the lifecycle of outbound messages: + * - Creating pending records before tx submission + * - Updating status on submission + * - Matching confirmations by txHash + * - Cleaning up after confirmation or failure + */ + +import { PendingStore, PendingMessage, PendingStatus } from './types.js'; + +/** + * Parameters for creating a new pending message. + */ +export interface CreatePendingParams { + id: string; + conversationId: string; + topic: string; + payloadHex: string; + plaintext: string; + sessionStateBefore: string; + sessionStateAfter: string; + createdAt: number; +} + +/** + * Internal pending message manager that wraps a PendingStore. + */ +export class PendingManager { + constructor(private store: PendingStore) {} + + /** + * Create and save a pending message record. + * Called right before submitting a transaction. + */ + async create(params: CreatePendingParams): Promise { + const pending: PendingMessage = { + ...params, + txHash: null, + status: 'preparing', + }; + await this.store.save(pending); + return pending; + } + + /** + * Mark as submitted with transaction hash. + * Called immediately after tx is broadcast. + */ + async markSubmitted(id: string, txHash: string): Promise { + await this.store.updateStatus(id, 'submitted', txHash); + } + + /** + * Mark as failed. + * Called when tx submission fails. + * Note: Ratchet slot is already burned (session was committed). + */ + async markFailed(id: string): Promise { + await this.store.updateStatus(id, 'failed'); + } + + + async get(id: string): Promise { + return this.store.get(id); + } + + + async getByTxHash(txHash: string): Promise { + return this.store.getByTxHash(txHash); + } + + async getByConversation(conversationId: string): Promise { + return this.store.getByConversation(conversationId); + } + + + /** + * Finalize (confirm) and delete. + * Called when we see our MessageSent event on-chain. + * + * @returns The finalized pending message, or null if not found + */ + async finalize(id: string): Promise { + const pending = await this.store.get(id); + if (!pending) { + return null; + } + + await this.store.delete(id); + return pending; + } + + /** + * Delete a pending message without finalizing. + * Used for cleanup on failure or cancellation. + */ + async delete(id: string): Promise { + await this.store.delete(id); + } + + // =========================================================================== + // Batch Operations + // =========================================================================== + + /** + * Clean up stale pending messages. + * Called periodically to remove old failed/stuck records. + * + * @param conversationId - Conversation to clean up + * @param maxAgeMs - Maximum age in milliseconds (default: 24 hours) + * @returns Number of records cleaned up + */ + async cleanupStale( + conversationId: string, + maxAgeMs: number = 24 * 60 * 60 * 1000 + ): Promise { + const pending = await this.store.getByConversation(conversationId); + const cutoff = Date.now() - maxAgeMs; + + let cleaned = 0; + for (const p of pending) { + if (p.createdAt < cutoff) { + await this.store.delete(p.id); + cleaned++; + } + } + + return cleaned; + } +} \ No newline at end of file diff --git a/packages/sdk/src/client/SessionManager.ts b/packages/sdk/src/client/SessionManager.ts new file mode 100644 index 0000000..c15c073 --- /dev/null +++ b/packages/sdk/src/client/SessionManager.ts @@ -0,0 +1,188 @@ +// packages/sdk/src/client/SessionManager.ts + +/** + * Internal Session Coordinator. + * + * Handles: + * - Session caching for performance + * - Topic matching (current, next, previous) + * - Automatic topic promotion when next topic is used + * - Cache invalidation + */ + +import { RatchetSession, TOPIC_TRANSITION_WINDOW_MS } from '../ratchet/types.js'; +import { SessionStore } from './types.js'; + +/** + * Result of topic-based session lookup. + */ +export interface TopicLookupResult { + session: RatchetSession; + topicMatch: 'current' | 'next' | 'previous'; +} + +/** + * Internal session manager that wraps a SessionStore with caching + * and topic promotion logic. + */ +export class SessionManager { + private cache = new Map(); + + constructor(private store: SessionStore) {} + + // =========================================================================== + // Session Retrieval + // =========================================================================== + + /** + * Get session by conversation ID, checking cache first. + */ + async getByConversationId(conversationId: string): Promise { + // Check cache first + const cached = this.cache.get(conversationId); + if (cached) { + return cached; + } + + // Load from store + const session = await this.store.get(conversationId); + if (session) { + this.cache.set(conversationId, session); + } + return session; + } + + /** + * Find session by inbound topic with automatic topic promotion. + * + * Checks topics in order: + * 1. currentTopicInbound - standard case + * 2. nextTopicInbound - DH ratchet advanced, promotes topics + * 3. previousTopicInbound - grace period for late messages + * + * @param topic - The topic to look up + * @returns Session and match type, or null if not found + */ + async getByInboundTopic(topic: string): Promise { + const topicLower = topic.toLowerCase(); + + // Try store's topic lookup (handles all three cases) + const session = await this.store.getByInboundTopic(topic); + if (!session) { + return null; + } + + // Check cache for more recent state (important for batched operations) + const cached = this.cache.get(session.conversationId); + let workingSession = cached || session; + + // Determine which topic matched + if (workingSession.currentTopicInbound.toLowerCase() === topicLower) { + // Cache if not already cached + if (!cached) { + this.cache.set(workingSession.conversationId, workingSession); + } + return { session: workingSession, topicMatch: 'current' }; + } + + if (workingSession.nextTopicInbound?.toLowerCase() === topicLower) { + // Promote next topics to current + workingSession = this.promoteTopics(workingSession); + this.cache.set(workingSession.conversationId, workingSession); + return { session: workingSession, topicMatch: 'next' }; + } + + if ( + workingSession.previousTopicInbound?.toLowerCase() === topicLower && + workingSession.previousTopicExpiry && + Date.now() < workingSession.previousTopicExpiry + ) { + if (!cached) { + this.cache.set(workingSession.conversationId, workingSession); + } + return { session: workingSession, topicMatch: 'previous' }; + } + + // Topic found in store but doesn't match current session state + // This shouldn't happen normally, but handle gracefully + return null; + } + + // =========================================================================== + // Session Persistence + // =========================================================================== + + /** + * Update session in cache and persist to store. + */ + async save(session: RatchetSession): Promise { + this.cache.set(session.conversationId, session); + await this.store.save(session); + } + + /** + * Update cache without persisting (for batch operations). + * Call save() after batch completes. + */ + updateCache(session: RatchetSession): void { + this.cache.set(session.conversationId, session); + } + + /** + * Persist all cached sessions to store. + * Used after batch operations. + */ + async flushCache(): Promise { + const saves = Array.from(this.cache.values()).map(s => this.store.save(s)); + await Promise.all(saves); + } + + // =========================================================================== + // Cache Management + // =========================================================================== + + /** + * Invalidate cache entry (e.g., on session reset). + */ + invalidate(conversationId: string): void { + this.cache.delete(conversationId); + } + + clearCache(): void { + this.cache.clear(); + } + + getCacheSize(): number { + return this.cache.size; + } + + isCached(conversationId: string): boolean { + return this.cache.has(conversationId); + } + + /** + * Promote next topics to current (internal helper). + * Called when a message arrives on nextTopicInbound. + */ + private promoteTopics(session: RatchetSession): RatchetSession { + if (!session.nextTopicInbound || !session.nextTopicOutbound) { + return session; + } + + return { + ...session, + // Move current to previous (for grace period) + previousTopicInbound: session.currentTopicInbound, + previousTopicExpiry: Date.now() + TOPIC_TRANSITION_WINDOW_MS, + // Promote next to current + currentTopicInbound: session.nextTopicInbound, + currentTopicOutbound: session.nextTopicOutbound, + // Clear next (will be computed on next DH ratchet) + nextTopicInbound: undefined, + nextTopicOutbound: undefined, + // Increment epoch + topicEpoch: session.topicEpoch + 1, + updatedAt: Date.now(), + }; + } +} \ No newline at end of file diff --git a/packages/sdk/src/client/VerbethClient.ts b/packages/sdk/src/client/VerbethClient.ts index e3161eb..2d695b1 100644 --- a/packages/sdk/src/client/VerbethClient.ts +++ b/packages/sdk/src/client/VerbethClient.ts @@ -3,16 +3,36 @@ /** * High-level client for Verbeth E2EE messaging. * - * Handles handshake operations. Message encryption is done via - * the ratchet module at the application layer. + * Provides a unified API for: + * - Handshake operations (sendHandshake, acceptHandshake) + * - Message encryption/decryption with session management + * - Two-phase commit for message sending + * - Transaction confirmation handling * - * NOTE: sendMessage() has been REMOVED. Use ratchet functions directly: - * - ratchetEncrypt() for encryption - * - packageRatchetPayload() for binary encoding - * - executor.sendMessage() for on-chain submission + * @example + * ```typescript + * // Create client + * const client = new VerbethClient({ + * executor, + * identityKeyPair, + * identityProof, + * signer, + * address: '0x...' + * }); + * + * // Configure storage (required for messaging) + * client.setSessionStore(sessionStore); + * client.setPendingStore(pendingStore); + * + * // Send a message + * const result = await client.sendMessage(conversationId, 'Hello!'); + * + * // On confirmation event + * const confirmed = await client.confirmTx(txHash); + * ``` */ -import nacl from 'tweetnacl'; +import { hexlify } from 'ethers'; import { initiateHandshake, respondToHandshake } from '../send.js'; import { deriveDuplexTopics } from '../crypto.js'; import type { IExecutor } from '../executor.js'; @@ -26,77 +46,27 @@ import * as utils from '../utils.js'; import * as identity from '../identity.js'; import * as ratchet from '../ratchet/index.js'; -// ============================================================================= -// Types -// ============================================================================= - -export interface VerbethClientConfig { - executor: IExecutor; - identityKeyPair: IdentityKeyPair; - identityProof: IdentityProof; - signer: Signer; - address: string; -} - -export interface HandshakeResult { - tx: any; - /** Ephemeral keypair - MUST persist secretKey for ratchet session init */ - ephemeralKeyPair: nacl.BoxKeyPair; -} - -export interface HandshakeResponseResult { - tx: any; - /** Derived duplex topics for the conversation */ - duplexTopics: DuplexTopics; - /** Tag used for inResponseTo field */ - tag: `0x${string}`; - /** Salt for topic derivation (= getBytes(tag)) */ - salt: Uint8Array; - /** - * Responder's DH ratchet secret - MUST persist as dhMySecretKey in ratchet. - * NOTE: This is DIFFERENT from the on-chain responderEphemeralR (which is the tag key). - */ - responderEphemeralSecret: Uint8Array; - /** - * Responder's DH ratchet public key (inside encrypted payload, NOT on-chain). - * NOTE: This is DIFFERENT from responderEphemeralR for unlinkability. - */ - responderEphemeralPublic: Uint8Array; -} +import { ratchetEncrypt } from '../ratchet/encrypt.js'; +import { ratchetDecrypt } from '../ratchet/decrypt.js'; +import { packageRatchetPayload, parseRatchetPayload, isRatchetPayload } from '../ratchet/codec.js'; +import { verifyMessageSignature } from '../ratchet/auth.js'; +import type { RatchetSession } from '../ratchet/types.js'; -// ============================================================================= -// Client -// ============================================================================= +import { SessionManager } from './SessionManager.js'; +import { PendingManager } from './PendingManager.js'; +import type { + VerbethClientConfig, + HandshakeResult, + HandshakeResponseResult, + SessionStore, + PendingStore, + PreparedMessage, + DecryptedMessage, + SendResult, + ConfirmResult, + SerializedSessionInfo, +} from './types.js'; -/** - * High-level client for Verbeth E2EE messaging. - * - * @example - * ```typescript - * const client = new VerbethClient({ - * executor, - * identityKeyPair, - * identityProof, - * signer, - * address: '0x...' - * }); - * - * // Send a handshake - * const { tx, ephemeralKeyPair } = await client.sendHandshake( - * '0xBob...', - * 'Hello Bob!' - * ); - * // MUST persist ephemeralKeyPair.secretKey for ratchet session init - * - * // Accept a handshake - * const { duplexTopics, responderEphemeralSecret } = await client.acceptHandshake( - * handshake.ephemeralPubKey, - * handshake.identityPubKey, - * 'Hello Alice!' - * ); - * // Use responderEphemeralSecret with initSessionAsResponder() - * ``` - */ export class VerbethClient { private readonly executor: IExecutor; private readonly identityKeyPair: IdentityKeyPair; @@ -104,6 +74,10 @@ export class VerbethClient { private readonly signer: Signer; private readonly address: string; + // configured via setters + private sessionManager?: SessionManager; + private pendingManager?: PendingManager; + constructor(config: VerbethClientConfig) { this.executor = config.executor; this.identityKeyPair = config.identityKeyPair; @@ -112,6 +86,32 @@ export class VerbethClient { this.address = config.address; } + /** + * Configure session storage. + * Must be called before using prepareMessage/decryptMessage/sendMessage. + */ + setSessionStore(store: SessionStore): void { + this.sessionManager = new SessionManager(store); + } + + /** + * Configure pending message storage. + * Must be called before using sendMessage/confirmTx/revertTx. + */ + setPendingStore(store: PendingStore): void { + this.pendingManager = new PendingManager(store); + } + + + hasSessionStore(): boolean { + return !!this.sessionManager; + } + + hasPendingStore(): boolean { + return !!this.pendingManager; + } + + /** * Initiates a handshake with a recipient. * @@ -149,26 +149,6 @@ export class VerbethClient { * @param initiatorIdentityPubKey - Initiator's long-term X25519 identity key * @param note - Response message to send back * @returns Transaction, derived duplex topics, and ephemeral keys for ratchet - * - * @example - * ```typescript - * const result = await client.acceptHandshake( - * handshake.ephemeralPubKey, - * handshake.identityPubKey, - * 'Hello Alice!' - * ); - * - * // Initialize ratchet session as responder - * const session = initSessionAsResponder({ - * myAddress: myAddress, - * contactAddress: handshake.sender, - * myResponderEphemeralSecret: result.responderEphemeralSecret, - * myResponderEphemeralPublic: result.responderEphemeralPublic, - * theirHandshakeEphemeralPubKey: handshake.ephemeralPubKey, - * topicOutbound: pickOutboundTopic(false, result.duplexTopics), - * topicInbound: pickOutboundTopic(true, result.duplexTopics), - * }); - * ``` */ async acceptHandshake( initiatorEphemeralPubKey: Uint8Array, @@ -207,8 +187,282 @@ export class VerbethClient { }; } + + /** + * Prepare a message for sending (encrypt without submitting). + * + * Two-phase commit pattern: + * 1. prepareMessage() - encrypts and persists session state immediately + * 2. Submit transaction using prepared.payload and prepared.topic + * 3. On confirmation, call confirmTx() to clean up pending record + * + * Session state is committed immediately for forward secrecy. + * If tx fails, the ratchet slot is "burned" (receiver handles via skip keys). + * + * @param conversationId - The conversation to send in + * @param plaintext - Message text to encrypt + * @returns PreparedMessage with payload ready for on-chain submission + */ + async prepareMessage( + conversationId: string, + plaintext: string + ): Promise { + if (!this.sessionManager) { + throw new Error('SessionStore not configured. Call setSessionStore() first.'); + } + + const session = await this.sessionManager.getByConversationId(conversationId); + if (!session) { + throw new Error(`No session found for conversation: ${conversationId}`); + } + + const plaintextBytes = new TextEncoder().encode(plaintext); + + const encryptResult = ratchetEncrypt( + session, + plaintextBytes, + this.identityKeyPair.signingSecretKey + ); + + const packedPayload = packageRatchetPayload( + encryptResult.signature, + encryptResult.header, + encryptResult.ciphertext + ); + + // Immediately persist session state + await this.sessionManager.save(encryptResult.session); + + const prepared: PreparedMessage = { + id: this.generatePreparedId(), + conversationId, + topic: encryptResult.topic, + payload: packedPayload, + plaintext, + sessionBefore: session, + sessionAfter: encryptResult.session, + messageNumber: session.sendingMsgNumber, + createdAt: Date.now(), + }; + + return prepared; + } + + // Session already saved in prepareMessage for forward secrecy. + // This method can be used for additional bookkeeping if needed. + async commitMessage(_prepared: PreparedMessage): Promise { + } + + /** + * Decrypt an incoming message. + * + * Handles: + * - Topic routing (current, next, previous) + * - Signature verification (DoS protection) + * - Ratchet decryption + * - Session state updates + * - Automatic topic promotion + * + * @param topic - The topic the message arrived on + * @param payload - Raw message payload (Uint8Array) + * @param senderSigningKey - Sender's Ed25519 signing public key + * @param isOwnMessage - Whether this is our own outbound message (echo) + * @returns DecryptedMessage or null if decryption fails + */ + async decryptMessage( + topic: string, + payload: Uint8Array, + senderSigningKey: Uint8Array, + isOwnMessage: boolean = false + ): Promise { + if (!this.sessionManager) { + throw new Error('SessionStore not configured. Call setSessionStore() first.'); + } + + if (isOwnMessage) { + return null; + } + + const result = await this.sessionManager.getByInboundTopic(topic); + if (!result) { + return null; + } + + const { session, topicMatch } = result; + + if (!isRatchetPayload(payload)) { + return null; + } + + const parsed = parseRatchetPayload(payload); + if (!parsed) { + return null; + } + + // verify signature before any ratchet operations + const sigValid = verifyMessageSignature( + parsed.signature, + parsed.header, + parsed.ciphertext, + senderSigningKey + ); + + if (!sigValid) { + return null; + } + + const decryptResult = ratchetDecrypt(session, parsed.header, parsed.ciphertext); + if (!decryptResult) { + return null; + } + + await this.sessionManager.save(decryptResult.session); + + const plaintextStr = new TextDecoder().decode(decryptResult.plaintext); + + return { + conversationId: session.conversationId, + plaintext: plaintextStr, + isOwnMessage: false, + session: decryptResult.session, + topic, + topicMatch, + }; + } + + /** + * Send a message with full lifecycle management. + * + * This is the high-level API that handles: + * 1. Encryption (with session commit) + * 2. Pending record creation + * 3. Transaction submission + * 4. Status tracking + * + * After calling this, wait for on-chain confirmation and call confirmTx(). + * + * @param conversationId - Conversation to send in + * @param plaintext - Message text + * @returns SendResult with txHash and metadata + */ + async sendMessage( + conversationId: string, + plaintext: string + ): Promise { + if (!this.sessionManager) { + throw new Error('SessionStore not configured. Call setSessionStore() first.'); + } + if (!this.pendingManager) { + throw new Error('PendingStore not configured. Call setPendingStore() first.'); + } + + // 1. Prepare message (encrypts and persists session) + const prepared = await this.prepareMessage(conversationId, plaintext); + + // 2. Create pending record + await this.pendingManager.create({ + id: prepared.id, + conversationId, + topic: prepared.topic, + payloadHex: hexlify(prepared.payload), + plaintext, + sessionStateBefore: JSON.stringify(this.serializeSessionInfo(prepared.sessionBefore)), + sessionStateAfter: JSON.stringify(this.serializeSessionInfo(prepared.sessionAfter)), + createdAt: prepared.createdAt, + }); + + // 3. Submit transaction + const timestamp = Math.floor(Date.now() / 1000); + const nonce = prepared.messageNumber; + + try { + const tx = await this.executor.sendMessage( + prepared.payload, + prepared.topic, + timestamp, + BigInt(nonce) + ); + + // 4. Update pending with txHash + await this.pendingManager.markSubmitted(prepared.id, tx.hash); + + return { + messageId: prepared.id, + txHash: tx.hash, + topic: prepared.topic, + messageNumber: nonce, + }; + } catch (error) { + // Mark as failed (ratchet slot is already burned) + await this.pendingManager.markFailed(prepared.id); + throw error; + } + } + + /** + * Confirm a transaction after on-chain confirmation. + * Call this when you see your MessageSent event on-chain. + * + * @param txHash - Transaction hash to confirm + * @returns ConfirmResult or null if not found + */ + async confirmTx(txHash: string): Promise { + if (!this.pendingManager) { + throw new Error('PendingStore not configured.'); + } + + const pending = await this.pendingManager.getByTxHash(txHash); + if (!pending || pending.status !== 'submitted') { + return null; + } + + // Finalize (delete pending record) + const finalized = await this.pendingManager.finalize(pending.id); + if (!finalized) { + return null; + } + + return { + conversationId: finalized.conversationId, + plaintext: finalized.plaintext, + messageId: finalized.id, + }; + } + + /** + * Handle transaction failure/revert. + * + * The ratchet slot is already burned (session was persisted in prepareMessage). + * This just cleans up the pending record. + * + * @param txHash - Transaction hash that failed + */ + async revertTx(txHash: string): Promise { + if (!this.pendingManager) { + throw new Error('PendingStore not configured.'); + } + + const pending = await this.pendingManager.getByTxHash(txHash); + if (pending) { + await this.pendingManager.delete(pending.id); + } + } + + + invalidateSessionCache(conversationId: string): void { + this.sessionManager?.invalidate(conversationId); + } + + clearSessionCache(): void { + this.sessionManager?.clearCache(); + } + + async getSession(conversationId: string): Promise { + return this.sessionManager?.getByConversationId(conversationId) ?? null; + } + // =========================================================================== - // Low-level API access + // Low-level API Access // =========================================================================== /** Crypto utilities */ @@ -260,4 +514,26 @@ export class VerbethClient { get identityProofInstance(): IdentityProof { return this.identityProof; } + + /** + * Generate unique ID for prepared messages. + */ + private generatePreparedId(): string { + return `prep-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`; + } + + /** + * Serialize session info for storage. + * Used in pending records for debugging/recovery. + */ + private serializeSessionInfo(session: RatchetSession): SerializedSessionInfo { + return { + conversationId: session.conversationId, + topicEpoch: session.topicEpoch, + sendingMsgNumber: session.sendingMsgNumber, + receivingMsgNumber: session.receivingMsgNumber, + currentTopicOutbound: session.currentTopicOutbound, + currentTopicInbound: session.currentTopicInbound, + }; + } } \ No newline at end of file diff --git a/packages/sdk/src/client/index.ts b/packages/sdk/src/client/index.ts index 680e7ec..2f0122f 100644 --- a/packages/sdk/src/client/index.ts +++ b/packages/sdk/src/client/index.ts @@ -1,8 +1,25 @@ // packages/sdk/src/client/index.ts export { VerbethClient } from './VerbethClient.js'; +export { SessionManager } from './SessionManager.js'; +export { PendingManager } from './PendingManager.js'; + export type { VerbethClientConfig, + HandshakeResult, - HandshakeResponseResult + HandshakeResponseResult, + + SessionStore, + PendingStore, + + PreparedMessage, + DecryptedMessage, + PendingMessage, + PendingStatus, + + SendResult, + ConfirmResult, + + SerializedSessionInfo, } from './types.js'; \ No newline at end of file diff --git a/packages/sdk/src/client/types.ts b/packages/sdk/src/client/types.ts index fe4687d..83913d5 100644 --- a/packages/sdk/src/client/types.ts +++ b/packages/sdk/src/client/types.ts @@ -1,12 +1,20 @@ // packages/sdk/src/client/types.ts +/** + * Client types for VerbethClient. + * + * Includes storage interfaces that apps implement to connect + * VerbethClient to their persistence layer. + */ + import type { Signer } from 'ethers'; import type { IExecutor } from '../executor.js'; import type { IdentityKeyPair, IdentityProof, DuplexTopics } from '../types.js'; +import type { RatchetSession } from '../ratchet/types.js'; import type nacl from 'tweetnacl'; /** - * Configuration for creating a VerbethClient instance + * Configuration for creating a VerbethClient instance. */ export interface VerbethClientConfig { executor: IExecutor; @@ -16,22 +24,122 @@ export interface VerbethClientConfig { address: string; } -/** - * Result from initiating a handshake - */ export interface HandshakeResult { tx: any; - ephemeralKeyPair: nacl.BoxKeyPair; // to be stored + ephemeralKeyPair: nacl.BoxKeyPair; // must persist secretKey for ratchet session init } -/** - * Result from accepting a handshake - */ export interface HandshakeResponseResult { tx: any; duplexTopics: DuplexTopics; tag: `0x${string}`; salt: Uint8Array; - responderEphemeralSecret: Uint8Array; + responderEphemeralSecret: Uint8Array; // must persist as dhMySecretKey in ratchet responderEphemeralPublic: Uint8Array; +} + +/** + * Storage interface for ratchet sessions. + * Implement this to connect VerbethClient to your storage layer. + */ +export interface SessionStore { + get(conversationId: string): Promise; + + /** + * Find session by any active inbound topic. + * Must check: currentTopicInbound, nextTopicInbound, previousTopicInbound (if not expired). + */ + getByInboundTopic(topic: string): Promise; + save(session: RatchetSession): Promise; +} + +/** + * Result of prepareMessage - contains everything needed to send and commit. + * + * Two-phase commit pattern: + * 1. prepareMessage() - encrypts and returns PreparedMessage + * 2. Send transaction using prepared.payload and prepared.topic + * 3. Session state is already committed for forward secrecy + */ +export interface PreparedMessage { + id: string; + conversationId: string; + topic: `0x${string}`; + payload: Uint8Array; + plaintext: string; + sessionBefore: RatchetSession; + sessionAfter: RatchetSession; + messageNumber: number; + createdAt: number; +} + +/** + * Result of decryptMessage. + */ +export interface DecryptedMessage { + conversationId: string; + plaintext: string; + isOwnMessage: boolean; + session: RatchetSession; + topic: string; + topicMatch: 'current' | 'next' | 'previous'; +} + + +export type PendingStatus = 'preparing' | 'submitted' | 'confirmed' | 'failed'; + +/** + * Pending outbound message record. + * Used for matching on-chain confirmations to sent messages. + */ +export interface PendingMessage { + id: string; + conversationId: string; + topic: string; + payloadHex: string; + plaintext: string; + sessionStateBefore: string; + sessionStateAfter: string; + createdAt: number; + txHash: string | null; + status: PendingStatus; +} + +/** + * Storage interface for pending outbound messages. + * Implement this to enable sendMessage/confirmTx/revertTx. + */ +export interface PendingStore { + save(pending: PendingMessage): Promise; + get(id: string): Promise; + getByTxHash(txHash: string): Promise; + updateStatus(id: string, status: PendingStatus, txHash?: string): Promise; + delete(id: string): Promise; + getByConversation(conversationId: string): Promise; +} + +/** + * Result of sendMessage. + */ +export interface SendResult { + messageId: string; + txHash: string; + topic: `0x${string}`; + messageNumber: number; +} + + +export interface ConfirmResult { + conversationId: string; + plaintext: string; + messageId: string; +} + +export interface SerializedSessionInfo { + conversationId: string; + topicEpoch: number; + sendingMsgNumber: number; + receivingMsgNumber: number; + currentTopicOutbound: string; + currentTopicInbound: string; } \ No newline at end of file diff --git a/packages/sdk/src/index.ts b/packages/sdk/src/index.ts index 8bdcac9..e090352 100644 --- a/packages/sdk/src/index.ts +++ b/packages/sdk/src/index.ts @@ -1,3 +1,5 @@ +// packages/sdk/src/index.ts + export * from './crypto.js'; export * from './payload.js'; export * from './send.js'; @@ -9,8 +11,6 @@ export * from './executor.js'; export { decryptMessage as decryptLog } from './crypto.js'; -export { getNextNonce } from './utils/nonce.js'; - export { encodeUnifiedPubKeys, decodeUnifiedPubKeys, @@ -46,15 +46,30 @@ export { ExecutorFactory } from './executor.js'; + +export { getNextNonce } from './utils/nonce.js'; export { SafeSessionSigner } from "./utils/safeSessionSigner.js"; export type { SafeSessionSignerOptions } from "./utils/safeSessionSigner.js"; -// high-level client API -export { VerbethClient } from './client/index.js'; +export { VerbethClient, SessionManager, PendingManager } from './client/index.js'; + export type { VerbethClientConfig, HandshakeResult, - HandshakeResponseResult + HandshakeResponseResult, + + SessionStore, + PendingStore, + + PreparedMessage, + DecryptedMessage, + PendingMessage, + PendingStatus, + + SendResult, + ConfirmResult, + + SerializedSessionInfo, } from './client/index.js'; export * from './ratchet/index.js'; \ No newline at end of file diff --git a/packages/sdk/src/ratchet/auth.ts b/packages/sdk/src/ratchet/auth.ts index ec38b4d..15a7bdc 100644 --- a/packages/sdk/src/ratchet/auth.ts +++ b/packages/sdk/src/ratchet/auth.ts @@ -52,6 +52,7 @@ export function verifyMessageSignature( /** * Encode header as 40 bytes for signature verification. + * Format: dh (32) + pn (4, BE) + n (4, BE) */ function encodeHeaderForSigning(header: MessageHeader): Uint8Array { const buf = new Uint8Array(40); @@ -62,7 +63,7 @@ function encodeHeaderForSigning(header: MessageHeader): Uint8Array { } // ============================================================================= -// Signature Creation (for completeness - also in encrypt.ts) +// Signature Creation // ============================================================================= /** diff --git a/packages/sdk/src/ratchet/codec.ts b/packages/sdk/src/ratchet/codec.ts index 403040c..9c1d24e 100644 --- a/packages/sdk/src/ratchet/codec.ts +++ b/packages/sdk/src/ratchet/codec.ts @@ -3,6 +3,7 @@ /** * Binary Codec for Ratchet Messages. * + * Wire format: * โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” * โ”‚ Offset โ”‚ Size โ”‚ Field โ”‚ * โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค @@ -13,13 +14,18 @@ * โ”‚ 101 โ”‚ 4 โ”‚ n (uint32 BE) - message number โ”‚ * โ”‚ 105 โ”‚ var โ”‚ Ciphertext (nonce + AEAD output) โ”‚ * โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ + * + * Total minimum: 105 bytes + ciphertext */ import { MessageHeader, ParsedRatchetPayload, RATCHET_VERSION_V1 } from './types.js'; +/** Minimum payload length: version(1) + sig(64) + dh(32) + pn(4) + n(4) */ const MIN_PAYLOAD_LENGTH = 1 + 64 + 32 + 4 + 4; // 105 bytes /** + * Package ratchet message components into binary format. + * * @param signature - Ed25519 signature (64 bytes) * @param header - Message header (dh, pn, n) * @param ciphertext - Encrypted payload (nonce + secretbox output) @@ -108,6 +114,7 @@ export function parseRatchetPayload(payload: Uint8Array): ParsedRatchetPayload | } /** + * Check if payload is in ratchet format. * Used to distinguish ratchet messages from legacy JSON format. * * @param payload - Raw payload bytes diff --git a/packages/sdk/src/ratchet/decrypt.ts b/packages/sdk/src/ratchet/decrypt.ts index d74675d..8420b0b 100644 --- a/packages/sdk/src/ratchet/decrypt.ts +++ b/packages/sdk/src/ratchet/decrypt.ts @@ -2,6 +2,8 @@ /** * Ratchet Decryption with Skip Key Handling. + * + * Handles: * - Normal sequential message decryption * - DH ratchet steps when sender's DH key changes * - Out-of-order messages via skipped keys @@ -23,6 +25,7 @@ import { kdfRootKey, kdfChainKey, dh, generateDHKeyPair, deriveTopicFromDH } fro /** * Decrypt a message using the ratchet. + * * @param session - Current ratchet session state * @param header - Parsed message header * @param ciphertext - Encrypted payload (nonce + secretbox output) @@ -33,7 +36,7 @@ export function ratchetDecrypt( header: MessageHeader, ciphertext: Uint8Array ): DecryptResult | null { - // even authenticated messages shouldn't require insane skips + // Sanity check: even authenticated messages shouldn't require insane skips const skipNeeded = Math.max(0, header.n - session.receivingMsgNumber); if (skipNeeded > MAX_SKIP_PER_MESSAGE || header.pn > MAX_SKIP_PER_MESSAGE) { console.error( @@ -58,10 +61,12 @@ export function ratchetDecrypt( // 3. Check if we need to perform a DH ratchet step if (dhPubHex !== currentTheirDHHex) { + // Skip any remaining messages from previous receiving chain if (newSession.receivingChainKey) { newSession = skipMessages(newSession, newSession.receivingMsgNumber, header.pn); } + // Perform DH ratchet step newSession = dhRatchetStep(newSession, header.dh); } @@ -87,6 +92,7 @@ export function ratchetDecrypt( try { messageKey.fill(0); } catch { + // Ignore if fill fails } if (!plaintext) { @@ -108,32 +114,34 @@ export function ratchetDecrypt( } /** - * DH ratchet on receipt of a message that carries a new remote DH public key. + * DH ratchet step on receipt of a message with a new remote DH public key. * - * Topic derivation is sender centric: `deriveTopicFromDH(x, 'outbound')` denotes the topic used - * by the party who *sent* the DH pubkey for their sending direction. Therefore, when we ratchet - * on receive, we swap labels for the topics derived from `dhReceive`. + * Topic derivation is sender-centric: `deriveTopicFromDH(x, 'outbound')` denotes + * the topic used by the party who *sent* the DH pubkey for their sending direction. + * Therefore, when we ratchet on receive, we swap labels for topics derived from `dhReceive`. */ function dhRatchetStep(session: RatchetSession, theirNewDHPub: Uint8Array): RatchetSession { - // advance receiving chain (based on our current DH secret and their new DH pubkey) + // Advance receiving chain (based on our current DH secret and their new DH pubkey) const dhReceive = dh(session.dhMySecretKey, theirNewDHPub); const { rootKey: rootKey1, chainKey: receivingChainKey } = kdfRootKey( session.rootKey, dhReceive ); + // Generate new DH keypair for our next sending chain const newDHKeyPair = generateDHKeyPair(); + // Advance sending chain const dhSend = dh(newDHKeyPair.secretKey, theirNewDHPub); const { rootKey: rootKey2, chainKey: sendingChainKey } = kdfRootKey(rootKey1, dhSend); const saltBytes = getBytes(session.conversationId); - // Current topics (post ratchet) are swapped since we're the receiver of dhReceive + // Current topics (post ratchet) - swapped since we're the receiver const newTopicOut = deriveTopicFromDH(dhReceive, 'inbound', saltBytes); const newTopicIn = deriveTopicFromDH(dhReceive, 'outbound', saltBytes); - // Next topics (for our next DH pubkey): normal labels because we will be the sender. + // Next topics (for our next DH pubkey) - normal labels because we will be the sender const nextTopicOut = deriveTopicFromDH(dhSend, 'outbound', saltBytes); const nextTopicIn = deriveTopicFromDH(dhSend, 'inbound', saltBytes); @@ -151,7 +159,6 @@ function dhRatchetStep(session: RatchetSession, theirNewDHPub: Uint8Array): Ratc nextTopicOutbound: nextTopicOut, nextTopicInbound: nextTopicIn, - currentTopicOutbound: newTopicOut, currentTopicInbound: newTopicIn, previousTopicInbound: session.currentTopicInbound, @@ -162,6 +169,7 @@ function dhRatchetStep(session: RatchetSession, theirNewDHPub: Uint8Array): Ratc /** * Skip messages by deriving and storing their keys for later out-of-order decryption. + * * Called when: * - header.n > receivingMsgNumber (messages skipped in current epoch) * - DH ratchet step with header.pn > 0 (messages from previous epoch) @@ -191,6 +199,7 @@ function skipMessages( chainKey = newChainKey; } + // Prune if we have too many skipped keys let prunedKeys = skippedKeys; if (skippedKeys.length > MAX_STORED_SKIPPED_KEYS) { prunedKeys = skippedKeys @@ -263,6 +272,8 @@ function decryptWithKey(ciphertext: Uint8Array, messageKey: Uint8Array): Uint8Ar } /** + * Prune expired skipped keys from session. + * * @param session - Current session * @param maxAgeMs - Maximum age in milliseconds (default: 24 hours) * @returns Session with pruned skipped keys @@ -276,6 +287,7 @@ export function pruneExpiredSkippedKeys( const prunedKeys = session.skippedKeys.filter((sk) => sk.createdAt > cutoff); + // Wipe expired keys for (const sk of session.skippedKeys) { if (sk.createdAt <= cutoff) { try { @@ -286,7 +298,7 @@ export function pruneExpiredSkippedKeys( } if (prunedKeys.length === session.skippedKeys.length) { - return session; + return session; // No change } return { diff --git a/packages/sdk/src/ratchet/encrypt.ts b/packages/sdk/src/ratchet/encrypt.ts index 13605b7..613070b 100644 --- a/packages/sdk/src/ratchet/encrypt.ts +++ b/packages/sdk/src/ratchet/encrypt.ts @@ -6,8 +6,8 @@ * Encrypts plaintext using the current sending chain, advances chain state, * and signs the message with Ed25519. * - * Returns a new session object. Caller must not persist until - * the tx is confirmed on-chain (two-phase commit pattern). + * Returns a new session object. Caller must persist session state + * immediately for forward secrecy (before tx submission). */ import nacl from 'tweetnacl'; @@ -26,7 +26,9 @@ export function encodeHeader(header: MessageHeader): Uint8Array { return buf; } -/** +/** + * Encrypt a message using the ratchet. + * * @param session - Current ratchet session state * @param plaintext - Message to encrypt * @param signingSecretKey - Ed25519 secret key for signing (64 bytes) diff --git a/packages/sdk/src/ratchet/kdf.ts b/packages/sdk/src/ratchet/kdf.ts index 68ff317..a72d856 100644 --- a/packages/sdk/src/ratchet/kdf.ts +++ b/packages/sdk/src/ratchet/kdf.ts @@ -14,6 +14,8 @@ import { keccak256 } from 'ethers'; import nacl from 'tweetnacl'; /** + * Derive new root key and chain key from DH output. + * * @param rootKey - Current root key (32 bytes) * @param dhOutput - DH shared secret (32 bytes) * @returns New root key and chain key @@ -30,6 +32,8 @@ export function kdfRootKey( } /** + * Derive message key and advance chain key. + * * @param chainKey - Current chain key (32 bytes) * @returns New chain key and message key for encryption/decryption */ diff --git a/packages/sdk/src/ratchet/session.ts b/packages/sdk/src/ratchet/session.ts index 284c7bd..6d20c28 100644 --- a/packages/sdk/src/ratchet/session.ts +++ b/packages/sdk/src/ratchet/session.ts @@ -2,7 +2,11 @@ /** * Ratchet Session Initialization. - * Initial shared secret is derived from ephemeral to ephemeral DH only. + * + * Provides functions to initialize ratchet sessions for both + * initiator (Alice) and responder (Bob) roles. + * + * Initial shared secret is derived from ephemeral-to-ephemeral DH only. */ import { keccak256, toUtf8Bytes, getBytes } from 'ethers'; @@ -16,6 +20,10 @@ import { kdfRootKey, dh, generateDHKeyPair, deriveTopicFromDH } from './kdf.js'; /** * Compute deterministic conversation ID from topics. * Sorting ensures both parties derive the same ID regardless of perspective. + * + * @param topicA - First topic + * @param topicB - Second topic + * @returns Unique conversation identifier */ export function computeConversationId(topicA: string, topicB: string): string { const sorted = [topicA.toLowerCase(), topicB.toLowerCase()].sort(); @@ -23,6 +31,8 @@ export function computeConversationId(topicA: string, topicB: string): string { } /** + * Initialize session as responder (Bob). + * * Called after receiving handshake, before/during sending response. * The responder must persist myResponderEphemeralSecret immediately. * This becomes dhMySecretKey and is required for all future ratchet operations. @@ -70,7 +80,7 @@ export function initSessionAsResponder(params: InitResponderParams): RatchetSess sendingChainKey, sendingMsgNumber: 0, - // Receiving chain not yet established + // Receiving chain not yet established (Alice sends first post-handshake) receivingChainKey: null, receivingMsgNumber: 0, @@ -91,9 +101,11 @@ export function initSessionAsResponder(params: InitResponderParams): RatchetSess } /** + * Initialize session as initiator (Alice). + * * Called after receiving and validating handshake response. * - * Initiator precomputes epoch 1 topics from its first post handshake DH step. + * Initiator precomputes epoch 1 topics from its first post-handshake DH step. * Outbound should use epoch 1 as soon as we introduce a new DH pubkey. * Inbound stays on epoch 0 until the responder ratchets. * @@ -118,7 +130,7 @@ export function initSessionAsInitiator(params: InitInitiatorParams): RatchetSess sharedSecret ); - // Generate first DH keypair for sending + // Generate first DH keypair for sending (Alice performs first DH ratchet) const myDHKeyPair = generateDHKeyPair(); const dhSend = dh(myDHKeyPair.secretKey, theirResponderEphemeralPubKey); @@ -129,6 +141,8 @@ export function initSessionAsInitiator(params: InitInitiatorParams): RatchetSess const conversationId = computeConversationId(topicOutbound, topicInbound); const saltBytes = getBytes(conversationId); + + // Pre-compute epoch 1 topics (for when our first message is sent) const epoch1TopicOut = deriveTopicFromDH(dhSend, 'outbound', saltBytes); const epoch1TopicIn = deriveTopicFromDH(dhSend, 'inbound', saltBytes); @@ -148,15 +162,19 @@ export function initSessionAsInitiator(params: InitInitiatorParams): RatchetSess sendingChainKey, sendingMsgNumber: 0, + + // Alice can receive Bob's messages immediately receivingChainKey: bobsSendingChain, receivingMsgNumber: 0, previousChainLength: 0, skippedKeys: [], + // Start with handshake topics currentTopicOutbound: topicOutbound, currentTopicInbound: topicInbound, + // Pre-computed next topics (will be promoted when we send) nextTopicOutbound: epoch1TopicOut, nextTopicInbound: epoch1TopicIn, topicEpoch: 0, diff --git a/packages/sdk/src/ratchet/types.ts b/packages/sdk/src/ratchet/types.ts index c9410a2..5fb3197 100644 --- a/packages/sdk/src/ratchet/types.ts +++ b/packages/sdk/src/ratchet/types.ts @@ -30,9 +30,7 @@ export const SYNC_BATCH_SIZE = 10_000; */ export const RATCHET_VERSION_V1 = 0x01; -/** - * Topic transition window (5 minutes). - */ +// Previous topic remains valid for this duration after promotion. export const TOPIC_TRANSITION_WINDOW_MS = 5 * 60 * 1000; /** @@ -86,12 +84,19 @@ export interface RatchetSession { skippedKeys: SkippedKey[]; // === Topic Ratcheting === + /** Current outbound topic (may differ from original after ratcheting) */ currentTopicOutbound: `0x${string}`; + /** Current inbound topic (may differ from original after ratcheting) */ currentTopicInbound: `0x${string}`; + /** Pre-computed next outbound topic (for our next DH ratchet) */ nextTopicOutbound?: `0x${string}`; + /** Pre-computed next inbound topic (for their next DH ratchet) */ nextTopicInbound?: `0x${string}`; + /** Previous inbound topic (grace period for late messages) */ previousTopicInbound?: `0x${string}`; + /** Expiry timestamp for previous topic */ previousTopicExpiry?: number; + /** Topic epoch counter */ topicEpoch: number; // === Metadata === @@ -135,11 +140,11 @@ export interface MessageHeader { * Result of ratchetEncrypt - includes new session state for two-phase commit. */ export interface EncryptResult { + /** Updated session state (MUST be persisted) */ session: RatchetSession; header: MessageHeader; ciphertext: Uint8Array; signature: Uint8Array; - /** Current outbound topic to use for this message */ topic: `0x${string}`; } @@ -147,6 +152,7 @@ export interface EncryptResult { * Result of ratchetDecrypt. */ export interface DecryptResult { + /** Updated session state (MUST be persisted) */ session: RatchetSession; plaintext: Uint8Array; } @@ -184,7 +190,7 @@ export interface InitInitiatorParams { contactAddress: string; /** Handshake ephemeral secret (must persist until response arrives) */ myHandshakeEphemeralSecret: Uint8Array; - + /** Responder's ephemeral from HandshakeResponse (inside encrypted payload) */ theirResponderEphemeralPubKey: Uint8Array; topicOutbound: `0x${string}`; topicInbound: `0x${string}`; diff --git a/plan(done).md b/plan(done).md new file mode 100644 index 0000000..4fc167c --- /dev/null +++ b/plan(done).md @@ -0,0 +1,241 @@ +# Verbeth SDK: Double Ratchet Implementation Plan + +## Overview + +This plan implements Signal-style Double Ratchet for bilateral forward secrecy and topic unlinkability. Compromising identity keys never allows decrypting past messagesโ€”not even message 0. + +**Scope**: Core Double Ratchet only. Post-quantum are separate future phases. + +--- + +## 1. Key Design Decisions + +### 1.1 Ephemeral-Only Initial Secret + +**Traditional Signal**: Initial secret includes identity keys โ†’ identity compromise exposes message 0. + +**Verbeth**: Initial secret is `DH(AliceEphemeral, BobRatchetEphemeral)` ONLY. +- No identity keys in initial secret +- Authentication via Ed25519 signatures on every message +- Identity compromise never decrypts any messages + +### 1.2 Two-Keypair Handshake (Unlinkability) + +Bob's `respondToHandshake` generates TWO separate keypairs: + +| Keypair | Purpose | Location | +|---------|---------|----------| +| `tagKeyPair (R, r)` | Compute `inResponseTo` tag | `R` on-chain as `responderEphemeralR` | +| `ratchetKeyPair` | First DH ratchet key | Public key inside encrypted payload | + +**Why**: Single keypair would let observers link `HandshakeResponse.R` to first message's DH header. With separation, no on-chain link exists between handshake and conversation. + +### 1.3 Session Keyed by Topics + +Sessions keyed by `conversationId = keccak256(sort([topicOut, topicIn]))`, not addresses. + +```typescript +interface RatchetSession { + conversationId: string; + topicOutbound: `0x${string}`; + topicInbound: `0x${string}`; + // ... ratchet state +} +``` + +Lookup: `session where topicInbound === event.topic` + +### 1.4 Immediate Session Commit (Skip-Key Resilient) + +**Original design**: Two-phase commit with sequential blocking. + +**Implemented design**: Immediate session commit after encryption. + +``` +1. Load session (from cache or DB) +2. Compute (nextState, header, ciphertext) +3. Save nextState to DB IMMEDIATELY +4. Send transaction +5. On SUCCESS: clean up pending record +6. On FAILURE: ratchet "slot" is burned, receiver handles via skip keys +``` + +**Why this works**: +- The ratchet protocol is designed for message loss +- Receivers handle gaps via skip-key mechanism +- Saving session immediately ensures subsequent messages use the advanced state +- Matches how Signal handles message failures + +### 1.5 Auth-Before-Ratchet (DoS Protection) + +**Attack**: Malicious `pn=999999, n=999999` forces millions of key derivations. + +**Defense**: Verify Ed25519 signature BEFORE any ratchet work. + +``` +1. Parse sig + header + ciphertext +2. Verify Ed25519(sig, header || ct, contact.signingPubKey) +3. IF invalid: reject (O(1) cost) +4. THEN attempt ratchet decrypt +``` + +### 1.6 Binary Encoding +Fixed overhead: ~105 bytes (vs ~200+ for JSON+base64). + +### 1.7 Skipped Keys: Reorg Tolerance, Not Offline Catch-Up + +**Common misconception**: Skipped keys handle offline periods. + +**Reality**: +- **Offline catch-up**: Process chain logs in order โ†’ chain key advances sequentially โ†’ no skipped keys +- **Skipped keys**: Handle block reorgs, out-of-order RPC responses, and failed transactions + +| Concept | Purpose | +|---------|---------| +| Chain key derivation | Sequential catch-up after offline | +| Skipped keys | Out-of-order delivery + tx failure tolerance | + +Bounds: +- `MAX_STORED_SKIPPED_KEYS = 1000` (memory limit) +- `MAX_SKIPPED_KEYS_AGE_MS = 24h` (TTL) + +--- + +## 2. State Loss & Recovery + +### 2.1 The Forward Secrecy Tradeoff + +**Fundamental truth**: Forward secrecy means lost local state = lost messages. + +The ratchet state is: +- **Stateful**: Each message advances the state irreversibly +- **Local-only**: Not stored on-chain or derivable from identity +- **Critical**: Without it, decryption is impossible + +### 2.2 When State Loss Occurs + +| Scenario | What's Lost | Recovery Path | +|----------|-------------|---------------| +| Browser IndexedDB cleared | Everything | Re-handshake all contacts | +| New device, same identity | Everything | Re-handshake all contacts | +| Corrupted database | Depends | Re-handshake affected contacts | +| Export then Import | Nothing | Seamless (ratchet state preserved) | + +### 2.3 Recovery: Just Re-Handshake + +No special "reset protocol" needed. The existing handshake flow handles recovery: + +``` +Alice (lost state) โ†’ sendHandshake(bob) โ†’ Bob accepts โ†’ New session +``` + +- New ephemeral keys generate new salt โ†’ new topics +- Old ratchet session orphaned in Bob's DB (harmless) +- Both parties continue with fresh session + +**UX implication**: Alice must manually re-initiate contact with each peer. This is acceptable; cloud sync (future) would eliminate this friction. + +--- + +# DH-Synchronized Topic Ratcheting + +Static topics enable long-term correlation of conversations by on-chain observers. Even with encrypted content, the repeated `topic` parameter in `MessageSent` events creates a linkable pattern. + +## Solution: DH-Synchronized Topic Ratcheting + +Derive new topics whenever a DH ratchet step occurs. The DH public key in message headers provides natural synchronizationโ€”both parties know when to rotate topics without additional coordination. + +## Key Insight + +The existing Double Ratchet already: +- Generates new DH keypairs on each turn (in `dhRatchetStep()`) +- Tracks `dhMyPublicKey` and `dhTheirPublicKey` +- Triggers on first message after receiving a new DH public key + +**Topic epochs = DH epochs.** When `dhTheirPublicKey` changes, derive new topics. + +--- + +# Security Notes + +1. **Deterministic** โ€” Both parties derive identical topics from `dhSend` +2. **No extra metadata** โ€” Epoch not transmitted; derived from DH state +3. **Unlinkable** โ€” After first DH step, new topic has no on-chain link to handshake +4. **Grace period** โ€” Prevents message loss without adding latency +--- + +## 4. Future Improvements + +### 4.1 Cloud Sync (Planned) + +**Problem**: Device loss = data loss. + +**Solution**: Encrypted cloud backup of full database state. + +``` +โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” +โ”‚ CLOUD SYNC FLOW โ”‚ +โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค +โ”‚ 1. Derive backup key: HKDF(identitySeed, "verbeth-backup") โ”‚ +โ”‚ 2. Serialize: { contacts, messages, ratchetSessions, ... } โ”‚ +โ”‚ 3. Encrypt: AES-GCM(backupKey, serializedData) โ”‚ +โ”‚ 4. Upload to user's cloud storage (Drive/iCloud/S3) โ”‚ +โ”‚ 5. On new device: download, decrypt, import โ”‚ +โ”‚ 6. Ratchet state restored โ†’ no reset needed โ”‚ +โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ +``` + +**Key properties**: +- Backup key derived from identity โ†’ only owner can decrypt +- Cloud provider never sees plaintext +- Backup includes ratchet state โ†’ seamless device migration +- Optional: encrypted sync on every state change + +**Implementation scope**: Separate feature, not part of core ratchet. + +### 4.2 Topic Ratcheting (Phase 2) + +Periodic topic rotation for enhanced metadata privacy. + +### 4.3 Post-Quantum (Phase 3) + +ML-KEM hybrid for quantum resistance. + +--- + +## 5. Success Criteria + +### Cryptographic โœ… +- [x] Identity key compromise never decrypts past messages (including message 0) +- [x] Post-compromise security: session recovers after key compromise +- [x] DoS resistance: unauthenticated messages rejected in O(1) +- [x] Unlinkability: on-chain R โ‰  message DH headers + +### State Management โœ… +- [x] Immediate session commit with skip-key resilience +- [x] Session caching: in-memory cache + DB persistence +- [x] Session keyed by topics (not addresses) +- [x] Confirmation matching by txHash + +### Resilience โœ… +- [x] Long offline periods: process in order, no skipped keys needed +- [x] Skipped keys for reorg tolerance (24h TTL) +- [x] Batch message processing with shared session cache + +### Session Reset โณ DEFERRED (handled implicitly by existing handshake) +- [x] New handshake to existing contact creates fresh session +- [x] Old session orphaned (no functional impact) +- [ ] *(Nice-to-have)* Detect missing sessions on startup +- [ ] *(Nice-to-have)* UI hint for "existing contact requests new session" +- [ ] *(Nice-to-have)* Cleanup orphaned sessions + +--- + +## 6. What's NOT in Scope + +| Feature | Phase | +|---------|-------| +| Topic ratcheting | Phase 2 | +| Post-quantum (ML-KEM) | Phase 3 | +| Cloud sync | Future | +| Export/import encryption | Future (current export is plaintext JSON) | \ No newline at end of file diff --git a/plan.md b/plan.md deleted file mode 100644 index 9df171f..0000000 --- a/plan.md +++ /dev/null @@ -1,771 +0,0 @@ -# Verbeth SDK: Double Ratchet Implementation Plan - -## Overview - -This plan implements Signal-style Double Ratchet for bilateral forward secrecy and topic unlinkability. Compromising identity keys never allows decrypting past messagesโ€”not even message 0. - -**Scope**: Core Double Ratchet only. Post-quantum are separate future phases. - ---- - -## 1. Key Design Decisions - -### 1.1 Ephemeral-Only Initial Secret - -**Traditional Signal**: Initial secret includes identity keys โ†’ identity compromise exposes message 0. - -**Verbeth**: Initial secret is `DH(AliceEphemeral, BobRatchetEphemeral)` ONLY. -- No identity keys in initial secret -- Authentication via Ed25519 signatures on every message -- Identity compromise never decrypts any messages - -### 1.2 Two-Keypair Handshake (Unlinkability) - -Bob's `respondToHandshake` generates TWO separate keypairs: - -| Keypair | Purpose | Location | -|---------|---------|----------| -| `tagKeyPair (R, r)` | Compute `inResponseTo` tag | `R` on-chain as `responderEphemeralR` | -| `ratchetKeyPair` | First DH ratchet key | Public key inside encrypted payload | - -**Why**: Single keypair would let observers link `HandshakeResponse.R` to first message's DH header. With separation, no on-chain link exists between handshake and conversation. - -### 1.3 Session Keyed by Topics - -Sessions keyed by `conversationId = keccak256(sort([topicOut, topicIn]))`, not addresses. - -```typescript -interface RatchetSession { - conversationId: string; - topicOutbound: `0x${string}`; - topicInbound: `0x${string}`; - // ... ratchet state -} -``` - -Lookup: `session where topicInbound === event.topic` - -### 1.4 Immediate Session Commit (Skip-Key Resilient) - -**Original design**: Two-phase commit with sequential blocking. - -**Implemented design**: Immediate session commit after encryption. - -``` -1. Load session (from cache or DB) -2. Compute (nextState, header, ciphertext) -3. Save nextState to DB IMMEDIATELY -4. Send transaction -5. On SUCCESS: clean up pending record -6. On FAILURE: ratchet "slot" is burned, receiver handles via skip keys -``` - -**Why this works**: -- The ratchet protocol is designed for message loss -- Receivers handle gaps via skip-key mechanism -- Saving session immediately ensures subsequent messages use the advanced state -- Matches how Signal handles message failures - -### 1.5 Auth-Before-Ratchet (DoS Protection) - -**Attack**: Malicious `pn=999999, n=999999` forces millions of key derivations. - -**Defense**: Verify Ed25519 signature BEFORE any ratchet work. - -``` -1. Parse sig + header + ciphertext -2. Verify Ed25519(sig, header || ct, contact.signingPubKey) -3. IF invalid: reject (O(1) cost) -4. THEN attempt ratchet decrypt -``` - -### 1.6 Binary Encoding -Fixed overhead: ~105 bytes (vs ~200+ for JSON+base64). - -### 1.7 Skipped Keys: Reorg Tolerance, Not Offline Catch-Up - -**Common misconception**: Skipped keys handle offline periods. - -**Reality**: -- **Offline catch-up**: Process chain logs in order โ†’ chain key advances sequentially โ†’ no skipped keys -- **Skipped keys**: Handle block reorgs, out-of-order RPC responses, and failed transactions - -| Concept | Purpose | -|---------|---------| -| Chain key derivation | Sequential catch-up after offline | -| Skipped keys | Out-of-order delivery + tx failure tolerance | - -Bounds: -- `MAX_STORED_SKIPPED_KEYS = 1000` (memory limit) -- `MAX_SKIPPED_KEYS_AGE_MS = 24h` (TTL) - ---- - -## 2. State Loss & Recovery - -### 2.1 The Forward Secrecy Tradeoff - -**Fundamental truth**: Forward secrecy means lost local state = lost messages. - -The ratchet state is: -- **Stateful**: Each message advances the state irreversibly -- **Local-only**: Not stored on-chain or derivable from identity -- **Critical**: Without it, decryption is impossible - -### 2.2 When State Loss Occurs - -| Scenario | What's Lost | Recovery Path | -|----------|-------------|---------------| -| Browser IndexedDB cleared | Everything | Re-handshake all contacts | -| New device, same identity | Everything | Re-handshake all contacts | -| Corrupted database | Depends | Re-handshake affected contacts | -| Export then Import | Nothing | Seamless (ratchet state preserved) | - -### 2.3 Recovery: Just Re-Handshake - -No special "reset protocol" needed. The existing handshake flow handles recovery: - -``` -Alice (lost state) โ†’ sendHandshake(bob) โ†’ Bob accepts โ†’ New session -``` - -- New ephemeral keys generate new salt โ†’ new topics -- Old ratchet session orphaned in Bob's DB (harmless) -- Both parties continue with fresh session - -**UX implication**: Alice must manually re-initiate contact with each peer. This is acceptable; cloud sync (future) would eliminate this friction. - ---- - -# DH-Synchronized Topic Ratcheting - -Static topics enable long-term correlation of conversations by on-chain observers. Even with encrypted content, the repeated `topic` parameter in `MessageSent` events creates a linkable pattern. - -## Solution: DH-Synchronized Topic Ratcheting - -Derive new topics whenever a DH ratchet step occurs. The DH public key in message headers provides natural synchronizationโ€”both parties know when to rotate topics without additional coordination. - -## Key Insight - -The existing Double Ratchet already: -- Generates new DH keypairs on each turn (in `dhRatchetStep()`) -- Tracks `dhMyPublicKey` and `dhTheirPublicKey` -- Triggers on first message after receiving a new DH public key - -**Topic epochs = DH epochs.** When `dhTheirPublicKey` changes, derive new topics. - ---- - -## Topic Transition Window (5 minutes) โ€” NOT a Wait Time - -The transition window is a **grace period**, not a delay. Messages flow instantly with zero UX impact. - -**What it means:** -- After a DH ratchet step, we listen on BOTH the old topic AND the new topic for 5 minutes -- Messages sent/received immediately on the new topic -- Old topic acceptance handles edge cases only - -**Why it's needed:** -1. **In-flight messages** โ€” A message encrypted before rotation may arrive after rotation -2. **Timing skew** โ€” Parties don't ratchet at the exact same millisecond -3. **Block propagation** โ€” On-chain message may be mined slightly out of order - -**Example timeline:** -``` -t=0:00 Alice sends msg#5, triggers DH ratchet โ†’ new topic T2 -t=0:01 Alice sends msg#6 on T2 โœ“ -t=0:03 Bob receives msg#5, triggers his DH ratchet โ†’ derives same T2 -t=0:04 Bob receives msg#6 on T2 โœ“ -t=0:05 Bob sends reply on T2 โœ“ -``` - -No waiting. The window just ensures we don't drop the rare out-of-order message. - ---- - -# Part 1: SDK Changes (`packages/sdk/`) - -## 1.1 Add `deriveTopicFromDH()` in `kdf.ts` - -```typescript -// packages/sdk/src/ratchet/kdf.ts - -import { keccak256 } from 'ethers'; - -/** - * Derive topic from DH shared secret. - * Called after each DH ratchet step. - */ -export function deriveTopicFromDH( - dhSharedSecret: Uint8Array, - direction: 'outbound' | 'inbound', - salt: Uint8Array // conversationId bytes -): `0x${string}` { - const info = `verbeth:topic-${direction}:v2`; - const okm = hkdf(sha256, dhSharedSecret, salt, info, 32); - return keccak256(okm) as `0x${string}`; -} -``` - ---- - -## 1.2 Extend `RatchetSession` in `types.ts` - -```typescript -// packages/sdk/src/ratchet/types.ts - -export const TOPIC_TRANSITION_WINDOW_MS = 5 * 60 * 1000; - -export interface RatchetSession { - // ... existing fields ... - - // === Topic Ratcheting === - /** Current outbound topic (ratcheted) */ - currentTopicOutbound: `0x${string}`; - /** Current inbound topic (ratcheted) */ - currentTopicInbound: `0x${string}`; - - /** Previous inbound topic (grace period) */ - previousTopicInbound?: `0x${string}`; - /** When to stop accepting on previous topic */ - previousTopicExpiry?: number; - - /** Topic epoch (increments with DH steps) */ - topicEpoch: number; -} -``` - ---- - -## 1.3 Update `initSessionAsResponder()` in `session.ts` - -```typescript -// packages/sdk/src/ratchet/session.ts - -export function initSessionAsResponder(params: InitResponderParams): RatchetSession { - // ... existing DH and chain key derivation ... - - return { - // ... existing fields ... - - // Epoch 0: use handshake-derived topics - currentTopicOutbound: topicOutbound, - currentTopicInbound: topicInbound, - previousTopicInbound: undefined, - previousTopicExpiry: undefined, - topicEpoch: 0, - }; -} -``` - ---- - -## 1.4 Update `initSessionAsInitiator()` in `session.ts` - -```typescript -// packages/sdk/src/ratchet/session.ts - -export function initSessionAsInitiator(params: InitInitiatorParams): RatchetSession { - // ... existing DH ratchet step (generates myDHKeyPair, computes dhSend) ... - - // Derive first ratcheted topics from dhSend - const saltBytes = getBytes(computeConversationId(topicOutbound, topicInbound)); - const ratchetedTopicOut = deriveTopicFromDH(dhSend, 'outbound', saltBytes); - const ratchetedTopicIn = deriveTopicFromDH(dhSend, 'inbound', saltBytes); - - return { - // ... existing fields ... - - // Epoch 1: initiator already did first DH step - currentTopicOutbound: ratchetedTopicOut, - currentTopicInbound: ratchetedTopicIn, - previousTopicInbound: topicInbound, - previousTopicExpiry: Date.now() + TOPIC_TRANSITION_WINDOW_MS, - topicEpoch: 1, - }; -} -``` - ---- - -## 1.5 Update `dhRatchetStep()` in `decrypt.ts` - -```typescript -// packages/sdk/src/ratchet/decrypt.ts - -function dhRatchetStep(session: RatchetSession, theirNewDHPub: Uint8Array): RatchetSession { - // ... existing: compute dhReceive, rootKey1, receivingChainKey ... - // ... existing: generate newDHKeyPair ... - // ... existing: compute dhSend, rootKey2, sendingChainKey ... - - // NEW: Derive ratcheted topics from dhSend - const saltBytes = getBytes(session.conversationId); - const newTopicOut = deriveTopicFromDH(dhSend, 'outbound', saltBytes); - const newTopicIn = deriveTopicFromDH(dhSend, 'inbound', saltBytes); - - return { - ...session, - rootKey: rootKey2, - dhMySecretKey: newDHKeyPair.secretKey, - dhMyPublicKey: newDHKeyPair.publicKey, - dhTheirPublicKey: theirNewDHPub, - receivingChainKey, - receivingMsgNumber: 0, - sendingChainKey, - sendingMsgNumber: 0, - previousChainLength: session.sendingMsgNumber, - - // Topic ratcheting - currentTopicOutbound: newTopicOut, - currentTopicInbound: newTopicIn, - previousTopicInbound: session.currentTopicInbound, - previousTopicExpiry: Date.now() + TOPIC_TRANSITION_WINDOW_MS, - topicEpoch: session.topicEpoch + 1, - }; -} -``` - ---- - -## 1.6 Add `matchesSessionTopic()` helper in `decrypt.ts` - -```typescript -// packages/sdk/src/ratchet/decrypt.ts - -/** - * Check if topic matches this session. - * Returns match type or null. - */ -export function matchesSessionTopic( - session: RatchetSession, - topic: `0x${string}` -): 'current' | 'previous' | null { - const t = topic.toLowerCase(); - - if (session.currentTopicInbound.toLowerCase() === t) { - return 'current'; - } - - if ( - session.previousTopicInbound?.toLowerCase() === t && - session.previousTopicExpiry && - Date.now() < session.previousTopicExpiry - ) { - return 'previous'; - } - - return null; -} -``` - ---- - -## 1.7 Update `ratchetEncrypt()` in `encrypt.ts` - -```typescript -// packages/sdk/src/ratchet/encrypt.ts - -export interface EncryptResult { - session: RatchetSession; - header: MessageHeader; - ciphertext: Uint8Array; - signature: Uint8Array; - topic: `0x${string}`; // NEW -} - -export function ratchetEncrypt( - session: RatchetSession, - plaintext: Uint8Array, - signingSecretKey: Uint8Array -): EncryptResult { - // ... existing encryption ... - - return { - session: newSession, - header, - ciphertext: encryptedPayload, - signature, - topic: session.currentTopicOutbound, // NEW: return current topic - }; -} -``` - ---- - -## 1.8 Export new functions in `index.ts` - -```typescript -// packages/sdk/src/ratchet/index.ts - -export { - // ... existing exports ... - deriveTopicFromDH, - matchesSessionTopic, - TOPIC_TRANSITION_WINDOW_MS, -} from './kdf.js'; -``` - ---- - -# Part 2: App Layer Changes - -## 2.1 Update `StoredRatchetSession` in `types.ts` - -```typescript -// src/types.ts - -export interface StoredRatchetSession { - // ... existing fields ... - - currentTopicOutbound: string; - currentTopicInbound: string; - previousTopicInbound?: string; - previousTopicExpiry?: number; - topicEpoch: number; -} -``` - ---- - -## 2.2 Update serialization in `types.ts` - -```typescript -// src/types.ts - -export function serializeRatchetSession(session: RatchetSession): StoredRatchetSession { - return { - // ... existing ... - currentTopicOutbound: session.currentTopicOutbound, - currentTopicInbound: session.currentTopicInbound, - previousTopicInbound: session.previousTopicInbound, - previousTopicExpiry: session.previousTopicExpiry, - topicEpoch: session.topicEpoch, - }; -} - -export function deserializeRatchetSession(stored: StoredRatchetSession): RatchetSession { - return { - // ... existing ... - currentTopicOutbound: stored.currentTopicOutbound as `0x${string}`, - currentTopicInbound: stored.currentTopicInbound as `0x${string}`, - previousTopicInbound: stored.previousTopicInbound as `0x${string}` | undefined, - previousTopicExpiry: stored.previousTopicExpiry, - topicEpoch: stored.topicEpoch, - }; -} -``` - ---- - -## 2.3 Update `schema.ts` โ€” Add indexes - -```typescript -// src/services/schema.ts - -this.version(2).stores({ - // ... existing ... - ratchetSessions: - "conversationId, topicInbound, topicOutbound, currentTopicInbound, previousTopicInbound, myAddress, contactAddress", -}); -``` - ---- - -## 2.4 Update `RatchetDbService.ts` โ€” Multi-topic lookup - -```typescript -// src/services/RatchetDbService.ts - -/** - * Find session by any active inbound topic (current or previous). - */ -async getRatchetSessionByAnyInboundTopic(topic: string): Promise { - const topicLower = topic.toLowerCase(); - - // Try current topic first - let stored = await this.db.ratchetSessions - .where("currentTopicInbound") - .equals(topicLower) - .first(); - - if (stored) { - return deserializeRatchetSession(stored); - } - - // Try previous topic (check expiry in caller) - stored = await this.db.ratchetSessions - .where("previousTopicInbound") - .equals(topicLower) - .first(); - - if (stored && stored.previousTopicExpiry && Date.now() < stored.previousTopicExpiry) { - return deserializeRatchetSession(stored); - } - - return null; -} - -/** - * Get all active inbound topics for a user (for event filtering). - */ -async getAllActiveInboundTopics(myAddress: string): Promise { - const sessions = await this.db.ratchetSessions - .where("myAddress") - .equals(myAddress.toLowerCase()) - .toArray(); - - const topics: string[] = []; - const now = Date.now(); - - for (const s of sessions) { - topics.push(s.currentTopicInbound); - if (s.previousTopicInbound && s.previousTopicExpiry && now < s.previousTopicExpiry) { - topics.push(s.previousTopicInbound); - } - } - - return [...new Set(topics)]; // dedupe -} -``` - ---- - -## 2.5 Update `EventProcessorService.ts` โ€” Use multi-topic lookup - -```typescript -// src/services/EventProcessorService.ts - -export async function processMessageEvent( - event: ProcessedEvent, - address: string, - emitterAddress: string | undefined, - sessionCache: Map, - onLog: (msg: string) => void -): Promise { - // ... existing setup ... - - const topic = log.topics[2]; - - // UPDATED: Check cache by topic, then fall back to multi-topic DB lookup - let session = sessionCache.get(topic); - - if (!session) { - session = await dbService.getRatchetSessionByAnyInboundTopic(topic) || undefined; - - if (session) { - sessionCache.set(topic, session); - } - } - - if (!session) { - onLog(`โ“ Unknown topic: ${topic.slice(0, 10)}...`); - return null; - } - - // ... rest unchanged (signature verify, decrypt, etc.) ... -} -``` - ---- - -## 2.6 Update `useMessageListener.ts` โ€” Query all active topics - -```typescript -// src/hooks/useMessageListener.ts - -const scanBlockRange = async (fromBlock: number, toBlock: number): Promise => { - // ... existing handshake scanning ... - - // UPDATED: Get ALL active inbound topics for this user - const activeTopics = await dbService.getAllActiveInboundTopics(address); - - if (activeTopics.length > 0) { - // Query each topic (or batch if RPC supports OR filters) - for (const topic of activeTopics) { - const messageFilter = { - address: LOGCHAIN_SINGLETON_ADDR, - topics: [EVENT_SIGNATURES.MessageSent, null, topic], - }; - const inboundLogs = await safeGetLogs(messageFilter, fromBlock, toBlock); - - for (const log of inboundLogs) { - const logKey = `${log.transactionHash}-${log.logIndex}`; - if (!processedLogs.current.has(logKey)) { - processedLogs.current.add(logKey); - allEvents.push({ - logKey, - eventType: "message", - rawLog: log, - blockNumber: log.blockNumber, - timestamp: Date.now(), - }); - } - } - } - } - - // .. existing outbound confirmation scanning (unchanged) ... -}; -``` - ---- - -## 2.7 Update `useMessageQueue.ts` (or equivalent) โ€” Use `EncryptResult.topic` - -```typescript -// In your message queue / sending logic - -const sendMessage = async (session: RatchetSession, plaintext: string) => { - const encryptResult = ratchetEncrypt( - session, - new TextEncoder().encode(plaintext), - identityKeyPair.signingSecretKey - ); - - const payload = packageRatchetPayload( - encryptResult.signature, - encryptResult.header, - encryptResult.ciphertext - ); - - // UPDATED: Use topic from encrypt result, not session.topicOutbound - await executor.sendMessage( - payload, - encryptResult.topic, // โ† ratcheted topic - Date.now(), - nonce - ); - - // Persist updated session - await dbService.saveRatchetSession(encryptResult.session); -}; -``` - ---- - -## 2.8 Update `useChatActions.ts` โ€” No direct changes needed - -The hook delegates to `useMessageQueue` which handles encryption. Ensure `useMessageQueue` passes through the `EncryptResult.topic` as shown above. - ---- - -## 2.9 Update `useMessageProcessor.ts` โ€” No direct changes needed - -The hook calls `processMessageEvent` from `EventProcessorService`, which now handles multi-topic lookup internally. - ---- - -# Implementation Order - -| # | Layer | File(s) | Change | -|---|-------|---------|--------| -| 1 | SDK | `kdf.ts` | Add `deriveTopicFromDH()` | -| 2 | SDK | `types.ts` | Extend `RatchetSession`, add constant | -| 3 | SDK | `session.ts` | Update both `initSession*` functions | -| 4 | SDK | `decrypt.ts` | Update `dhRatchetStep()`, add `matchesSessionTopic()` | -| 5 | SDK | `encrypt.ts` | Return `topic` in `EncryptResult` | -| 6 | SDK | `index.ts` | Export new functions | -| 7 | App | `types.ts` | Update `StoredRatchetSession`, serialization | -| 8 | App | `schema.ts` | Add `currentTopicInbound`, `previousTopicInbound` indexes | -| 9 | App | `RatchetDbService.ts` | Add `getRatchetSessionByAnyInboundTopic()`, `getAllActiveInboundTopics()` | -| 10 | App | `EventProcessorService.ts` | Use multi-topic lookup | -| 11 | App | `useMessageListener.ts` | Query all active topics | -| 12 | App | `useMessageQueue.ts` | Use `EncryptResult.topic` for sending | - ---- - -# Testing Checklist - -- [ ] New session (epoch 0): messages use handshake topics -- [ ] Initiator's first message: uses ratcheted topic (epoch 1) -- [ ] Responder receives on ratcheted topic after their DH step -- [ ] Both parties derive identical topics from same DH output -- [ ] Message on previous topic (within window) decrypts successfully -- [ ] Message on expired previous topic is rejected -- [ ] On-chain: observe topic changes after each conversational turn - ---- - -# Security Notes - -1. **Deterministic** โ€” Both parties derive identical topics from `dhSend` -2. **No extra metadata** โ€” Epoch not transmitted; derived from DH state -3. **Unlinkable** โ€” After first DH step, new topic has no on-chain link to handshake -4. **Grace period** โ€” Prevents message loss without adding latency ---- - -## 4. Future Improvements - -### 4.1 Cloud Sync (Planned) - -**Problem**: Device loss = data loss. - -**Solution**: Encrypted cloud backup of full database state. - -``` -โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” -โ”‚ CLOUD SYNC FLOW โ”‚ -โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค -โ”‚ 1. Derive backup key: HKDF(identitySeed, "verbeth-backup") โ”‚ -โ”‚ 2. Serialize: { contacts, messages, ratchetSessions, ... } โ”‚ -โ”‚ 3. Encrypt: AES-GCM(backupKey, serializedData) โ”‚ -โ”‚ 4. Upload to user's cloud storage (Drive/iCloud/S3) โ”‚ -โ”‚ 5. On new device: download, decrypt, import โ”‚ -โ”‚ 6. Ratchet state restored โ†’ no reset needed โ”‚ -โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ -``` - -**Key properties**: -- Backup key derived from identity โ†’ only owner can decrypt -- Cloud provider never sees plaintext -- Backup includes ratchet state โ†’ seamless device migration -- Optional: encrypted sync on every state change - -**Implementation scope**: Separate feature, not part of core ratchet. - -### 4.2 Topic Ratcheting (Phase 2) - -Periodic topic rotation for enhanced metadata privacy. - -### 4.3 Post-Quantum (Phase 3) - -ML-KEM hybrid for quantum resistance. - ---- - -## 5. Success Criteria - -### Cryptographic โœ… -- [x] Identity key compromise never decrypts past messages (including message 0) -- [x] Post-compromise security: session recovers after key compromise -- [x] DoS resistance: unauthenticated messages rejected in O(1) -- [x] Unlinkability: on-chain R โ‰  message DH headers - -### State Management โœ… -- [x] Immediate session commit with skip-key resilience -- [x] Session caching: in-memory cache + DB persistence -- [x] Session keyed by topics (not addresses) -- [x] Confirmation matching by txHash - -### Resilience โœ… -- [x] Long offline periods: process in order, no skipped keys needed -- [x] Skipped keys for reorg tolerance (24h TTL) -- [x] Batch message processing with shared session cache - -### Session Reset โณ DEFERRED (handled implicitly by existing handshake) -- [x] New handshake to existing contact creates fresh session -- [x] Old session orphaned (no functional impact) -- [ ] *(Nice-to-have)* Detect missing sessions on startup -- [ ] *(Nice-to-have)* UI hint for "existing contact requests new session" -- [ ] *(Nice-to-have)* Cleanup orphaned sessions - ---- - -## 6. What's NOT in Scope - -| Feature | Phase | -|---------|-------| -| Topic ratcheting | Phase 2 | -| Post-quantum (ML-KEM) | Phase 3 | -| Cloud sync | Future | -| Export/import encryption | Future (current export is plaintext JSON) | \ No newline at end of file diff --git a/verbeth-client-plan.md b/verbeth-client-plan.md new file mode 100644 index 0000000..b92f58f --- /dev/null +++ b/verbeth-client-plan.md @@ -0,0 +1,1236 @@ +# VerbethClient SDK Improvements: Implementation Guide + +## Executive Summary + +This document provides concrete implementation details for the VerbethClient improvement plan. The changes centralize session management into the SDK while allowing apps to provide their own storage adapters. + +--- + +## Current Pain Points (from codebase analysis) + +| Problem | Where it occurs | +|---------|-----------------| +| Session lookup logic duplicated | `RatchetDbService.getRatchetSessionByAnyInboundTopic()`, `EventProcessorService.processMessageEvent()` | +| Two-phase commit scattered | `useMessageQueue.ts` lines 139-254 | +| Session cache managed by app | `useMessageQueue.ts` line 77-78, `EventProcessorService.ts` line 539-569 | +| Pending outbound tracking manual | `useMessageQueue.ts` lines 170-182 | +| Topic promotion duplicated | `EventProcessorService.ts` lines 543-569 | + +--- + +## Milestone 1: Session Store Interface + Encrypt/Decrypt Helpers + +### 1.1 New SDK Types + +**File: `packages/sdk/src/client/types.ts`** + +```typescript +import { RatchetSession, MessageHeader, EncryptResult } from '../ratchet/types.js'; + +/** + * Storage interface for ratchet sessions. + * Implement this to connect VerbethClient to your storage layer. + */ +export interface SessionStore { + /** + * Get session by conversation ID (primary key). + */ + get(conversationId: string): Promise; + + /** + * Find session by any active inbound topic. + * Must check: currentTopicInbound, nextTopicInbound, previousTopicInbound (if not expired). + */ + getByInboundTopic(topic: string): Promise; + + /** + * Persist session state. + * Called after encrypt (immediate commit) and after decrypt. + */ + save(session: RatchetSession): Promise; +} + +/** + * Result of prepareMessage - contains everything needed to send and commit. + */ +export interface PreparedMessage { + /** Unique ID for this prepared message */ + id: string; + /** Conversation this message belongs to */ + conversationId: string; + /** Topic to publish to (may be ratcheted) */ + topic: `0x${string}`; + /** Binary payload ready for on-chain submission */ + payload: Uint8Array; + /** Original plaintext (for UI/storage) */ + plaintext: string; + /** Session state BEFORE encryption (for rollback if needed) */ + sessionBefore: RatchetSession; + /** Session state AFTER encryption (to persist on commit) */ + sessionAfter: RatchetSession; + /** Message number in the sending chain */ + messageNumber: number; + /** Timestamp when prepared */ + createdAt: number; +} + +/** + * Result of decryptMessage. + */ +export interface DecryptedMessage { + /** Conversation ID */ + conversationId: string; + /** Decrypted plaintext */ + plaintext: string; + /** Whether this was our own message (echo) */ + isOwnMessage: boolean; + /** Updated session state (must be persisted) */ + session: RatchetSession; + /** Topic the message arrived on */ + topic: string; + /** Which topic matched: 'current', 'next', or 'previous' */ + topicMatch: 'current' | 'next' | 'previous'; +} +``` + +### 1.2 Session Manager (Internal) + +**File: `packages/sdk/src/client/SessionManager.ts`** + +```typescript +import { RatchetSession, TOPIC_TRANSITION_WINDOW_MS } from '../ratchet/types.js'; +import { SessionStore } from './types.js'; + +/** + * Internal session coordinator. + * Handles topic matching, session lookup, and topic promotion. + */ +export class SessionManager { + private cache = new Map(); + + constructor(private store: SessionStore) {} + + /** + * Get session by conversation ID, checking cache first. + */ + async getByConversationId(conversationId: string): Promise { + // Check cache first + const cached = this.cache.get(conversationId); + if (cached) return cached; + + // Load from store + const session = await this.store.get(conversationId); + if (session) { + this.cache.set(conversationId, session); + } + return session; + } + + /** + * Find session by inbound topic with automatic topic promotion. + */ + async getByInboundTopic(topic: string): Promise<{ + session: RatchetSession; + topicMatch: 'current' | 'next' | 'previous'; + } | null> { + const topicLower = topic.toLowerCase(); + + // Try store's topic lookup + const session = await this.store.getByInboundTopic(topic); + if (!session) return null; + + // Check cache for more recent state + const cached = this.cache.get(session.conversationId); + let workingSession = cached || session; + + // Determine which topic matched and handle promotion + if (workingSession.currentTopicInbound.toLowerCase() === topicLower) { + return { session: workingSession, topicMatch: 'current' }; + } + + if (workingSession.nextTopicInbound?.toLowerCase() === topicLower) { + // Promote next topics to current + workingSession = this.promoteTopics(workingSession); + this.cache.set(workingSession.conversationId, workingSession); + return { session: workingSession, topicMatch: 'next' }; + } + + if ( + workingSession.previousTopicInbound?.toLowerCase() === topicLower && + workingSession.previousTopicExpiry && + Date.now() < workingSession.previousTopicExpiry + ) { + return { session: workingSession, topicMatch: 'previous' }; + } + + return null; + } + + /** + * Update session in cache and persist to store. + */ + async save(session: RatchetSession): Promise { + this.cache.set(session.conversationId, session); + await this.store.save(session); + } + + /** + * Update cache without persisting (for batch operations). + */ + updateCache(session: RatchetSession): void { + this.cache.set(session.conversationId, session); + } + + /** + * Invalidate cache entry (e.g., on session reset). + */ + invalidate(conversationId: string): void { + this.cache.delete(conversationId); + } + + /** + * Clear entire cache. + */ + clearCache(): void { + this.cache.clear(); + } + + /** + * Promote next topics to current (internal helper). + */ + private promoteTopics(session: RatchetSession): RatchetSession { + if (!session.nextTopicInbound || !session.nextTopicOutbound) { + return session; + } + + return { + ...session, + previousTopicInbound: session.currentTopicInbound, + previousTopicExpiry: Date.now() + TOPIC_TRANSITION_WINDOW_MS, + currentTopicInbound: session.nextTopicInbound, + currentTopicOutbound: session.nextTopicOutbound, + nextTopicInbound: undefined, + nextTopicOutbound: undefined, + topicEpoch: session.topicEpoch + 1, + updatedAt: Date.now(), + }; + } +} +``` + +### 1.3 VerbethClient Extensions + +**File: `packages/sdk/src/client/VerbethClient.ts`** (additions to existing class) + +```typescript +import { hexlify } from 'ethers'; +import { ratchetEncrypt, packageRatchetPayload } from '../ratchet/index.js'; +import { ratchetDecrypt, parseRatchetPayload, isRatchetPayload } from '../ratchet/decrypt.js'; +import { verifyMessageSignature } from '../ratchet/auth.js'; +import { SessionStore, PreparedMessage, DecryptedMessage } from './types.js'; +import { SessionManager } from './SessionManager.js'; + +// Add to VerbethClient class: + +export class VerbethClient { + // ... existing properties ... + + private sessionManager?: SessionManager; + + /** + * Configure session storage. + * Must be called before using prepareMessage/decryptMessage. + */ + setSessionStore(store: SessionStore): void { + this.sessionManager = new SessionManager(store); + } + + /** + * Prepare a message for sending (encrypt without persisting). + * + * Two-phase commit pattern: + * 1. prepareMessage() - encrypts and returns PreparedMessage + * 2. Send transaction using prepared.payload and prepared.topic + * 3. commitMessage() - persists session state after tx confirmation + * + * Session state is committed immediately for forward secrecy. + * If tx fails, the ratchet slot is "burned" (receiver handles via skip keys). + */ + async prepareMessage( + conversationId: string, + plaintext: string + ): Promise { + if (!this.sessionManager) { + throw new Error('SessionStore not configured. Call setSessionStore() first.'); + } + + const session = await this.sessionManager.getByConversationId(conversationId); + if (!session) { + throw new Error(`No session found for conversation: ${conversationId}`); + } + + const plaintextBytes = new TextEncoder().encode(plaintext); + + const encryptResult = ratchetEncrypt( + session, + plaintextBytes, + this.identityKeyPairInstance.signingSecretKey + ); + + const payload = packageRatchetPayload( + encryptResult.signature, + encryptResult.header, + encryptResult.ciphertext + ); + + // Immediately persist session state (forward secrecy) + await this.sessionManager.save(encryptResult.session); + + const prepared: PreparedMessage = { + id: `prep-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`, + conversationId, + topic: encryptResult.topic, + payload, + plaintext, + sessionBefore: session, + sessionAfter: encryptResult.session, + messageNumber: session.sendingMsgNumber, + createdAt: Date.now(), + }; + + return prepared; + } + + /** + * Commit a prepared message after successful tx. + * In the current design, session is already persisted in prepareMessage(). + * This method exists for API symmetry and future extensibility. + */ + async commitMessage(prepared: PreparedMessage): Promise { + // Session already saved in prepareMessage for forward secrecy. + // This method can be used for additional bookkeeping if needed. + } + + /** + * Decrypt an incoming message. + * Handles topic routing, signature verification, and session updates. + * + * @param topic - The topic the message arrived on + * @param payload - Raw message payload (Uint8Array) + * @param senderSigningKey - Sender's Ed25519 signing public key + * @param isOwnMessage - Whether this is our own outbound message (echo) + * @returns DecryptedMessage or null if decryption fails + */ + async decryptMessage( + topic: string, + payload: Uint8Array, + senderSigningKey: Uint8Array, + isOwnMessage: boolean = false + ): Promise { + if (!this.sessionManager) { + throw new Error('SessionStore not configured. Call setSessionStore() first.'); + } + + // Skip decryption for own messages (we already have plaintext) + if (isOwnMessage) { + return null; + } + + // Find session by topic + const result = await this.sessionManager.getByInboundTopic(topic); + if (!result) { + return null; + } + + const { session, topicMatch } = result; + + // Validate payload format + if (!isRatchetPayload(payload)) { + return null; + } + + const parsed = parseRatchetPayload(payload); + if (!parsed) { + return null; + } + + // AUTH-FIRST: Verify signature before any ratchet operations + const sigValid = verifyMessageSignature( + parsed.signature, + parsed.header, + parsed.ciphertext, + senderSigningKey + ); + + if (!sigValid) { + return null; + } + + // Decrypt + const decryptResult = ratchetDecrypt(session, parsed.header, parsed.ciphertext); + if (!decryptResult) { + return null; + } + + // Persist updated session + await this.sessionManager.save(decryptResult.session); + + const plaintextStr = new TextDecoder().decode(decryptResult.plaintext); + + return { + conversationId: session.conversationId, + plaintext: plaintextStr, + isOwnMessage: false, + session: decryptResult.session, + topic, + topicMatch, + }; + } + + /** + * Invalidate session cache for a conversation. + * Call after external session changes (e.g., session reset). + */ + invalidateSessionCache(conversationId: string): void { + this.sessionManager?.invalidate(conversationId); + } + + /** + * Clear all cached sessions. + */ + clearSessionCache(): void { + this.sessionManager?.clearCache(); + } +} +``` + +### 1.4 SDK Index Exports + +**File: `packages/sdk/src/client/index.ts`** + +```typescript +export { VerbethClient } from './VerbethClient.js'; +export type { + SessionStore, + PreparedMessage, + DecryptedMessage +} from './types.js'; +``` + +**Update `packages/sdk/src/index.ts`:** + +```typescript +// ... existing exports ... +export type { SessionStore, PreparedMessage, DecryptedMessage } from './client/index.js'; +``` + +--- + +## Milestone 2: Pending Message Manager + +### 2.1 Pending Store Interface + +**File: `packages/sdk/src/client/types.ts`** (additions) + +```typescript + +export type PendingStatus = 'preparing' | 'submitted' | 'confirmed' | 'failed'; + +/** + * Pending outbound message record. + */ +export interface PendingMessage { + /** Unique ID */ + id: string; + /** Conversation ID */ + conversationId: string; + /** Topic used for sending */ + topic: string; + /** Hex-encoded payload */ + payloadHex: string; + /** Original plaintext */ + plaintext: string; + /** Session state before encryption (serialized JSON) */ + sessionStateBefore: string; + /** Session state after encryption (serialized JSON) */ + sessionStateAfter: string; + /** Creation timestamp */ + createdAt: number; + /** Transaction hash (once submitted) */ + txHash: string | null; + /** Current status */ + status: PendingStatus; +} + +/** + * Storage interface for pending outbound messages. + */ +export interface PendingStore { + /** + * Save a new pending message. + */ + save(pending: PendingMessage): Promise; + + /** + * Get pending message by ID. + */ + get(id: string): Promise; + + /** + * Get pending message by transaction hash. + */ + getByTxHash(txHash: string): Promise; + + /** + * Update pending message status. + */ + updateStatus(id: string, status: PendingStatus, txHash?: string): Promise; + + /** + * Delete pending message (after confirmation or cancellation). + */ + delete(id: string): Promise; + + /** + * Get all pending messages for a conversation. + */ + getByConversation(conversationId: string): Promise; +} + +/** + * Result of sendMessage. + */ +export interface SendResult { + /** Message ID for tracking */ + messageId: string; + /** Transaction hash */ + txHash: string; + /** Topic the message was sent on */ + topic: string; + /** Message number in sending chain */ + messageNumber: number; +} + +/** + * Result of confirmTx. + */ +export interface ConfirmResult { + /** Conversation ID */ + conversationId: string; + /** Original plaintext */ + plaintext: string; + /** Message ID */ + messageId: string; +} +``` + +### 2.2 Pending Manager (Internal) + +**File: `packages/sdk/src/client/PendingManager.ts`** + +```typescript +import { hexlify } from 'ethers'; +import { PendingStore, PendingMessage, PendingStatus } from './types.js'; + +/** + * Internal pending message coordinator. + */ +export class PendingManager { + constructor(private store: PendingStore) {} + + /** + * Create and save a pending message record. + */ + async create(params: Omit): Promise { + const pending: PendingMessage = { + ...params, + txHash: null, + status: 'preparing', + }; + await this.store.save(pending); + return pending; + } + + /** + * Mark as submitted with transaction hash. + */ + async markSubmitted(id: string, txHash: string): Promise { + await this.store.updateStatus(id, 'submitted', txHash); + } + + /** + * Get pending by transaction hash. + */ + async getByTxHash(txHash: string): Promise { + return this.store.getByTxHash(txHash); + } + + /** + * Finalize (confirm) and delete. + */ + async finalize(id: string): Promise { + const pending = await this.store.get(id); + if (!pending) return null; + + await this.store.delete(id); + return pending; + } + + /** + * Mark as failed. + */ + async markFailed(id: string): Promise { + await this.store.updateStatus(id, 'failed'); + } + + /** + * Delete a pending message. + */ + async delete(id: string): Promise { + await this.store.delete(id); + } +} +``` + +### 2.3 VerbethClient Extensions (Milestone 2) + +**Add to `packages/sdk/src/client/VerbethClient.ts`:** + +```typescript +import { PendingStore, PendingMessage, SendResult, ConfirmResult } from './types.js'; +import { PendingManager } from './PendingManager.js'; + +// Add to VerbethClient class: + +export class VerbethClient { + // ... existing properties ... + + private pendingManager?: PendingManager; + + /** + * Configure pending message storage. + * Must be called before using sendMessage/confirmTx/revertTx. + */ + setPendingStore(store: PendingStore): void { + this.pendingManager = new PendingManager(store); + } + + /** + * Send a message with full lifecycle management. + * + * This is the high-level API that handles: + * 1. Encryption + * 2. Pending record creation + * 3. Transaction submission + * 4. Status tracking + * + * After calling this, wait for on-chain confirmation and call confirmTx(). + */ + async sendMessage( + conversationId: string, + plaintext: string + ): Promise { + if (!this.sessionManager) { + throw new Error('SessionStore not configured. Call setSessionStore() first.'); + } + if (!this.pendingManager) { + throw new Error('PendingStore not configured. Call setPendingStore() first.'); + } + if (!this.executorInstance) { + throw new Error('Executor not configured.'); + } + + // 1. Prepare message (encrypts and persists session) + const prepared = await this.prepareMessage(conversationId, plaintext); + + // 2. Create pending record + const pending = await this.pendingManager.create({ + id: prepared.id, + conversationId, + topic: prepared.topic, + payloadHex: hexlify(prepared.payload), + plaintext, + sessionStateBefore: JSON.stringify(this.serializeSession(prepared.sessionBefore)), + sessionStateAfter: JSON.stringify(this.serializeSession(prepared.sessionAfter)), + createdAt: prepared.createdAt, + }); + + // 3. Submit transaction + const timestamp = Math.floor(Date.now() / 1000); + const nonce = prepared.messageNumber; + + try { + const tx = await this.executorInstance.sendMessage( + prepared.payload, + prepared.topic, + timestamp, + BigInt(nonce) + ); + + // 4. Update pending with txHash + await this.pendingManager.markSubmitted(prepared.id, tx.hash); + + return { + messageId: prepared.id, + txHash: tx.hash, + topic: prepared.topic, + messageNumber: nonce, + }; + } catch (error) { + // Mark as failed (ratchet slot is burned) + await this.pendingManager.markFailed(prepared.id); + throw error; + } + } + + /** + * Confirm a transaction after on-chain confirmation. + * Call this when you see your MessageSent event on-chain. + * + * @param txHash - Transaction hash to confirm + * @returns ConfirmResult or null if not found + */ + async confirmTx(txHash: string): Promise { + if (!this.pendingManager) { + throw new Error('PendingStore not configured.'); + } + + const pending = await this.pendingManager.getByTxHash(txHash); + if (!pending || pending.status !== 'submitted') { + return null; + } + + // Finalize (delete pending record) + const finalized = await this.pendingManager.finalize(pending.id); + if (!finalized) { + return null; + } + + return { + conversationId: finalized.conversationId, + plaintext: finalized.plaintext, + messageId: finalized.id, + }; + } + + /** + * Handle transaction failure/revert. + * The ratchet slot is already burned (session was persisted in prepareMessage). + * This just cleans up the pending record. + * + * @param txHash - Transaction hash that failed + */ + async revertTx(txHash: string): Promise { + if (!this.pendingManager) { + throw new Error('PendingStore not configured.'); + } + + const pending = await this.pendingManager.getByTxHash(txHash); + if (pending) { + await this.pendingManager.delete(pending.id); + } + } + + /** + * Serialize session for storage (helper). + * Apps should use their own serialization if needed. + */ + private serializeSession(session: RatchetSession): any { + // Basic serialization - apps can override + return { + conversationId: session.conversationId, + topicEpoch: session.topicEpoch, + sendingMsgNumber: session.sendingMsgNumber, + receivingMsgNumber: session.receivingMsgNumber, + // ... other fields as hex strings + }; + } +} +``` + +### 2.4 Updated SDK Exports + +**Update `packages/sdk/src/client/index.ts`:** + +```typescript +export { VerbethClient } from './VerbethClient.js'; +export type { + SessionStore, + PreparedMessage, + DecryptedMessage, + PendingStore, + PendingMessage, + PendingStatus, + SendResult, + ConfirmResult, +} from './types.js'; +``` + +--- + +## App-Side Adapter Implementation + +these adapters could also be in the same file. + +### SessionStore Adapter + +**File: `apps/demo/src/adapters/SessionStoreAdapter.ts`** + +```typescript +import type { SessionStore } from '@verbeth/sdk'; +import { dbService } from '../services/DbService.js'; + +/** + * Adapter connecting VerbethClient SessionStore to app's DbService. + */ +export function createSessionStore(): SessionStore { + return { + async get(conversationId: string) { + return dbService.getRatchetSessionByConversation(conversationId); + }, + + async getByInboundTopic(topic: string) { + return dbService.getRatchetSessionByAnyInboundTopic(topic); + }, + + async save(session) { + await dbService.saveRatchetSession(session); + }, + }; +} +``` + +### PendingStore Adapter + +**File: `apps/demo/src/adapters/PendingStoreAdapter.ts`** + +```typescript +import type { PendingStore, PendingMessage, PendingStatus } from '@verbeth/sdk'; +import { dbService } from '../services/DbService.js'; + +/** + * Adapter connecting VerbethClient PendingStore to app's DbService. + */ +export function createPendingStore(): PendingStore { + return { + async save(pending: PendingMessage) { + await dbService.savePendingOutbound(pending); + }, + + async get(id: string) { + return dbService.getPendingOutbound(id); + }, + + async getByTxHash(txHash: string) { + return dbService.getPendingOutboundByTxHash(txHash); + }, + + async updateStatus(id: string, status: PendingStatus, txHash?: string) { + await dbService.updatePendingOutboundStatus(id, status, txHash); + }, + + async delete(id: string) { + await dbService.deletePendingOutbound(id); + }, + + async getByConversation(conversationId: string) { + return dbService.getPendingOutboundByConversation(conversationId); + }, + }; +} +``` + +### Updated App.tsx Initialization + +**In `apps/demo/src/App.tsx`:** + +```typescript +import { createSessionStore } from './adapters/SessionStoreAdapter.js'; +import { createPendingStore } from './adapters/PendingStoreAdapter.js'; + +// In the useEffect where VerbethClient is created: +useEffect(() => { + if (executor && identityKeyPair && identityProof && identitySigner && currentAddress) { + const client = new VerbethClient({ + userAddress: currentAddress, + identityKeyPair, + identityProof, + executor, + signer: identitySigner, + }); + + // Configure storage adapters + client.setSessionStore(createSessionStore()); + client.setPendingStore(createPendingStore()); + + setVerbethClient(client); + } +}, [executor, identityKeyPair, identityProof, identitySigner, address]); +``` + +--- + +## Simplified useMessageQueue (After Milestones 1 & 2) + +**File: `apps/demo/src/hooks/useMessageQueue.ts`** (refactored) + +```typescript +import { useCallback, useRef, useEffect } from "react"; +import { VerbethClient } from "@verbeth/sdk"; +import { Contact, Message, generateTempMessageId } from "../types.js"; + +interface UseMessageQueueProps { + verbethClient: VerbethClient | null; + addLog: (message: string) => void; + addMessage: (message: Message) => Promise; + updateMessageStatus: (id: string, status: Message["status"], error?: string) => Promise; + removeMessage: (id: string) => Promise; + updateContact: (contact: Contact) => Promise; +} + +export interface QueuedMessage { + id: string; + conversationId: string; + contact: Contact; + plaintext: string; + status: 'queued' | 'sending' | 'pending' | 'confirmed' | 'failed'; + error?: string; + txHash?: string; + createdAt: number; +} + +interface ConversationQueue { + messages: QueuedMessage[]; + isProcessing: boolean; +} + +export const useMessageQueue = ({ + verbethClient, + addLog, + addMessage, + updateMessageStatus, + removeMessage, + updateContact, +}: UseMessageQueueProps) => { + const queuesRef = useRef>(new Map()); + const failedMessagesRef = useRef>(new Map()); + const mountedRef = useRef(true); + + useEffect(() => { + mountedRef.current = true; + return () => { mountedRef.current = false; }; + }, []); + + const processQueue = useCallback(async (conversationId: string) => { + if (!verbethClient || !mountedRef.current) return; + + const queue = queuesRef.current.get(conversationId); + if (!queue || queue.isProcessing || queue.messages.length === 0) return; + + queue.isProcessing = true; + + while (queue.messages.length > 0 && mountedRef.current) { + const message = queue.messages[0]; + + if (message.status === 'confirmed' || message.status === 'pending') { + queue.messages.shift(); + continue; + } + + if (message.status === 'failed') { + queue.messages.shift(); + continue; + } + + try { + message.status = 'sending'; + + // ===================================================================== + // SDK handles everything: encryption, session persistence, pending tracking + // ===================================================================== + const result = await verbethClient.sendMessage( + conversationId, + message.plaintext + ); + + message.id = result.messageId; + message.txHash = result.txHash; + message.status = 'pending'; + + addLog(`๐Ÿ“ค Message sent: "${message.plaintext.slice(0, 30)}..." (tx: ${result.txHash.slice(0, 10)}..., n=${result.messageNumber})`); + + // Update contact with current topic + const updatedContact: Contact = { + ...message.contact, + lastMessage: message.plaintext, + lastTimestamp: Date.now(), + }; + await updateContact(updatedContact); + + queue.messages.shift(); + + } catch (error) { + const errorMessage = error instanceof Error ? error.message : 'Unknown error'; + + message.status = 'failed'; + message.error = errorMessage; + + await updateMessageStatus(message.id, 'failed', errorMessage); + addLog(`โœ— Failed to send: "${message.plaintext.slice(0, 20)}..." - ${errorMessage}`); + + failedMessagesRef.current.set(message.id, { ...message }); + queue.messages.shift(); + } + } + + queue.isProcessing = false; + }, [verbethClient, addLog, updateContact, updateMessageStatus]); + + const queueMessage = useCallback(async ( + contact: Contact, + messageText: string + ): Promise => { + if (!verbethClient || !contact.conversationId) { + addLog('โœ— Cannot queue message: missing client or conversation'); + return null; + } + + const messageId = generateTempMessageId(); + const conversationId = contact.conversationId; + + const queuedMessage: QueuedMessage = { + id: messageId, + conversationId, + contact, + plaintext: messageText, + status: 'queued', + createdAt: Date.now(), + }; + + let queue = queuesRef.current.get(conversationId); + if (!queue) { + queue = { messages: [], isProcessing: false }; + queuesRef.current.set(conversationId, queue); + } + queue.messages.push(queuedMessage); + + // Optimistic UI + const optimisticMessage: Message = { + id: messageId, + topic: contact.topicOutbound || '', + sender: verbethClient.userAddress, + recipient: contact.address, + ciphertext: '', + timestamp: Date.now(), + blockTimestamp: Date.now(), + blockNumber: 0, + direction: 'outgoing', + decrypted: messageText, + read: true, + nonce: 0, + dedupKey: `pending-${messageId}`, + type: 'text', + ownerAddress: verbethClient.userAddress, + status: 'pending', + }; + + await addMessage(optimisticMessage); + addLog(`๐Ÿ“ Message queued: "${messageText.slice(0, 30)}..."`); + + setTimeout(() => processQueue(conversationId), 0); + return messageId; + }, [verbethClient, addLog, addMessage, processQueue]); + + // ... retryMessage, cancelMessage, getQueueStatus remain largely the same ... + + return { + queueMessage, + retryMessage: useCallback(async (id: string) => { /* ... */ }, []), + cancelMessage: useCallback(async (id: string) => { /* ... */ }, []), + getQueueStatus: useCallback((convId: string) => { /* ... */ }, []), + invalidateSessionCache: useCallback((convId: string) => { + verbethClient?.invalidateSessionCache(convId); + }, [verbethClient]), + clearAllQueues: useCallback(() => { + queuesRef.current.clear(); + failedMessagesRef.current.clear(); + verbethClient?.clearSessionCache(); + }, [verbethClient]), + }; +}; +``` + +--- + +## Simplified EventProcessorService (After Milestone 1) + +**In `apps/demo/src/services/EventProcessorService.ts`:** + +The `processMessageEvent` function becomes simpler: + +```typescript +export async function processMessageEvent( + event: ProcessedEvent, + address: string, + emitterAddress: string | undefined, + verbethClient: VerbethClient, // Now we pass the client + onLog: (msg: string) => void +): Promise { + try { + const log = event.rawLog; + const abiCoder = new AbiCoder(); + const [ciphertextBytes, timestamp, topic, nonce] = abiCoder.decode( + ['bytes', 'uint256', 'bytes32', 'uint256'], + log.data + ); + + const sender = '0x' + log.topics[1].slice(-40); + const ciphertextRaw = hexToUint8Array(ciphertextBytes); + + const isOurMessage = + sender.toLowerCase() === address.toLowerCase() || + (emitterAddress && sender.toLowerCase() === emitterAddress.toLowerCase()); + + // ========================================================================= + // OUTGOING CONFIRMATION - Use SDK's confirmTx + // ========================================================================= + if (isOurMessage) { + const confirmed = await verbethClient.confirmTx(log.transactionHash); + if (confirmed) { + onLog(`โœ… Message confirmed: "${confirmed.plaintext.slice(0, 30)}..."`); + return { + messageUpdate: [confirmed.messageId, { status: 'confirmed' }], + }; + } + return null; + } + + // ========================================================================= + // INCOMING MESSAGE - Use SDK's decryptMessage + // ========================================================================= + + // Get contact for signing key + const contact = await dbService.getContactByTopic(topic, address); + if (!contact?.signingPubKey) { + onLog(`โ“ No contact found for topic ${topic.slice(0, 10)}...`); + return null; + } + + const decrypted = await verbethClient.decryptMessage( + topic, + ciphertextRaw, + contact.signingPubKey, + isOurMessage + ); + + if (!decrypted) { + onLog(`โœ— Failed to decrypt message from ${sender.slice(0, 8)}...`); + return null; + } + + const message: Message = { + id: generateMessageId(log.transactionHash, log), + topic, + sender: contact.address, + recipient: address, + ciphertext: hexlify(ciphertextRaw), + timestamp: Number(timestamp) * 1000, + blockTimestamp: Date.now(), + blockNumber: log.blockNumber, + direction: 'incoming', + decrypted: decrypted.plaintext, + read: false, + nonce: Number(nonce), + dedupKey: `msg-${log.transactionHash}-${log.logIndex}`, + type: 'text', + ownerAddress: address, + status: 'confirmed', + }; + + // Update contact topics if they changed + const updatedContact: Contact = { + ...contact, + topicInbound: decrypted.session.currentTopicInbound, + topicOutbound: decrypted.session.currentTopicOutbound, + lastMessage: decrypted.plaintext, + lastTimestamp: Date.now(), + }; + + await dbService.saveMessage(message); + await dbService.saveContact(updatedContact); + + onLog(`๐Ÿ“ฉ Message from ${contact.address.slice(0, 8)}...: "${decrypted.plaintext}"`); + + return { newMessage: message, contactUpdate: updatedContact }; + } catch (error) { + onLog(`โœ— Failed to process message: ${error}`); + return null; + } +} +``` + +--- + +## Migration Guide + +All changes are additive. Existing code continues to work. However, we must now prune old code no longer needed (like duplexTopics). + +### Recommended Migration Path + +1. **Add adapters** to your app (SessionStoreAdapter, PendingStoreAdapter) +2. **Configure VerbethClient** with `setSessionStore()` and `setPendingStore()` after creation +3. **Gradually replace** direct session/pending operations with SDK methods: + - Replace manual `ratchetEncrypt` + session save โ†’ `client.prepareMessage()` + - Replace pending record creation โ†’ already handled by `client.sendMessage()` + - Replace manual decryption flow โ†’ `client.decryptMessage()` + - Replace confirmation matching โ†’ `client.confirmTx()` + +4. **Remove** duplicated logic: + - Session cache in hooks (SDK manages internally) + - Topic promotion logic (SDK handles in `getByInboundTopic`) + + +--- + +## Milestone 3: Event Processor Helpers + +### Goal +Simplify event processing loops. + +```ts +interface ProcessedIncomingMessage { + conversationId: string; + plaintext: string; + sender: string; + topic: string; + isOwnMessage: boolean; +} +``` + +```ts +class VerbethClient { + async processMessageEvent(event: { + topic: string; + payload: Uint8Array; + txHash: string; + sender?: string; + }): Promise; + + async processMessageEvents(events: Array): Promise; +} +``` + +--- + +## App-Side Example + +```ts +const sessionStore: SessionStore = { + get: (id) => dbService.getRatchetSessionByConversation(id), + getByInboundTopic: (topic) => + dbService.getRatchetSessionByAnyInboundTopic(topic), + save: (session) => dbService.saveRatchetSession(session), +}; + +verbethClient.setSessionStore(sessionStore); +``` From 529544b88f31c2a79fdf1af058ef4ba1c0a5cffa Mon Sep 17 00:00:00 2001 From: Marco Esposito Date: Sat, 17 Jan 2026 11:20:15 +0100 Subject: [PATCH 15/51] wip remove duplex topics --- apps/demo/src/App.tsx | 4 +- apps/demo/src/hooks/useChatActions.ts | 19 +- apps/demo/src/hooks/useMessageQueue(old).ts | 488 ------ .../services/EventProcessorService(old).ts | 718 -------- .../src/services/EventProcessorService.ts | 39 +- apps/docs/topic-ratcheting.md | 10 + packages/sdk/src/client/VerbethClient.ts | 64 +- packages/sdk/src/client/types.ts | 5 +- packages/sdk/src/crypto.ts | 133 +- packages/sdk/src/index.ts | 6 +- packages/sdk/src/payload.ts | 49 +- packages/sdk/src/send.ts | 34 +- packages/sdk/src/types.ts | 16 - packages/sdk/src/utils.ts | 15 +- packages/sdk/src/verify.ts | 63 +- packages/sdk/test/crypto.test.ts | 1508 ++++++++--------- packages/sdk/test/utils.test.ts | 216 +-- packages/sdk/test/verify.test.ts | 696 ++++---- plan(done).md | 241 --- 19 files changed, 1380 insertions(+), 2944 deletions(-) delete mode 100644 apps/demo/src/hooks/useMessageQueue(old).ts delete mode 100644 apps/demo/src/services/EventProcessorService(old).ts delete mode 100644 plan(done).md diff --git a/apps/demo/src/App.tsx b/apps/demo/src/App.tsx index e29378f..a6c2a5f 100644 --- a/apps/demo/src/App.tsx +++ b/apps/demo/src/App.tsx @@ -369,10 +369,10 @@ export default function App() { {/* LEFT: title */}

- World Post + Verbeth

- powered by Verbeth + powered by the world computer
{/* RIGHT: auth buttons - EOA only */} diff --git a/apps/demo/src/hooks/useChatActions.ts b/apps/demo/src/hooks/useChatActions.ts index f4f7fe3..0326dac 100644 --- a/apps/demo/src/hooks/useChatActions.ts +++ b/apps/demo/src/hooks/useChatActions.ts @@ -1,4 +1,5 @@ // src/hooks/useChatActions.ts +// CLEANED VERSION - pickOutboundTopic removed, topics come directly from SDK /** * Chat Actions Hook. @@ -8,12 +9,15 @@ * - sendMessageToContact * - Retry/cancel failed messages * - Queue status management + * + * CHANGE: acceptHandshake now receives topics directly from VerbethClient + * instead of using pickOutboundTopic on duplexTopics. */ import { useCallback } from "react"; import { hexlify } from "ethers"; import { - pickOutboundTopic, + // REMOVED: pickOutboundTopic - no longer needed VerbethClient, initSessionAsResponder, } from "@verbeth/sdk"; @@ -159,6 +163,8 @@ export const useChatActions = ({ /** * Accept a handshake from another user. * Creates ratchet session and establishes contact. + * + * UPDATED: Now receives topicOutbound/topicInbound directly from SDK */ const acceptHandshake = useCallback( async (handshake: any, responseMessage: string) => { @@ -170,7 +176,9 @@ export const useChatActions = ({ try { const { tx, - duplexTopics, + // CHANGED: Now receive topics directly instead of duplexTopics + topicOutbound, + topicInbound, responderEphemeralSecret, responderEphemeralPublic, } = await verbethClient.acceptHandshake( @@ -179,8 +187,11 @@ export const useChatActions = ({ responseMessage ); - const topicOutbound = pickOutboundTopic(false, duplexTopics); - const topicInbound = pickOutboundTopic(true, duplexTopics); + // REMOVED: Topic selection via pickOutboundTopic + // const topicOutbound = pickOutboundTopic(false, duplexTopics); + // const topicInbound = pickOutboundTopic(true, duplexTopics); + + // Topics now come directly from the SDK const ratchetSession = initSessionAsResponder({ myAddress: verbethClient.userAddress, diff --git a/apps/demo/src/hooks/useMessageQueue(old).ts b/apps/demo/src/hooks/useMessageQueue(old).ts deleted file mode 100644 index 8a72ac8..0000000 --- a/apps/demo/src/hooks/useMessageQueue(old).ts +++ /dev/null @@ -1,488 +0,0 @@ -// src/hooks/useMessageQueue.ts - -/** - * Message Queue Hook for Sequential Processing with Optimistic UI. - * - * 1. Session state is cached per conversation and persists across processQueue calls - * 2. After encryption, session state is immediately saved to DB (not waiting for confirmation) - * 3. Failed messages don't corrupt session state - the ratchet slot is "burned" - * 4. Confirmations now just clean up pending records, not commit session state - * - */ - -import { useCallback, useRef, useEffect } from "react"; -import { hexlify } from "ethers"; -import { - VerbethClient, - ratchetEncrypt, - packageRatchetPayload, - RatchetSession, -} from "@verbeth/sdk"; -import { dbService } from "../services/DbService.js"; -import { - Contact, - Message, - PendingOutbound, - generateTempMessageId, - serializeRatchetSession, -} from "../types.js"; - - -export type QueuedMessageStatus = - | "queued" - | "sending" - | "pending" - | "confirmed" - | "failed"; - -export interface QueuedMessage { - id: string; - conversationId: string; - contact: Contact; - plaintext: string; - status: QueuedMessageStatus; - error?: string; - txHash?: string; - createdAt: number; -} - -interface ConversationQueue { - messages: QueuedMessage[]; - isProcessing: boolean; -} - -interface UseMessageQueueProps { - verbethClient: VerbethClient | null; - addLog: (message: string) => void; - addMessage: (message: Message) => Promise; - updateMessageStatus: (id: string, status: Message["status"], error?: string) => Promise; - removeMessage: (id: string) => Promise; - updateContact: (contact: Contact) => Promise; -} - - -export const useMessageQueue = ({ - verbethClient, - addLog, - addMessage, - updateMessageStatus, - removeMessage, - updateContact, -}: UseMessageQueueProps) => { - - const queuesRef = useRef>(new Map()); - - // persistent session cache across processQueue invocations - // This ensures we never lose track of the latest session state - const sessionCacheRef = useRef>(new Map()); - - const failedMessagesRef = useRef>(new Map()); - // Track mounted state to prevent updates after unmount - const mountedRef = useRef(true); - - useEffect(() => { - mountedRef.current = true; - return () => { - mountedRef.current = false; - }; - }, []); - - // =========================================================================== - // Queue Processor - // =========================================================================== - - const processQueue = useCallback(async (conversationId: string) => { - if (!verbethClient || !mountedRef.current) return; - - const queue = queuesRef.current.get(conversationId); - if (!queue || queue.isProcessing || queue.messages.length === 0) return; - - queue.isProcessing = true; - - // Check session cache first, only fall back to DB if not cached - // This ensures we always use the most recently advanced session state - let currentSession: RatchetSession | null = sessionCacheRef.current.get(conversationId) ?? null; - - if (!currentSession) { - try { - currentSession = await dbService.getRatchetSessionByConversation(conversationId); - if (currentSession) { - sessionCacheRef.current.set(conversationId, currentSession); - addLog(`๐Ÿ“‚ Loaded session from DB for ${conversationId.slice(0, 10)}...`); - } - } catch (error) { - addLog(`โœ— Failed to load ratchet session for ${conversationId.slice(0, 10)}...`); - queue.isProcessing = false; - return; - } - } - - if (!currentSession) { - addLog(`โœ— No ratchet session found for ${conversationId.slice(0, 10)}...`); - queue.isProcessing = false; - return; - } - - while (queue.messages.length > 0 && mountedRef.current) { - const message = queue.messages[0]; - - if (message.status === "confirmed" || message.status === "pending") { - queue.messages.shift(); - continue; - } - - if (message.status === "failed") { - queue.messages.shift(); - continue; - } - - try { - message.status = "sending"; - - // use the cached in-memory session state - const sessionBefore = currentSession; - - const plaintext = new TextEncoder().encode(message.plaintext); - - // ratchetEncrypt now returns topic in the result (ratcheted topic) - const encryptResult = ratchetEncrypt( - sessionBefore, - plaintext, - verbethClient.identityKeyPairInstance.signingSecretKey - ); - - const { session: nextSession, header, ciphertext, signature, topic: ratchetedTopic } = encryptResult; - - // ===================================================================== - // Update both in-memory cache and DB immediately after encryption - // I.e., we commit the session state before sending the tx - // ===================================================================== - currentSession = nextSession; - sessionCacheRef.current.set(conversationId, nextSession); - - await dbService.saveRatchetSession(nextSession); - addLog(`๐Ÿ’พ Session state committed (sendingMsgNumber=${nextSession.sendingMsgNumber}, topicEpoch=${nextSession.topicEpoch})`); - - const payload = packageRatchetPayload(signature, header, ciphertext); - const payloadHex = hexlify(payload); - - // Create pending record for confirmation matching - const pending: PendingOutbound = { - id: message.id, - conversationId, - topic: ratchetedTopic, // Use ratcheted topic from EncryptResult - payloadHex, - plaintext: message.plaintext, - sessionStateBefore: JSON.stringify(serializeRatchetSession(sessionBefore)), - sessionStateAfter: JSON.stringify(serializeRatchetSession(nextSession)), - createdAt: message.createdAt, - txHash: null, - status: "preparing", - }; - await dbService.savePendingOutbound(pending); - - // Send transaction - const timestamp = Math.floor(Date.now() / 1000); - const nonce = nextSession.sendingMsgNumber - 1; - - await dbService.updatePendingOutboundStatus(message.id, "submitted"); - - const tx = await verbethClient.executorInstance.sendMessage( - payload, - ratchetedTopic, - timestamp, - BigInt(nonce) - ); - - // Update with txHash - message.txHash = tx.hash; - message.status = "pending"; - await dbService.updatePendingOutboundStatus(message.id, "submitted", tx.hash); - - addLog(`๐Ÿ“ค Message sent: "${message.plaintext.slice(0, 30)}..." (tx: ${tx.hash.slice(0, 10)}..., n=${nonce})`); - - // Update contact with current topic - const updatedContact: Contact = { - ...message.contact, - topicOutbound: nextSession.currentTopicOutbound, - topicInbound: nextSession.currentTopicInbound, - lastMessage: message.plaintext, - lastTimestamp: Date.now(), - }; - await updateContact(updatedContact); - - // Remove from queue (confirmation will be handled by useMessageProcessor) - queue.messages.shift(); - - } catch (error) { - const errorMessage = error instanceof Error ? error.message : "Unknown error"; - - // Mark as failed - message.status = "failed"; - message.error = errorMessage; - - // ===================================================================== - // On failure, we do not roll back session state - // Instead, we let the slot be skipped, and the receiver will - // handle this via their skip-key mechanism. - // - // This is intentional and matches Signal's behavior. - // ===================================================================== - - - try { - await dbService.deletePendingOutbound(message.id); - } catch { - } - - await updateMessageStatus(message.id, "failed", errorMessage); - - addLog(`โœ— Failed to send (slot burned): "${message.plaintext.slice(0, 20)}..." - ${errorMessage}`); - - // Store failed message for retry/cancel - failedMessagesRef.current.set(message.id, { ...message }); - - // Remove from active queue - queue.messages.shift(); - - // Continue processing remaining messages with the advanced session state - // (currentSession is already updated, which is correct) - } - } - - queue.isProcessing = false; - }, [verbethClient, addLog, updateContact, updateMessageStatus]); - - // =========================================================================== - // Public API - // =========================================================================== - - /** - * Queue a message for sending. - * Shows optimistically in UI immediately, processes sequentially. - */ - const queueMessage = useCallback(async ( - contact: Contact, - messageText: string - ): Promise => { - if (!verbethClient) { - addLog("โœ— Client not initialized"); - return null; - } - - if (!contact.conversationId) { - addLog("โœ— Contact doesn't have a ratchet session"); - return null; - } - - const messageId = generateTempMessageId(); - const conversationId = contact.conversationId; - - // Create queued message - const queuedMessage: QueuedMessage = { - id: messageId, - conversationId, - contact, - plaintext: messageText, - status: "queued", - createdAt: Date.now(), - }; - - // Get or create queue for this conversation - let queue = queuesRef.current.get(conversationId); - if (!queue) { - queue = { messages: [], isProcessing: false }; - queuesRef.current.set(conversationId, queue); - } - - // Add to queue - queue.messages.push(queuedMessage); - - // Show optimistic UI message immediately - const optimisticMessage: Message = { - id: messageId, - topic: contact.topicOutbound || "", - sender: verbethClient.userAddress, - recipient: contact.address, - ciphertext: "", - timestamp: Date.now(), - blockTimestamp: Date.now(), - blockNumber: 0, - direction: "outgoing", - decrypted: messageText, - read: true, - nonce: 0, - dedupKey: `pending-${messageId}`, - type: "text", - ownerAddress: verbethClient.userAddress, - status: "pending", - }; - - await addMessage(optimisticMessage); - - addLog(`๐Ÿ“ Message queued: "${messageText.slice(0, 30)}..."`); - - // Trigger queue processing (non-blocking) - setTimeout(() => processQueue(conversationId), 0); - - return messageId; - }, [verbethClient, addLog, addMessage, processQueue]); - - /** - * Retry a failed message. - * - * The original ratchet slot was burned. Retry creates a new - * encryption with the current (advanced) session state. This means the - * message number will be different from the original attempt. - */ - const retryMessage = useCallback(async (messageId: string): Promise => { - // Check the failed messages map first - const failedMessage = failedMessagesRef.current.get(messageId); - - if (failedMessage) { - const conversationId = failedMessage.conversationId; - - // Remove from failed messages map - failedMessagesRef.current.delete(messageId); - - // Reset status for retry - failedMessage.status = "queued"; - failedMessage.error = undefined; - failedMessage.createdAt = Date.now(); - - // Get or create queue - let queue = queuesRef.current.get(conversationId); - if (!queue) { - queue = { messages: [], isProcessing: false }; - queuesRef.current.set(conversationId, queue); - } - - // Add to end of queue - queue.messages.push(failedMessage); - - // Update UI status back to pending - await updateMessageStatus(messageId, "pending"); - - addLog(`๐Ÿ”„ Retrying message (new slot): "${failedMessage.plaintext.slice(0, 30)}..."`); - - // Trigger processing - setTimeout(() => processQueue(conversationId), 0); - - return true; - } - - // Fallback: check if still in active queue (shouldn't happen normally) - for (const [conversationId, queue] of queuesRef.current.entries()) { - const messageIndex = queue.messages.findIndex( - m => m.id === messageId && m.status === "failed" - ); - - if (messageIndex !== -1) { - const message = queue.messages[messageIndex]; - - message.status = "queued"; - message.error = undefined; - message.createdAt = Date.now(); - - // Move to end of queue - queue.messages.splice(messageIndex, 1); - queue.messages.push(message); - - await updateMessageStatus(messageId, "pending"); - - addLog(`๐Ÿ”„ Retrying message: "${message.plaintext.slice(0, 30)}..."`); - - setTimeout(() => processQueue(conversationId), 0); - - return true; - } - } - - addLog(`โœ— Could not find message ${messageId} to retry`); - return false; - }, [addLog, updateMessageStatus, processQueue]); - - /** - * Cancel/delete a failed or queued message. - */ - const cancelMessage = useCallback(async (messageId: string): Promise => { - // Check failed messages map first - const failedMessage = failedMessagesRef.current.get(messageId); - - if (failedMessage) { - failedMessagesRef.current.delete(messageId); - - // Remove from DB and UI - await removeMessage(messageId); - - addLog(`๐Ÿ—‘๏ธ Deleted message: "${failedMessage.plaintext.slice(0, 30)}..."`); - return true; - } - - // Fallback: check active queues - for (const [, queue] of queuesRef.current.entries()) { - const messageIndex = queue.messages.findIndex( - m => m.id === messageId && (m.status === "queued" || m.status === "failed") - ); - - if (messageIndex !== -1) { - const message = queue.messages[messageIndex]; - queue.messages.splice(messageIndex, 1); - - await removeMessage(messageId); - - addLog(`๐Ÿ—‘๏ธ Deleted message: "${message.plaintext.slice(0, 30)}..."`); - return true; - } - } - - addLog(`โœ— Could not find message ${messageId} to delete`); - return false; - }, [addLog, removeMessage]); - - /** - * Get queue status for a conversation. - */ - const getQueueStatus = useCallback((conversationId: string): { - queueLength: number; - isProcessing: boolean; - pendingMessages: QueuedMessage[]; - } => { - const queue = queuesRef.current.get(conversationId); - if (!queue) { - return { queueLength: 0, isProcessing: false, pendingMessages: [] }; - } - return { - queueLength: queue.messages.length, - isProcessing: queue.isProcessing, - pendingMessages: [...queue.messages], - }; - }, []); - - /** - * Invalidate cached session for a conversation. - * Call this when session is reset or updated externally. - */ - const invalidateSessionCache = useCallback((conversationId: string) => { - sessionCacheRef.current.delete(conversationId); - addLog(`๐Ÿ”„ Session cache invalidated for ${conversationId.slice(0, 10)}...`); - }, [addLog]); - - /** - * Clear all queues (e.g., on logout). - */ - const clearAllQueues = useCallback(() => { - queuesRef.current.clear(); - failedMessagesRef.current.clear(); - sessionCacheRef.current.clear(); - }, []); - - return { - queueMessage, - retryMessage, - cancelMessage, - getQueueStatus, - invalidateSessionCache, - clearAllQueues, - }; -}; \ No newline at end of file diff --git a/apps/demo/src/services/EventProcessorService(old).ts b/apps/demo/src/services/EventProcessorService(old).ts deleted file mode 100644 index 41c2ba2..0000000 --- a/apps/demo/src/services/EventProcessorService(old).ts +++ /dev/null @@ -1,718 +0,0 @@ -// src/services/EventProcessorService.ts - -/** - * Event Processing Service. - * - * Handles decoding, verification, decryption, and persistence of blockchain events. - * Returns only what's needed for React state updates. - */ - -import { AbiCoder, getBytes } from "ethers"; -import { - type IdentityContext, - type IdentityKeyPair, - type RatchetSession, - parseHandshakePayload, - parseBindingMessage, - verifyHandshakeIdentity, - decodeUnifiedPubKeys, - verifyAndExtractHandshakeResponseKeys, - deriveDuplexTopics, - verifyDerivedDuplexTopics, - computeTagFromInitiator, - pickOutboundTopic, - initSessionAsInitiator, - ratchetDecrypt, - parseRatchetPayload, - isRatchetPayload, - verifyMessageSignature, -} from "@verbeth/sdk"; - -import { dbService } from "./DbService.js"; -import { - Contact, - Message, - PendingHandshake, - ProcessedEvent, - MessageDirection, - MessageType, - ContactStatus, - generateTempMessageId, -} from "../types.js"; - -export function hexToUint8Array(hex: string): Uint8Array { - const cleanHex = hex.replace("0x", ""); - return new Uint8Array( - cleanHex.match(/.{1,2}/g)?.map((byte) => parseInt(byte, 16)) || [] - ); -} - -export function generateMessageId( - txHash: string, - log: { logIndex?: number; index?: number } -): string { - const idx = - typeof log.logIndex !== "undefined" - ? log.logIndex - : typeof log.index !== "undefined" - ? log.index - : 0; - return `${txHash}-${idx}`; -} - -export interface HandshakeResult { - pendingHandshake: PendingHandshake; - systemMessage: Message; -} - -export interface HandshakeResponseResult { - updatedContact: Contact; - systemMessage: Message; -} - -export interface MessageResult { - newMessage?: Message; - messageUpdate?: [string, Partial]; - contactUpdate?: Contact; -} - -// ============================================================================= -// Handshake Processing -// ============================================================================= - -export async function processHandshakeEvent( - event: ProcessedEvent, - address: string, - readProvider: any, - identityContext: IdentityContext, - onLog: (msg: string) => void -): Promise { - try { - const log = event.rawLog; - const abiCoder = new AbiCoder(); - const decoded = abiCoder.decode(["bytes", "bytes", "bytes"], log.data); - const [identityPubKeyBytes, ephemeralPubKeyBytes, plaintextPayloadBytes] = - decoded; - - const unifiedPubKeys = hexToUint8Array(identityPubKeyBytes); - const decodedKeys = decodeUnifiedPubKeys(unifiedPubKeys); - - if (!decodedKeys) { - onLog("โœ— Failed to decode unified public keys"); - return null; - } - - const identityPubKey = decodedKeys.identityPubKey; - const signingPubKey = decodedKeys.signingPubKey; - const ephemeralPubKey = hexToUint8Array(ephemeralPubKeyBytes); - const plaintextPayload = new TextDecoder().decode( - hexToUint8Array(plaintextPayloadBytes) - ); - - const cleanSenderAddress = "0x" + log.topics[2].slice(-40); - const recipientHash = log.topics[1]; - - let handshakeContent; - let hasValidIdentityProof = false; - - try { - handshakeContent = parseHandshakePayload(plaintextPayload); - hasValidIdentityProof = true; - } catch (error) { - handshakeContent = { - plaintextPayload: plaintextPayload, - identityProof: null, - }; - hasValidIdentityProof = false; - } - - let isVerified = false; - if (hasValidIdentityProof) { - try { - const handshakeEvent = { - recipientHash, - sender: cleanSenderAddress, - pubKeys: identityPubKeyBytes, - ephemeralPubKey: ephemeralPubKeyBytes, - plaintextPayload: plaintextPayload, - }; - - isVerified = await verifyHandshakeIdentity( - handshakeEvent, - readProvider, - identityContext - ); - } catch (error) { - onLog(`Failed to verify handshake identity: ${error}`); - } - } - - let identityAddress = cleanSenderAddress; - if (hasValidIdentityProof && handshakeContent.identityProof?.message) { - try { - const parsed = parseBindingMessage( - handshakeContent.identityProof.message - ); - if (parsed.address) { - identityAddress = parsed.address; - } - } catch (e) {} - } - - const existingContact = await dbService.getContact( - identityAddress, - address - ); - const isExistingEstablished = existingContact?.status === "established"; - - const pendingHandshake: PendingHandshake = { - id: log.transactionHash, - ownerAddress: address, - sender: identityAddress, - emitterAddress: cleanSenderAddress, - identityPubKey, - signingPubKey, - ephemeralPubKey, - message: handshakeContent.plaintextPayload, - timestamp: Date.now(), - blockNumber: log.blockNumber, - verified: isVerified, - isExistingContact: isExistingEstablished, - }; - - const messagePrefix = pendingHandshake.isExistingContact - ? "Session reset request received" - : "Request received"; - - const systemMessage: Message = { - id: generateTempMessageId(), - topic: "", - sender: identityAddress, - recipient: address, - ciphertext: "", - timestamp: Date.now(), - blockTimestamp: Date.now(), - blockNumber: log.blockNumber, - direction: "incoming" as const, - decrypted: `${messagePrefix}: "${handshakeContent.plaintextPayload}"`, - read: true, - nonce: 0, - dedupKey: `handshake-received-${log.transactionHash}`, - type: "system" as const, - ownerAddress: address, - status: "confirmed" as const, - verified: isVerified, - }; - - await dbService.savePendingHandshake(pendingHandshake); - await dbService.saveMessage(systemMessage); - - const logSuffix = isExistingEstablished ? " (session reset)" : ""; - onLog( - `๐Ÿ“จ Handshake received from ${identityAddress.slice( - 0, - 8 - )}...${logSuffix} ${isVerified ? "โœ…" : "โš ๏ธ"}: "${ - handshakeContent.plaintextPayload - }"` - ); - - return { pendingHandshake, systemMessage }; - } catch (error) { - onLog(`โœ— Failed to process handshake log: ${error}`); - return null; - } -} - -// ============================================================================= -// Handshake Response Processing -// ============================================================================= - -export async function processHandshakeResponseEvent( - event: ProcessedEvent, - address: string, - readProvider: any, - identityKeyPair: IdentityKeyPair, - identityContext: IdentityContext, - onLog: (msg: string) => void -): Promise { - try { - const log = event.rawLog; - const abiCoder = new AbiCoder(); - const [responderEphemeralRBytes, ciphertextBytes] = abiCoder.decode( - ["bytes32", "bytes"], - log.data - ); - - const ciphertextJson = new TextDecoder().decode( - hexToUint8Array(ciphertextBytes) - ); - - const responder = "0x" + log.topics[2].slice(-40); - const inResponseTo = log.topics[1]; - - const currentContacts = await dbService.getAllContacts(address); - - onLog( - `๐Ÿ” Debug: Loaded ${currentContacts.length} contacts from DB for handshake response` - ); - - const contact = currentContacts.find( - (c) => - c.address.toLowerCase() === - event.matchedContactAddress?.toLowerCase() && - c.status === "handshake_sent" - ); - - if (!contact || !contact.handshakeEphemeralSecret) { - onLog( - `โ“ Received handshake response but no matching pending contact found (responder: ${responder.slice( - 0, - 8 - )}...)` - ); - return null; - } - - const responseEvent = { - inResponseTo, - responder, - responderEphemeralR: responderEphemeralRBytes, - ciphertext: ciphertextJson, - }; - - const result = await verifyAndExtractHandshakeResponseKeys( - responseEvent, - getBytes(contact.handshakeEphemeralSecret!), - readProvider, - identityContext - ); - - if (!result.isValid || !result.keys) { - onLog( - `โŒ Failed to verify handshake response from ${contact.address.slice( - 0, - 8 - )}... - invalid signature or tag mismatch` - ); - return null; - } - - const { identityPubKey, signingPubKey, ephemeralPubKey, note } = - result.keys; - - const saltHex = computeTagFromInitiator( - getBytes(contact.handshakeEphemeralSecret!), - hexToUint8Array(responderEphemeralRBytes) - ); - const salt = Uint8Array.from(Buffer.from(saltHex.slice(2), "hex")); - - const duplexTopics = deriveDuplexTopics( - identityKeyPair.secretKey, - identityPubKey, - salt - ); - - const isValidTopics = verifyDerivedDuplexTopics({ - myIdentitySecretKey: identityKeyPair.secretKey, - theirIdentityPubKey: identityPubKey, - topicInfo: { - out: duplexTopics.topicOut, - in: duplexTopics.topicIn, - chk: duplexTopics.checksum, - }, - salt, - }); - - if (!isValidTopics) { - onLog( - `โŒ Invalid duplex topics checksum for ${contact.address.slice( - 0, - 8 - )}...` - ); - return null; - } - - onLog( - `โœ… Handshake response verified from ${contact.address.slice(0, 8)}...` - ); - - const topicOutbound = pickOutboundTopic(true, duplexTopics); - const topicInbound = pickOutboundTopic(false, duplexTopics); - - const ratchetSession = initSessionAsInitiator({ - myAddress: address, - contactAddress: contact.address, - myHandshakeEphemeralSecret: getBytes(contact.handshakeEphemeralSecret!), - theirResponderEphemeralPubKey: ephemeralPubKey, - topicOutbound, - topicInbound, - }); - - const updatedContact: Contact = { - ...contact, - status: "established" as ContactStatus, - identityPubKey, - signingPubKey, - handshakeEphemeralSecret: undefined, - topicOutbound: ratchetSession.currentTopicOutbound, - topicInbound: ratchetSession.currentTopicInbound, - conversationId: ratchetSession.conversationId, - lastMessage: note || "Handshake accepted", - lastTimestamp: Date.now(), - }; - - const systemMessage: Message = { - id: generateTempMessageId(), - topic: updatedContact.topicInbound || "", - sender: contact.address, - recipient: address, - ciphertext: "", - timestamp: Date.now(), - blockTimestamp: Date.now(), - blockNumber: 0, - direction: "incoming" as const, - decrypted: `Request accepted: "${note || "No message"}"`, - read: true, - nonce: 0, - dedupKey: `handshake-response-${inResponseTo}`, - type: "system" as const, - ownerAddress: address, - status: "confirmed" as const, - verified: true, - }; - - await dbService.saveRatchetSession(ratchetSession); - await dbService.saveContact(updatedContact); - await dbService.saveMessage(systemMessage); - - onLog( - `๐Ÿค Handshake completed with ${contact.address.slice(0, 8)}... : "${ - note || "No message" - }"` - ); - - return { updatedContact, systemMessage }; - } catch (error) { - onLog(`โœ— Failed to process handshake response log: ${error}`); - return null; - } -} - -// ============================================================================= -// Message Processing (Outgoing Confirmation + Incoming Decryption) -// ============================================================================= - -/** - * Process a message event. - * Session cache is keyed by conversationId (not topic) to handle topic ratcheting. - */ -export async function processMessageEvent( - event: ProcessedEvent, - address: string, - emitterAddress: string | undefined, - sessionCache: Map, - onLog: (msg: string) => void -): Promise { - try { - const log = event.rawLog; - const abiCoder = new AbiCoder(); - const decoded = abiCoder.decode(["bytes", "uint256", "uint256"], log.data); - const [ciphertextBytes, timestamp, nonce] = decoded; - const topic = log.topics[2]; - const sender = "0x" + log.topics[1].slice(-40); - const dedupKey = `${address.toLowerCase()}:${generateMessageId( - log.transactionHash, - log - )}`; - - const ciphertextHex = ciphertextBytes as string; - const ciphertextRaw = hexToUint8Array(ciphertextHex); - const emitter = emitterAddress || address; - const isOurMessage = - emitter && sender.toLowerCase() === emitter.toLowerCase(); - - if (!isOurMessage) { - const already = await dbService.getByDedupKey(dedupKey); - if (already) return null; - } - - onLog( - `๐Ÿ” Processing message log: sender=${sender.slice( - 0, - 8 - )}..., isOurMessage=${isOurMessage}, topic=${topic.slice( - 0, - 10 - )}..., nonce=${Number(nonce)}` - ); - - // ========================================================================= - // OUTGOING MESSAGE CONFIRMATION (Ratchet two-phase commit) - // ========================================================================= - if (isOurMessage) { - onLog( - `๐Ÿ”„ Confirming our outgoing message: topic=${topic.slice( - 0, - 10 - )}..., nonce=${Number(nonce)}` - ); - - // Match by txHash - const pending = await dbService.getPendingOutboundByTxHash( - log.transactionHash - ); - - if (pending && pending.status === "submitted") { - // clean up the pending record (session already committed during encryption) - const finalized = await dbService.finalizePendingOutbound(pending.id); - - if (!finalized) { - onLog( - `โš ๏ธ Failed to finalize pending outbound ${pending.id.slice( - 0, - 8 - )}...` - ); - return null; - } - - const newId = generateMessageId(log.transactionHash, log); - const updates: Partial = { - id: newId, - status: "confirmed", - blockNumber: log.blockNumber, - blockTimestamp: Date.now(), - ciphertext: ciphertextHex, - nonce: Number(nonce), - dedupKey, - }; - - await dbService.updateMessage(pending.id, updates); - await dbService.upsertDedup({ - key: dedupKey, - messageId: newId, - txHash: log.transactionHash, - blockNumber: log.blockNumber, - }); - - onLog( - `โœ… Message confirmed: "${finalized.plaintext.slice( - 0, - 30 - )}..." (${pending.id.slice(0, 8)} โ†’ ${newId.slice(0, 8)})` - ); - - return { - messageUpdate: [pending.id, updates], - }; - } - - onLog( - `โš ๏ธ Outgoing message on-chain but no pending record found (tx: ${log.transactionHash.slice( - 0, - 10 - )}...)` - ); - return null; - } - - // ========================================================================= - // INCOMING MESSAGE - Use multi-topic lookup for ratchet session - // ========================================================================= - - // multi-topic lookup: handles both current and previous (grace period) topics - const session = await dbService.getRatchetSessionByAnyInboundTopic(topic); - - if (!session) { - onLog( - `โ“ Received message on unknown topic: ${topic.slice( - 0, - 10 - )}... from ${sender.slice(0, 8)}...` - ); - return null; - } - - // Check session cache by conversationId (not topic, since topic can change) - let cachedSession = sessionCache.get(session.conversationId); - let workingSession = cachedSession || session; - - const topicLower = (topic as string).toLowerCase(); - if ( - workingSession.nextTopicInbound && - topicLower === workingSession.nextTopicInbound.toLowerCase() - ) { - onLog( - `๐Ÿ“ˆ Promoting next topics to current (epoch ${ - workingSession.topicEpoch - } โ†’ ${workingSession.topicEpoch + 1})` - ); - - workingSession = { - ...workingSession, - - previousTopicInbound: workingSession.currentTopicInbound, - previousTopicExpiry: Date.now() + 5 * 60 * 1000, // 5 min grace - - currentTopicInbound: workingSession.nextTopicInbound, - currentTopicOutbound: workingSession.nextTopicOutbound!, - - nextTopicInbound: undefined, - nextTopicOutbound: undefined, - topicEpoch: workingSession.topicEpoch + 1, - }; - - // Aggiorna la cache con la sessione promossa - sessionCache.set(workingSession.conversationId, workingSession); - } - // ========================================================================= - - // Find contact for signing key verification - const contact = await dbService.getContact( - workingSession.contactAddress, - address - ); - if (!contact?.signingPubKey) { - onLog( - `โœ— No signing key for contact ${workingSession.contactAddress.slice( - 0, - 8 - )}...` - ); - return null; - } - - // Check if ratchet format - if (!isRatchetPayload(ciphertextRaw)) { - onLog( - `โœ— Message not in ratchet format from ${contact.address.slice(0, 8)}...` - ); - return null; - } - - const parsed = parseRatchetPayload(ciphertextRaw); - if (!parsed) { - onLog( - `โœ— Failed to parse ratchet payload from ${contact.address.slice( - 0, - 8 - )}...` - ); - return null; - } - - // AUTH-FIRST: Verify signature BEFORE any ratchet operations (DoS protection) - const sigValid = verifyMessageSignature( - parsed.signature, - parsed.header, - parsed.ciphertext, - contact.signingPubKey - ); - - if (!sigValid) { - onLog( - `โœ— Invalid signature on message from ${contact.address.slice( - 0, - 8 - )}..., ignoring` - ); - return null; - } - - // Decrypt with ratchet (signature verified) - const decryptResult = ratchetDecrypt( - workingSession, - parsed.header, - parsed.ciphertext - ); - - if (!decryptResult) { - onLog( - `โœ— Ratchet decryption failed from ${contact.address.slice(0, 8)}...` - ); - return null; - } - - // Update session cache by conversationId (topic may have changed due to DH ratchet) - sessionCache.set( - decryptResult.session.conversationId, - decryptResult.session - ); - - const decryptedText = new TextDecoder().decode(decryptResult.plaintext); - - const message: Message = { - id: generateMessageId(log.transactionHash, log), - topic: topic, - sender: contact.address, - recipient: address, - ciphertext: ciphertextHex, - timestamp: Number(timestamp) * 1000, - blockTimestamp: Date.now(), - blockNumber: log.blockNumber, - direction: "incoming" as MessageDirection, - decrypted: decryptedText, - read: false, - nonce: Number(nonce), - dedupKey, - type: "text" as MessageType, - ownerAddress: address, - status: "confirmed", - }; - - // Update contact with current topic (may have ratcheted) - const updatedContact: Contact = { - ...contact, - topicInbound: decryptResult.session.currentTopicInbound, - topicOutbound: decryptResult.session.currentTopicOutbound, - lastMessage: decryptedText, - lastTimestamp: Date.now(), - }; - - // Persist to DB - const saved = await dbService.saveMessage(message); - if (saved) { - await dbService.upsertDedup({ - key: dedupKey, - messageId: message.id, - txHash: log.transactionHash, - blockNumber: log.blockNumber, - }); - await dbService.saveContact(updatedContact); - } - - onLog( - `๐Ÿ“ฉ Message from ${contact.address.slice(0, 8)}...: "${decryptedText}"` - ); - - return saved - ? { newMessage: message, contactUpdate: updatedContact } - : null; - } catch (error) { - onLog(`โœ— Failed to process message log: ${error}`); - return null; - } -} - -export async function persistSessionCache( - sessionCache: Map, - onLog: (msg: string) => void -): Promise { - if (sessionCache.size === 0) return; - - for (const [conversationId, session] of sessionCache) { - try { - await dbService.saveRatchetSession(session); - onLog(`๐Ÿ’พ Persisted session state for ${conversationId.slice(0, 10)}...`); - } catch (error) { - onLog( - `โœ— Failed to persist session for ${conversationId.slice( - 0, - 10 - )}...: ${error}` - ); - } - } -} diff --git a/apps/demo/src/services/EventProcessorService.ts b/apps/demo/src/services/EventProcessorService.ts index 5dbcac7..d04fc97 100644 --- a/apps/demo/src/services/EventProcessorService.ts +++ b/apps/demo/src/services/EventProcessorService.ts @@ -1,10 +1,14 @@ // src/services/EventProcessorService.ts +// CLEANED VERSION - duplexTopics removed, topics derived from ephemeral DH /** * Event Processing Service. * * Handles decoding, verification, decryption, and persistence of blockchain events. * Uses VerbethClient SDK methods for simplified session management. + * + * CHANGE: processHandshakeResponseEvent now derives topics from ephemeral DH + * instead of using verifyDerivedDuplexTopics. */ import { AbiCoder, getBytes } from "ethers"; @@ -17,8 +21,11 @@ import { verifyHandshakeIdentity, decodeUnifiedPubKeys, verifyAndExtractHandshakeResponseKeys, - pickOutboundTopic, + // REMOVED: pickOutboundTopic initSessionAsInitiator, + // NEW: for topic derivation + dh, + deriveTopicFromDH, } from "@verbeth/sdk"; import { dbService } from "./DbService.js"; @@ -204,7 +211,8 @@ export async function processHandshakeEvent( } // ============================================================================= -// Handshake Response Processing (unchanged - creates new session) +// Handshake Response Processing +// UPDATED: Now derives topics from ephemeral DH instead of identity keys // ============================================================================= export async function processHandshakeResponseEvent( @@ -263,21 +271,16 @@ export async function processHandshakeResponseEvent( return null; } - // Derive duplex topics - const { verifyDerivedDuplexTopics } = await import("@verbeth/sdk"); - const { topics, ok } = verifyDerivedDuplexTopics({ - myIdentitySecretKey: identityKeyPair.secretKey, - theirIdentityPubKey: result.keys.identityPubKey, - tag: inResponseTo as `0x${string}`, - }); - - if (ok === false) { - onLog(`โœ— Topic checksum mismatch in handshake response`); - return null; - } - - const topicOutbound = pickOutboundTopic(true, topics); - const topicInbound = pickOutboundTopic(false, topics); + // ========================================================================= + // NEW: Derive initial topics from ephemeral shared secret + // This replaces the old verifyDerivedDuplexTopics + pickOutboundTopic + // ========================================================================= + const ephemeralShared = dh(initiatorEphemeralSecret, result.keys.ephemeralPubKey); + const salt = getBytes(inResponseTo); // Use tag as salt + + // Topics are derived from initiator's perspective (no swap needed here) + const topicOutbound = deriveTopicFromDH(ephemeralShared, 'outbound', salt); + const topicInbound = deriveTopicFromDH(ephemeralShared, 'inbound', salt); // Initialize ratchet session as initiator const ratchetSession = initSessionAsInitiator({ @@ -511,4 +514,4 @@ export async function processMessageEvent( onLog(`โœ— Failed to process message: ${error}`); return null; } -} +} \ No newline at end of file diff --git a/apps/docs/topic-ratcheting.md b/apps/docs/topic-ratcheting.md index c46b68f..2f4d230 100644 --- a/apps/docs/topic-ratcheting.md +++ b/apps/docs/topic-ratcheting.md @@ -134,6 +134,16 @@ Enables O(1) lookups by any topic variant. ## Typical Flow +Handshake Exchange + โ†“ +Seed Topic (from ephemeral DH) โ† both parties compute this + โ†“ +First Message (Alice โ†’ Bob on seed topic, includes new DH pub) + โ†“ +DH Ratchet โ†’ New Topics (from message DH) + โ†“ +Subsequent messages use ratcheted topics + ``` Alice (Initiator) Bob (Responder) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ diff --git a/packages/sdk/src/client/VerbethClient.ts b/packages/sdk/src/client/VerbethClient.ts index 2d695b1..788cc64 100644 --- a/packages/sdk/src/client/VerbethClient.ts +++ b/packages/sdk/src/client/VerbethClient.ts @@ -1,4 +1,5 @@ // packages/sdk/src/client/VerbethClient.ts +// CLEANED VERSION - duplexTopics removed, topics derived from ephemeral DH /** * High-level client for Verbeth E2EE messaging. @@ -9,34 +10,17 @@ * - Two-phase commit for message sending * - Transaction confirmation handling * - * @example - * ```typescript - * // Create client - * const client = new VerbethClient({ - * executor, - * identityKeyPair, - * identityProof, - * signer, - * address: '0x...' - * }); - * - * // Configure storage (required for messaging) - * client.setSessionStore(sessionStore); - * client.setPendingStore(pendingStore); - * - * // Send a message - * const result = await client.sendMessage(conversationId, 'Hello!'); - * - * // On confirmation event - * const confirmed = await client.confirmTx(txHash); - * ``` + * CHANGE: acceptHandshake now returns topicOutbound/topicInbound directly, + * derived from the ephemeral DH shared secret (same approach as post-handshake + * topic ratcheting). */ -import { hexlify } from 'ethers'; +import { hexlify, getBytes } from 'ethers'; import { initiateHandshake, respondToHandshake } from '../send.js'; -import { deriveDuplexTopics } from '../crypto.js'; +// REMOVED: deriveDuplexTopics import import type { IExecutor } from '../executor.js'; -import type { IdentityKeyPair, IdentityProof, DuplexTopics } from '../types.js'; +import type { IdentityKeyPair, IdentityProof } from '../types.js'; +// REMOVED: DuplexTopics from types import type { Signer } from 'ethers'; import * as crypto from '../crypto.js'; @@ -50,6 +34,7 @@ import { ratchetEncrypt } from '../ratchet/encrypt.js'; import { ratchetDecrypt } from '../ratchet/decrypt.js'; import { packageRatchetPayload, parseRatchetPayload, isRatchetPayload } from '../ratchet/codec.js'; import { verifyMessageSignature } from '../ratchet/auth.js'; +import { dh, deriveTopicFromDH } from '../ratchet/kdf.js'; // NEW: for topic derivation import type { RatchetSession } from '../ratchet/types.js'; import { SessionManager } from './SessionManager.js'; @@ -142,17 +127,18 @@ export class VerbethClient { /** * Accepts a handshake from an initiator. * - * Derives duplex topics for the conversation and returns ephemeral keys - * needed for ratchet session initialization. + * UPDATED: Now derives topics from ephemeral DH shared secret (same approach + * as post-handshake topic ratcheting). Returns topicOutbound/topicInbound + * directly instead of duplexTopics structure. * * @param initiatorEphemeralPubKey - Initiator's ephemeral public key from handshake event - * @param initiatorIdentityPubKey - Initiator's long-term X25519 identity key + * @param initiatorIdentityPubKey - Initiator's long-term X25519 identity key (kept for future use) * @param note - Response message to send back - * @returns Transaction, derived duplex topics, and ephemeral keys for ratchet + * @returns Transaction, derived topics, and ephemeral keys for ratchet */ async acceptHandshake( initiatorEphemeralPubKey: Uint8Array, - initiatorIdentityPubKey: Uint8Array, + initiatorIdentityPubKey: Uint8Array, // Kept for potential future use note: string ): Promise { const { @@ -168,18 +154,24 @@ export class VerbethClient { note, identityProof: this.identityProof, signer: this.signer, - initiatorIdentityPubKey, + // REMOVED: initiatorIdentityPubKey - no longer used for topic derivation }); - const duplexTopics = deriveDuplexTopics( - this.identityKeyPair.secretKey, - initiatorIdentityPubKey, - salt - ); + // NEW: Derive initial topics from ephemeral shared secret + // This is consistent with post-handshake topic ratcheting in ratchet/kdf.ts + const ephemeralShared = dh(responderEphemeralSecret, initiatorEphemeralPubKey); + + // Use salt (the tag) for topic derivation, same as conversationId derivation + // Labels are from INITIATOR's perspective, so we SWAP for responder: + // - Responder's outbound = initiator's inbound + // - Responder's inbound = initiator's outbound + const topicOutbound = deriveTopicFromDH(ephemeralShared, 'inbound', salt); + const topicInbound = deriveTopicFromDH(ephemeralShared, 'outbound', salt); return { tx, - duplexTopics, + topicOutbound, + topicInbound, tag, salt, responderEphemeralSecret, diff --git a/packages/sdk/src/client/types.ts b/packages/sdk/src/client/types.ts index 83913d5..240d500 100644 --- a/packages/sdk/src/client/types.ts +++ b/packages/sdk/src/client/types.ts @@ -9,7 +9,7 @@ import type { Signer } from 'ethers'; import type { IExecutor } from '../executor.js'; -import type { IdentityKeyPair, IdentityProof, DuplexTopics } from '../types.js'; +import type { IdentityKeyPair, IdentityProof } from '../types.js'; import type { RatchetSession } from '../ratchet/types.js'; import type nacl from 'tweetnacl'; @@ -31,7 +31,8 @@ export interface HandshakeResult { export interface HandshakeResponseResult { tx: any; - duplexTopics: DuplexTopics; + topicOutbound: `0x${string}`; + topicInbound: `0x${string}`; tag: `0x${string}`; salt: Uint8Array; responderEphemeralSecret: Uint8Array; // must persist as dhMySecretKey in ratchet diff --git a/packages/sdk/src/crypto.ts b/packages/sdk/src/crypto.ts index f1f5a7d..ab1cf64 100644 --- a/packages/sdk/src/crypto.ts +++ b/packages/sdk/src/crypto.ts @@ -1,19 +1,22 @@ // packages/sdk/src/crypto.ts +// CLEANED VERSION - duplexTopics and legacy functions removed /** * Cryptographic utilities for Verbeth. * * This module handles: * - Handshake encryption/decryption (NaCl box - one-time exchange) - * - Topic derivation (HKDF + Keccak) * - Tag computation for handshake responses * * NOTE: Post-handshake message encryption uses the ratchet module. * See `ratchet/encrypt.ts` and `ratchet/decrypt.ts` for Double Ratchet. + * + * NOTE: Topic derivation is now handled entirely by the ratchet module. + * See `ratchet/kdf.ts` for `deriveTopicFromDH`. */ import nacl from 'tweetnacl'; -import { keccak256, toUtf8Bytes, dataSlice } from 'ethers'; +import { keccak256, toUtf8Bytes } from 'ethers'; import { sha256 } from '@noble/hashes/sha2'; import { hkdf } from '@noble/hashes/hkdf'; import { @@ -82,55 +85,6 @@ export function decryptStructuredPayload( return decodeStructuredContent(box, converter); } -// ============================================================================= -// Legacy Message Encryption (for backward compatibility / log decryption) -// ============================================================================= - -/** - * Encrypts a message using NaCl box. - * - * @deprecated For new messages, use ratchetEncrypt() from the ratchet module. - * This function is kept for backward compatibility with legacy logs. - */ -export function encryptMessage( - message: string, - recipientPublicKey: Uint8Array, - ephemeralSecretKey: Uint8Array, - ephemeralPublicKey: Uint8Array, - staticSigningSecretKey?: Uint8Array, - staticSigningPublicKey?: Uint8Array -): string { - const payload: MessagePayload = { content: message }; - return encryptStructuredPayload( - payload, - recipientPublicKey, - ephemeralSecretKey, - ephemeralPublicKey, - staticSigningSecretKey, - staticSigningPublicKey - ); -} - -/** - * Decrypts a message using NaCl box. - * - * @deprecated For new messages, use ratchetDecrypt() from the ratchet module. - * This function is kept for backward compatibility with legacy logs. - */ -export function decryptMessage( - payloadJson: string, - recipientSecretKey: Uint8Array, - staticSigningPublicKey?: Uint8Array -): string | null { - const result = decryptStructuredPayload( - payloadJson, - recipientSecretKey, - (obj) => obj as MessagePayload, - staticSigningPublicKey - ); - return result ? result.content : null; -} - // ============================================================================= // Handshake Response Decryption // ============================================================================= @@ -154,11 +108,7 @@ export function decryptHandshakeResponse( ephemeralPubKey: Uint8Array.from(Buffer.from(obj.ephemeralPubKey, 'base64')), note: obj.note, identityProof: obj.identityProof, - topicInfo: obj.topicInfo ? { - out: obj.topicInfo.out, - in: obj.topicInfo.in, - chk: obj.topicInfo.chk - } : undefined + // topicInfo removed - no longer needed }; } ); @@ -227,66 +177,13 @@ export function computeTagFromInitiator( } // ============================================================================= -// Topic Derivation +// REMOVED FUNCTIONS: // ============================================================================= - -/** - * Derives a bytes32 topic from the shared secret via HKDF(SHA256) + Keccak-256. - * - info: domain separation (e.g., "verbeth:topic-out:v1") - * - salt: recommended to use a tag as salt (stable and shareable) - */ -function deriveTopic( - shared: Uint8Array, - info: string, - salt?: Uint8Array -): `0x${string}` { - const okm = hkdf(sha256, shared, salt ?? new Uint8Array(0), new TextEncoder().encode(info), 32); - return keccak256(okm) as `0x${string}`; -} - -/** - * Derives long-term shared secret from identity keys. - */ -export function deriveLongTermShared( - myIdentitySecretKey: Uint8Array, - theirIdentityPublicKey: Uint8Array -): Uint8Array { - return nacl.scalarMult(myIdentitySecretKey, theirIdentityPublicKey); -} - -/** - * Directional duplex topics (Initiator-Responder, Responder-Initiator). - * Recommended salt: tag (bytes) - */ -export function deriveDuplexTopics( - myIdentitySecretKey: Uint8Array, - theirIdentityPublicKey: Uint8Array, - salt?: Uint8Array -): { topicOut: `0x${string}`; topicIn: `0x${string}`; checksum: `0x${string}` } { - const shared = deriveLongTermShared(myIdentitySecretKey, theirIdentityPublicKey); - const topicOut = deriveTopic(shared, "verbeth:topic-out:v1", salt); - const topicIn = deriveTopic(shared, "verbeth:topic-in:v1", salt); - const chkFull = keccak256(Buffer.concat([ - toUtf8Bytes("verbeth:topic-chk:v1"), - Buffer.from(topicOut.slice(2), 'hex'), - Buffer.from(topicIn.slice(2), 'hex'), - ])); - const checksum = dataSlice(chkFull as `0x${string}`, 8) as `0x${string}`; - return { topicOut, topicIn, checksum }; -} - -/** - * Verifies duplex topics checksum. - */ -export function verifyDuplexTopicsChecksum( - topicOut: `0x${string}`, - topicIn: `0x${string}`, - checksum: `0x${string}` -): boolean { - const chkFull = keccak256(Buffer.concat([ - toUtf8Bytes("verbeth:topic-chk:v1"), - Buffer.from(topicOut.slice(2), 'hex'), - Buffer.from(topicIn.slice(2), 'hex'), - ])); - return dataSlice(chkFull as `0x${string}`, 8) === checksum; -} \ No newline at end of file +// +// deriveLongTermShared() - was used for duplexTopics, now use ratchet/kdf.ts dh() +// deriveDuplexTopics() - replaced by deriveTopicFromDH() in ratchet/kdf.ts +// verifyDuplexTopicsChecksum() - no longer needed, topics derive from DH +// encryptMessage() - deprecated, use ratchetEncrypt() from ratchet module +// decryptMessage() - deprecated, use ratchetDecrypt() from ratchet module +// +// ============================================================================= \ No newline at end of file diff --git a/packages/sdk/src/index.ts b/packages/sdk/src/index.ts index e090352..bdfe18d 100644 --- a/packages/sdk/src/index.ts +++ b/packages/sdk/src/index.ts @@ -9,8 +9,6 @@ export * from './utils.js'; export * from './identity.js'; export * from './executor.js'; -export { decryptMessage as decryptLog } from './crypto.js'; - export { encodeUnifiedPubKeys, decodeUnifiedPubKeys, @@ -23,7 +21,6 @@ export { export { decryptAndExtractHandshakeKeys, - decryptMessage, decryptHandshakeResponse } from './crypto.js'; @@ -72,4 +69,5 @@ export type { SerializedSessionInfo, } from './client/index.js'; -export * from './ratchet/index.js'; \ No newline at end of file +export * from './ratchet/index.js'; +export { dh, deriveTopicFromDH } from './ratchet/kdf.js'; \ No newline at end of file diff --git a/packages/sdk/src/payload.ts b/packages/sdk/src/payload.ts index 0cd3c70..32e1260 100644 --- a/packages/sdk/src/payload.ts +++ b/packages/sdk/src/payload.ts @@ -1,5 +1,8 @@ // packages/sdk/src/payload.ts -import { IdentityProof, TopicInfoWire } from './types.js'; +// CLEANED VERSION - TopicInfoWire removed + +import { IdentityProof } from './types.js'; +// REMOVED: TopicInfoWire import export interface EncryptedPayload { @@ -158,12 +161,18 @@ export interface HandshakePayload { plaintextPayload: string; } +/** + * HandshakeResponseContent - CLEANED + * + * REMOVED: topicInfo field - topics are now derived from ephemeral DH + * in the caller (VerbethClient.acceptHandshake and EventProcessorService) + */ export interface HandshakeResponseContent { unifiedPubKeys: Uint8Array; // 65 bytes: version + X25519 + Ed25519 ephemeralPubKey: Uint8Array; note?: string; identityProof: IdentityProof; - topicInfo?: TopicInfoWire; + // REMOVED: topicInfo?: TopicInfoWire; } export function encodeHandshakePayload(payload: HandshakePayload): Uint8Array { @@ -184,20 +193,26 @@ export function decodeHandshakePayload(encoded: Uint8Array): HandshakePayload { }; } +/** + * Encodes HandshakeResponseContent - CLEANED + * + * REMOVED: topicInfo encoding - no longer included in handshake response + */ export function encodeHandshakeResponseContent(content: HandshakeResponseContent): Uint8Array { return new TextEncoder().encode(JSON.stringify({ unifiedPubKeys: Buffer.from(content.unifiedPubKeys).toString('base64'), ephemeralPubKey: Buffer.from(content.ephemeralPubKey).toString('base64'), note: content.note, - identityProof: content.identityProof, - topicInfo: content.topicInfo ? { - out: content.topicInfo.out, - in: content.topicInfo.in, - chk: content.topicInfo.chk - } : undefined - })); - } + identityProof: content.identityProof, + // REMOVED: topicInfo encoding + })); +} +/** + * Decodes HandshakeResponseContent - CLEANED + * + * REMOVED: topicInfo decoding - no longer expected in handshake response + */ export function decodeHandshakeResponseContent(encoded: Uint8Array): HandshakeResponseContent { const json = new TextDecoder().decode(encoded); const obj = JSON.parse(json); @@ -211,11 +226,7 @@ export function decodeHandshakeResponseContent(encoded: Uint8Array): HandshakeRe ephemeralPubKey: Uint8Array.from(Buffer.from(obj.ephemeralPubKey, 'base64')), note: obj.note, identityProof: obj.identityProof, - topicInfo: obj.topicInfo ? { - out: obj.topicInfo.out, - in: obj.topicInfo.in, - chk: obj.topicInfo.chk - } : undefined + // REMOVED: topicInfo decoding }; } @@ -236,7 +247,9 @@ export function createHandshakePayload( } /** - * Creates HandshakeResponseContent from separate identity keys + * Creates HandshakeResponseContent from separate identity keys - CLEANED + * + * REMOVED: topicInfo parameter - topics are now derived from ephemeral DH */ export function createHandshakeResponseContent( identityPubKey: Uint8Array, @@ -244,7 +257,7 @@ export function createHandshakeResponseContent( ephemeralPubKey: Uint8Array, note?: string, identityProof?: IdentityProof, - topicInfo?: TopicInfoWire + // REMOVED: topicInfo?: TopicInfoWire parameter ): HandshakeResponseContent { if (!identityProof) { throw new Error("Identity proof is now mandatory for handshake responses"); @@ -255,7 +268,7 @@ export function createHandshakeResponseContent( ephemeralPubKey, note, identityProof, - topicInfo + // REMOVED: topicInfo field }; } diff --git a/packages/sdk/src/send.ts b/packages/sdk/src/send.ts index 942b691..45255ae 100644 --- a/packages/sdk/src/send.ts +++ b/packages/sdk/src/send.ts @@ -1,10 +1,14 @@ // packages/sdk/src/send.ts +// CLEANED VERSION - topicInfo removed from handshake response /** * Handshake and message sending functions. * * NOTE: sendEncryptedMessage is REMOVED - use ratchet for established sessions. * Only handshake functions remain here. + * + * CHANGE: respondToHandshake no longer computes or includes topicInfo. + * Topics are now derived from ephemeral DH by the caller. */ import { @@ -15,14 +19,16 @@ import { getBytes } from "ethers"; import nacl from 'tweetnacl'; -import { encryptStructuredPayload, deriveDuplexTopics } from './crypto.js'; +import { encryptStructuredPayload } from './crypto.js'; +// REMOVED: deriveDuplexTopics import import { HandshakeContent, serializeHandshakeContent, encodeUnifiedPubKeys, createHandshakeResponseContent, } from './payload.js'; -import { IdentityKeyPair, IdentityProof, TopicInfoWire } from './types.js'; +import { IdentityKeyPair, IdentityProof } from './types.js'; +// REMOVED: TopicInfoWire from imports import { IExecutor } from './executor.js'; import { computeTagFromResponder } from './crypto.js'; @@ -91,6 +97,9 @@ export async function initiateHandshake({ * Responds to a handshake with unified keys and mandatory identity proof. * Executor-agnostic: works with EOA, UserOp, and Direct EntryPoint (for tests) * + * CHANGE: No longer computes or returns topicInfo. Topics are derived from + * ephemeral DH by the caller using deriveTopicFromDH(). + * * @returns Transaction, tag, salt, AND ephemeral keys (MUST be persisted for ratchet session) */ export async function respondToHandshake({ @@ -100,7 +109,7 @@ export async function respondToHandshake({ note, identityProof, signer, - initiatorIdentityPubKey, + // REMOVED: initiatorIdentityPubKey - no longer needed for topic derivation }: { executor: IExecutor; initiatorEphemeralPubKey: Uint8Array; @@ -108,7 +117,7 @@ export async function respondToHandshake({ note?: string; identityProof: IdentityProof; signer: Signer; - initiatorIdentityPubKey?: Uint8Array; + // REMOVED: initiatorIdentityPubKey?: Uint8Array; }): Promise<{ tx: any; salt: Uint8Array; @@ -152,24 +161,19 @@ export async function respondToHandshake({ ); const salt: Uint8Array = getBytes(inResponseTo); - let topicInfo: TopicInfoWire | undefined = undefined; - if (initiatorIdentityPubKey) { - const { topicOut, topicIn, checksum } = deriveDuplexTopics( - responderIdentityKeyPair.secretKey, - initiatorIdentityPubKey, - salt - ); - topicInfo = { out: topicOut, in: topicIn, chk: checksum }; - } + // REMOVED: topicInfo computation - caller will derive topics from ephemeral DH + // let topicInfo: TopicInfoWire | undefined = undefined; + // if (initiatorIdentityPubKey) { ... } // Response content includes ratchetKeyPair.publicKey (hidden inside encrypted payload) + // UPDATED: No longer includes topicInfo const responseContent = createHandshakeResponseContent( responderIdentityKeyPair.publicKey, // X25519 identity responderIdentityKeyPair.signingPublicKey, // Ed25519 signing ratchetKeyPair.publicKey, // First DH ratchet key (INSIDE payload) note, - identityProof, - topicInfo + identityProof + // REMOVED: topicInfo parameter ); // Encrypt using ratchetKeyPair (the epk in encrypted payload = ratchetKeyPair.publicKey) diff --git a/packages/sdk/src/types.ts b/packages/sdk/src/types.ts index c605c0f..8828f15 100644 --- a/packages/sdk/src/types.ts +++ b/packages/sdk/src/types.ts @@ -23,22 +23,6 @@ export interface HandshakeResponseLog { ciphertext: string; // Contains unified pubKeys + identityProof encrypted } -// Duplex topics structure -export interface DuplexTopics { - /** Initiator to Responder */ - topicOut: `0x${string}`; - /** Responder to Initiator */ - topicIn: `0x${string}`; -} - -// for HSR -export interface TopicInfoWire { - out: `0x${string}`; - in: `0x${string}`; - // short checksum - chk: `0x${string}`; -} - // Identity key pair structure export interface IdentityKeyPair { // X25519 keys per encryption/decryption diff --git a/packages/sdk/src/utils.ts b/packages/sdk/src/utils.ts index 4ad11e3..4245896 100644 --- a/packages/sdk/src/utils.ts +++ b/packages/sdk/src/utils.ts @@ -1,4 +1,5 @@ // packages/sdk/src/utils.ts +// CLEANED VERSION - pickOutboundTopic and DuplexTopics removed import { Contract, @@ -14,7 +15,7 @@ import { defineChain, type PublicClient, } from "viem"; -import { DuplexTopics } from "./types.js"; +// REMOVED: DuplexTopics import no longer needed export function parseBindingMessage(message: string): { @@ -179,7 +180,11 @@ export async function isSmartContract1271( } } -// picks the correct outbound topic from a DuplexTopics structure -export function pickOutboundTopic(isInitiator: boolean, t: DuplexTopics): `0x${string}` { - return isInitiator ? t.topicOut : t.topicIn; -} \ No newline at end of file +// ============================================================================= +// REMOVED FUNCTIONS: +// ============================================================================= +// +// pickOutboundTopic() - removed, no longer using DuplexTopics structure +// Topics are now derived directly from ephemeral DH +// +// ============================================================================= \ No newline at end of file diff --git a/packages/sdk/src/verify.ts b/packages/sdk/src/verify.ts index 95472c5..2d0ccbc 100644 --- a/packages/sdk/src/verify.ts +++ b/packages/sdk/src/verify.ts @@ -1,7 +1,11 @@ // packages/sdk/src/verify.ts +// CLEANED VERSION - duplexTopics verification removed + import { JsonRpcProvider, getBytes, hexlify, getAddress } from "ethers"; -import { decryptAndExtractHandshakeKeys, computeTagFromInitiator, verifyDuplexTopicsChecksum, deriveDuplexTopics } from "./crypto.js"; -import { HandshakeLog, HandshakeResponseLog, IdentityProof, TopicInfoWire, DuplexTopics, IdentityContext } from "./types.js"; +import { decryptAndExtractHandshakeKeys, computeTagFromInitiator } from "./crypto.js"; +// REMOVED: verifyDuplexTopicsChecksum, deriveDuplexTopics imports +import { HandshakeLog, HandshakeResponseLog, IdentityProof, IdentityContext } from "./types.js"; +// REMOVED: TopicInfoWire, DuplexTopics from imports import { parseHandshakePayload, parseHandshakeKeys } from "./payload.js"; import { Rpcish, @@ -45,14 +49,6 @@ export async function verifyHandshakeIdentity( return false; } - // // 6492 awareness - // const dp: any = content.identityProof; - // const sigPrimary: string = dp.signature; - // const sig6492: string | undefined = dp.signature6492 ?? dp.erc6492; - // const uses6492 = hasERC6492Suffix(sigPrimary) || !!sig6492; - - // const isContract1271 = await isSmartContract1271(handshakeEvent.sender, provider); - return await verifyIdentityProof( content.identityProof, handshakeEvent.sender, @@ -98,17 +94,11 @@ export async function verifyHandshakeResponseIdentity( return false; } - // 6492 awareness const dpAny: any = extractedResponse.identityProof; if (!dpAny) { console.error("Missing identityProof in handshake response payload"); return false; } - // const sigPrimary: string = dpAny.signature; - // const sig6492: string | undefined = dpAny.signature6492 ?? dpAny.erc6492; - // const uses6492 = hasERC6492Suffix(sigPrimary) || !!sig6492; - - // const isContract1271 = await isSmartContract1271(responseEvent.responder,provider); const expectedKeys = { identityPubKey: extractedResponse.identityPubKey, @@ -204,7 +194,6 @@ export async function verifyIdentityProof( } // anti replay cross chain or cross dapp: - // if ctx.* is provided, require it to be present in the signed message and match. if (typeof ctx?.chainId === "number") { if (typeof parsed.chainId !== "number" || parsed.chainId !== ctx.chainId) { console.error("ChainId mismatch"); @@ -311,35 +300,11 @@ export async function verifyAndExtractHandshakeResponseKeys( }; } -/** - * Verify and derive duplex topics from a long-term DH secret. - * - Accepts either `tag` (inResponseTo) or a raw salt as KDF input. - * - Recomputes topicOut/topicIn deterministically from the identity DH. - * - If topicInfo is provided (from HSR), also verify the checksum. - * - Used by the initiator after decrypting a HandshakeResponse to confirm responderโ€™s topics. - */ -export function verifyDerivedDuplexTopics({ - myIdentitySecretKey, - theirIdentityPubKey, - tag, - salt, - topicInfo -}: { - myIdentitySecretKey: Uint8Array; - theirIdentityPubKey: Uint8Array; - tag?: `0x${string}`; - salt?: Uint8Array; - topicInfo?: TopicInfoWire; -}): { topics: DuplexTopics; ok?: boolean } { - const s = salt ?? (tag ? getBytes(tag) : undefined); - if (!s) throw new Error("Provide either salt or inResponseTo"); - - const { topicOut, topicIn, checksum } = deriveDuplexTopics( - myIdentitySecretKey, - theirIdentityPubKey, - s - ); - - const ok = topicInfo ? verifyDuplexTopicsChecksum(topicOut, topicIn, topicInfo.chk) : undefined; - return { topics: { topicOut, topicIn }, ok }; -} \ No newline at end of file +// ============================================================================= +// REMOVED FUNCTIONS: +// ============================================================================= +// +// verifyDerivedDuplexTopics() - removed, no longer using identity-based topics +// Topics now derive from ephemeral DH in ratchet/kdf.ts +// +// ============================================================================= \ No newline at end of file diff --git a/packages/sdk/test/crypto.test.ts b/packages/sdk/test/crypto.test.ts index c0aee71..4b73e60 100644 --- a/packages/sdk/test/crypto.test.ts +++ b/packages/sdk/test/crypto.test.ts @@ -1,754 +1,754 @@ -import { describe, it, expect } from "vitest"; -import nacl from "tweetnacl"; -import { - encryptMessage, - decryptMessage, - encryptStructuredPayload, - decryptStructuredPayload, - decryptHandshakeResponse, - decryptAndExtractHandshakeKeys, - deriveDuplexTopics, - verifyDuplexTopicsChecksum, -} from "../src/crypto.js"; -import { - HandshakePayload, - encodeHandshakePayload, - decodeHandshakePayload, - encodeHandshakeResponseContent, - decodeHandshakeResponseContent, - MessagePayload, - HandshakeResponseContent, - encodeUnifiedPubKeys, - extractKeysFromHandshakePayload, - extractKeysFromHandshakeResponse, - parseHandshakeKeys, -} from "../src/payload.js"; -import { IdentityProof } from "../src/types.js"; -import type { LogMessage } from "../src/types.js"; - -function randomTagHex(): `0x${string}` { - const b = nacl.randomBytes(32); - return ("0x" + Buffer.from(b).toString("hex")) as `0x${string}`; -} - -describe("Encryption/Decryption", () => { - describe("Message Encryption", () => { - it("should encrypt and decrypt a message successfully", () => { - const senderBoxKey = nacl.box.keyPair(); - const senderSignKey = nacl.sign.keyPair(); - const recipientKey = nacl.box.keyPair(); - const message = "Hello VerbEth!"; - - const encrypted = encryptMessage( - message, - recipientKey.publicKey, - senderBoxKey.secretKey, - senderBoxKey.publicKey, - senderSignKey.secretKey, - senderSignKey.publicKey - ); - - const decrypted = decryptMessage( - encrypted, - recipientKey.secretKey, - senderSignKey.publicKey - ); - expect(decrypted).toBe(message); - }); - - it("should return null on decryption with wrong recipient key", () => { - const senderBoxKey = nacl.box.keyPair(); - const senderSignKey = nacl.sign.keyPair(); - const recipientKey = nacl.box.keyPair(); - const wrongKey = nacl.box.keyPair(); - const message = "Sensitive Info"; - - const encrypted = encryptMessage( - message, - recipientKey.publicKey, - senderBoxKey.secretKey, - senderBoxKey.publicKey, - senderSignKey.secretKey, - senderSignKey.publicKey - ); - - const decrypted = decryptMessage( - encrypted, - wrongKey.secretKey, - senderSignKey.publicKey - ); - expect(decrypted).toBeNull(); - }); - - it("should fail to decrypt if payload is tampered", () => { - const senderBoxKey = nacl.box.keyPair(); - const senderSignKey = nacl.sign.keyPair(); - const recipientKey = nacl.box.keyPair(); - const message = "tamper test"; - - let encrypted = encryptMessage( - message, - recipientKey.publicKey, - senderBoxKey.secretKey, - senderBoxKey.publicKey, - senderSignKey.secretKey, - senderSignKey.publicKey - ); - - const parsed = JSON.parse(encrypted); - parsed.ct = Buffer.from("00".repeat(32), "hex").toString("base64"); - const tampered = JSON.stringify(parsed); - - const decrypted = decryptMessage( - tampered, - recipientKey.secretKey, - senderSignKey.publicKey - ); - expect(decrypted).toBeNull(); - }); - - it("should work with the structured message format", () => { - const senderBoxKey = nacl.box.keyPair(); - const senderSignKey = nacl.sign.keyPair(); - const recipientKey = nacl.box.keyPair(); - - const messagePayload: MessagePayload = { - content: "Hello structured VerbEth!", - timestamp: Date.now(), - messageType: "text", - }; - - const encrypted = encryptStructuredPayload( - messagePayload, - recipientKey.publicKey, - senderBoxKey.secretKey, - senderBoxKey.publicKey, - senderSignKey.secretKey, - senderSignKey.publicKey - ); - - const decrypted = decryptStructuredPayload( - encrypted, - recipientKey.secretKey, - (obj) => obj as MessagePayload, - senderSignKey.publicKey - ); - - expect(decrypted).toEqual(messagePayload); - }); - - it("should encrypt without signing keys (optional parameters)", () => { - const senderBoxKey = nacl.box.keyPair(); - const recipientKey = nacl.box.keyPair(); - const message = "No signature test"; - - const encrypted = encryptMessage( - message, - recipientKey.publicKey, - senderBoxKey.secretKey, - senderBoxKey.publicKey - ); - - const decrypted = decryptMessage(encrypted, recipientKey.secretKey); - expect(decrypted).toBe(message); - }); - - it("should encrypt structured payload without signing keys", () => { - const senderBoxKey = nacl.box.keyPair(); - const recipientKey = nacl.box.keyPair(); - - const messagePayload: MessagePayload = { - content: "Unsigned structured message", - timestamp: Date.now(), - messageType: "text", - }; - - const encrypted = encryptStructuredPayload( - messagePayload, - recipientKey.publicKey, - senderBoxKey.secretKey, - senderBoxKey.publicKey - ); - - const decrypted = decryptStructuredPayload( - encrypted, - recipientKey.secretKey, - (obj) => obj as MessagePayload - ); - - expect(decrypted).toEqual(messagePayload); - }); - }); - - describe("Handshake Response Encryption", () => { - it("should encrypt and decrypt handshake response content", () => { - const initiatorEphemeralKey = nacl.box.keyPair(); - const responderEphemeralKey = nacl.box.keyPair(); - - const identityPubKey = new Uint8Array(32).fill(3); - const signingPubKey = new Uint8Array(32).fill(7); - const unifiedPubKeys = encodeUnifiedPubKeys( - identityPubKey, - signingPubKey - ); - - const ephemeralPubKey = new Uint8Array(32).fill(4); - const note = "here is my response"; - - const identityProof: IdentityProof = { - message: "VerbEth Identity Key Identity v1\nAddress: 0x1234...", - signature: "0x" + "1".repeat(130), - }; - - const responseContent: HandshakeResponseContent = { - unifiedPubKeys, - ephemeralPubKey, - note, - identityProof, - }; - - const encrypted = encryptStructuredPayload( - responseContent, - initiatorEphemeralKey.publicKey, - responderEphemeralKey.secretKey, - responderEphemeralKey.publicKey - ); - - const decrypted = decryptHandshakeResponse( - encrypted, - initiatorEphemeralKey.secretKey - ); - - expect(decrypted).not.toBeNull(); - expect(decrypted!.unifiedPubKeys).toEqual(unifiedPubKeys); - expect(decrypted!.ephemeralPubKey).toEqual(ephemeralPubKey); - expect(decrypted!.note).toBe(note); - expect(decrypted!.identityProof).toEqual(identityProof); - }); - - it("should handle handshake response with identity proof", () => { - const initiatorEphemeralKey = nacl.box.keyPair(); - const responderEphemeralKey = nacl.box.keyPair(); - - const identityPubKey = new Uint8Array(32).fill(5); - const signingPubKey = new Uint8Array(32).fill(8); - const unifiedPubKeys = encodeUnifiedPubKeys( - identityPubKey, - signingPubKey - ); - - const ephemeralPubKey = new Uint8Array(32).fill(6); - - const identityProof: IdentityProof = { - message: "VerbEth Identity Key identity v1\nAddress: 0xabcd...", - signature: "0x" + "2".repeat(130), - }; - - const responseContent: HandshakeResponseContent = { - unifiedPubKeys, - ephemeralPubKey, - note: "with identity proof", - identityProof, - }; - - const encrypted = encryptStructuredPayload( - responseContent, - initiatorEphemeralKey.publicKey, - responderEphemeralKey.secretKey, - responderEphemeralKey.publicKey - ); - - const decrypted = decryptHandshakeResponse( - encrypted, - initiatorEphemeralKey.secretKey - ); - - expect(decrypted).not.toBeNull(); - expect(decrypted!.identityProof).toEqual(identityProof); - }); - }); - - describe("decryptAndExtractHandshakeKeys", () => { - it("should decrypt and extract all keys from handshake response", () => { - const initiatorEphemeralKey = nacl.box.keyPair(); - const responderEphemeralKey = nacl.box.keyPair(); - - const identityPubKey = new Uint8Array(32).fill(10); - const signingPubKey = new Uint8Array(32).fill(11); - const unifiedPubKeys = encodeUnifiedPubKeys( - identityPubKey, - signingPubKey - ); - const ephemeralPubKey = new Uint8Array(32).fill(12); - const note = "convenience function test"; - - const identityProof: IdentityProof = { - message: "VerbEth Identity Key Identity v1\nAddress: 0xtest...", - signature: "0x" + "3".repeat(130), - }; - - const responseContent: HandshakeResponseContent = { - unifiedPubKeys, - ephemeralPubKey, - note, - identityProof, - }; - - const encrypted = encryptStructuredPayload( - responseContent, - initiatorEphemeralKey.publicKey, - responderEphemeralKey.secretKey, - responderEphemeralKey.publicKey - ); - - const result = decryptAndExtractHandshakeKeys( - encrypted, - initiatorEphemeralKey.secretKey - ); - - expect(result).not.toBeNull(); - expect(result!.identityPubKey).toEqual(identityPubKey); - expect(result!.signingPubKey).toEqual(signingPubKey); - expect(result!.ephemeralPubKey).toEqual(ephemeralPubKey); - expect(result!.note).toBe(note); - expect(result!.identityProof).toEqual(identityProof); - }); - - it("should return null for invalid encrypted data", () => { - const initiatorEphemeralKey = nacl.box.keyPair(); - - // Create a valid-looking but unencryptable payload - const invalidPayload = { - v: 1, - epk: Buffer.from(new Uint8Array(32).fill(1)).toString("base64"), - n: Buffer.from(new Uint8Array(24).fill(2)).toString("base64"), - ct: Buffer.from(new Uint8Array(16).fill(3)).toString("base64"), - }; - const invalidEncrypted = JSON.stringify(invalidPayload); - - const result = decryptAndExtractHandshakeKeys( - invalidEncrypted, - initiatorEphemeralKey.secretKey - ); - - expect(result).toBeNull(); - }); - - it("should return null with wrong decryption key", () => { - const initiatorEphemeralKey = nacl.box.keyPair(); - const responderEphemeralKey = nacl.box.keyPair(); - const wrongKey = nacl.box.keyPair(); - - const identityPubKey = new Uint8Array(32).fill(13); - const signingPubKey = new Uint8Array(32).fill(14); - const unifiedPubKeys = encodeUnifiedPubKeys( - identityPubKey, - signingPubKey - ); - - const identityProof: IdentityProof = { - message: "Wrong key test", - signature: "0x" + "4".repeat(130), - }; - - const responseContent: HandshakeResponseContent = { - unifiedPubKeys, - ephemeralPubKey: new Uint8Array(32).fill(15), - note: "should fail", - identityProof, - }; - - const encrypted = encryptStructuredPayload( - responseContent, - initiatorEphemeralKey.publicKey, - responderEphemeralKey.secretKey, - responderEphemeralKey.publicKey - ); - - const result = decryptAndExtractHandshakeKeys( - encrypted, - wrongKey.secretKey - ); - - expect(result).toBeNull(); - }); - }); - - describe("Key Extraction Functions", () => { - it("should extract keys from handshake payload", () => { - const identityPubKey = new Uint8Array(32).fill(20); - const signingPubKey = new Uint8Array(32).fill(21); - const ephemeralPubKey = new Uint8Array(32).fill(22); - const unifiedPubKeys = encodeUnifiedPubKeys( - identityPubKey, - signingPubKey - ); - - const payload: HandshakePayload = { - unifiedPubKeys, - ephemeralPubKey, - plaintextPayload: "test payload", - }; - - const extracted = extractKeysFromHandshakePayload(payload); - - expect(extracted).not.toBeNull(); - expect(extracted!.identityPubKey).toEqual(identityPubKey); - expect(extracted!.signingPubKey).toEqual(signingPubKey); - expect(extracted!.ephemeralPubKey).toEqual(ephemeralPubKey); - }); - - it("should extract keys from handshake response content", () => { - const identityPubKey = new Uint8Array(32).fill(25); - const signingPubKey = new Uint8Array(32).fill(26); - const ephemeralPubKey = new Uint8Array(32).fill(27); - const unifiedPubKeys = encodeUnifiedPubKeys( - identityPubKey, - signingPubKey - ); - - const identityProof: IdentityProof = { - message: "Extract test", - signature: "0x" + "5".repeat(130), - }; - - const content: HandshakeResponseContent = { - unifiedPubKeys, - ephemeralPubKey, - note: "extract test", - identityProof, - }; - - const extracted = extractKeysFromHandshakeResponse(content); - - expect(extracted).not.toBeNull(); - expect(extracted!.identityPubKey).toEqual(identityPubKey); - expect(extracted!.signingPubKey).toEqual(signingPubKey); - expect(extracted!.ephemeralPubKey).toEqual(ephemeralPubKey); - }); - - it("should return null for invalid unified keys in payload", () => { - const invalidUnifiedKeys = new Uint8Array(30).fill(1); // Wrong size - - const payload: HandshakePayload = { - unifiedPubKeys: invalidUnifiedKeys, - ephemeralPubKey: new Uint8Array(32).fill(2), - plaintextPayload: "invalid test", - }; - - const extracted = extractKeysFromHandshakePayload(payload); - expect(extracted).toBeNull(); - }); - - it("should return null for invalid unified keys in response content", () => { - const invalidUnifiedKeys = new Uint8Array(30).fill(1); // Wrong size - - const identityProof: IdentityProof = { - message: "Invalid test", - signature: "0x" + "6".repeat(130), - }; - - const content: HandshakeResponseContent = { - unifiedPubKeys: invalidUnifiedKeys, - ephemeralPubKey: new Uint8Array(32).fill(2), - note: "invalid test", - identityProof, - }; - - const extracted = extractKeysFromHandshakeResponse(content); - expect(extracted).toBeNull(); - }); - }); - - describe("Handshake Key Parsing", () => { - it("should parse handshake keys from event correctly", () => { - const identityPubKey = new Uint8Array(32).fill(30); - const signingPubKey = new Uint8Array(32).fill(31); - const unifiedPubKeys = encodeUnifiedPubKeys( - identityPubKey, - signingPubKey - ); - - const event = { - pubKeys: "0x" + Buffer.from(unifiedPubKeys).toString("hex"), - }; - - const parsed = parseHandshakeKeys(event); - - expect(parsed).not.toBeNull(); - expect(parsed!.identityPubKey).toEqual(identityPubKey); - expect(parsed!.signingPubKey).toEqual(signingPubKey); - }); - - it("should return null for invalid hex in pubKeys", () => { - const event = { - pubKeys: "0xinvalidhex", - }; - - const parsed = parseHandshakeKeys(event); - expect(parsed).toBeNull(); - }); - - it("should return null for wrong size pubKeys", () => { - const shortKeys = new Uint8Array(30).fill(1); // Wrong size - - const event = { - pubKeys: "0x" + Buffer.from(shortKeys).toString("hex"), - }; - - const parsed = parseHandshakeKeys(event); - expect(parsed).toBeNull(); - }); - - it("should handle pubKeys without 0x prefix", () => { - const identityPubKey = new Uint8Array(32).fill(35); - const signingPubKey = new Uint8Array(32).fill(36); - const unifiedPubKeys = encodeUnifiedPubKeys( - identityPubKey, - signingPubKey - ); - - const event = { - pubKeys: "0x" + Buffer.from(unifiedPubKeys).toString("hex"), - }; - - const parsed = parseHandshakeKeys(event); - - expect(parsed).not.toBeNull(); - expect(parsed!.identityPubKey).toEqual(identityPubKey); - expect(parsed!.signingPubKey).toEqual(signingPubKey); - }); - }); - - describe("Error Handling", () => { - it("should throw error for malformed JSON in decryptStructuredPayload", () => { - const recipientKey = nacl.box.keyPair(); - const malformedJson = "invalid json"; - - expect(() => { - decryptStructuredPayload( - malformedJson, - recipientKey.secretKey, - (obj) => obj as MessagePayload - ); - }).toThrow(); - }); - - it("should throw error for missing fields in payload", () => { - const recipientKey = nacl.box.keyPair(); - const incompletePayload = JSON.stringify({ - epk: Buffer.from(new Uint8Array(32)).toString("base64"), - // Missing nonce and ciphertext - }); - - expect(() => { - decryptStructuredPayload( - incompletePayload, - recipientKey.secretKey, - (obj) => obj as MessagePayload - ); - }).toThrow(); - }); - - it("should throw error for invalid base64 in payload fields", () => { - const recipientKey = nacl.box.keyPair(); - const invalidPayload = JSON.stringify({ - epk: "invalid-base64!", - n: "invalid-base64!", - ct: "invalid-base64!", - }); - - expect(() => { - decryptStructuredPayload( - invalidPayload, - recipientKey.secretKey, - (obj) => obj as MessagePayload - ); - }).toThrow(); - }); - - it("should return null when converter function throws error", () => { - const senderBoxKey = nacl.box.keyPair(); - const recipientKey = nacl.box.keyPair(); - - const messagePayload: MessagePayload = { - content: "Test message", - timestamp: Date.now(), - messageType: "text", - }; - - const encrypted = encryptStructuredPayload( - messagePayload, - recipientKey.publicKey, - senderBoxKey.secretKey, - senderBoxKey.publicKey - ); - - // Converter that throws error - const throwingConverter = (obj: any) => { - throw new Error("Converter error"); - }; - - expect(() => { - decryptStructuredPayload( - encrypted, - recipientKey.secretKey, - throwingConverter - ); - }).toThrow("Converter error"); - }); - - it("should throw error for decryptHandshakeResponse with missing identityProof", () => { - const initiatorEphemeralKey = nacl.box.keyPair(); - const responderEphemeralKey = nacl.box.keyPair(); - - // Create content without identityProof - const invalidContent = { - unifiedPubKeys: encodeUnifiedPubKeys( - new Uint8Array(32).fill(40), - new Uint8Array(32).fill(41) - ), - ephemeralPubKey: new Uint8Array(32).fill(42), - note: "missing proof", - // No identityProof - }; - - const encrypted = encryptStructuredPayload( - invalidContent, - initiatorEphemeralKey.publicKey, - responderEphemeralKey.secretKey, - responderEphemeralKey.publicKey - ); - - expect(() => { - decryptHandshakeResponse(encrypted, initiatorEphemeralKey.secretKey); - }).toThrow("Invalid handshake response: missing identityProof"); - }); - }); - - describe("Payload Encoding/Decoding", () => { - it("should encode and decode handshake payload correctly", () => { - const identityPubKey = new Uint8Array(32).fill(1); - const signingPubKey = new Uint8Array(32).fill(9); - const unifiedPubKeys = encodeUnifiedPubKeys( - identityPubKey, - signingPubKey - ); - - const payload: HandshakePayload = { - unifiedPubKeys, - ephemeralPubKey: new Uint8Array(32).fill(2), - plaintextPayload: "hello bob", - }; - - const encoded = encodeHandshakePayload(payload); - const decoded = decodeHandshakePayload(encoded); - - expect(decoded.unifiedPubKeys).toEqual(payload.unifiedPubKeys); - expect(decoded.ephemeralPubKey).toEqual(payload.ephemeralPubKey); - expect(decoded.plaintextPayload).toBe("hello bob"); - }); - - it("should encode and decode response content correctly", () => { - const identityPubKey = new Uint8Array(32).fill(3); - const signingPubKey = new Uint8Array(32).fill(10); - const unifiedPubKeys = encodeUnifiedPubKeys( - identityPubKey, - signingPubKey - ); - - const ephemeralPubKey = new Uint8Array(32).fill(4); - const note = "here is my response"; - - const identityProof: IdentityProof = { - message: "VerbEth Identity Key Identity v1\nAddress: 0xtest...", - signature: "0x" + "3".repeat(130), - }; - - const content: HandshakeResponseContent = { - unifiedPubKeys, - ephemeralPubKey, - note, - identityProof, - }; - - const encoded = encodeHandshakeResponseContent(content); - const decoded = decodeHandshakeResponseContent(encoded); - - expect(decoded.unifiedPubKeys).toEqual(unifiedPubKeys); - expect(decoded.ephemeralPubKey).toEqual(ephemeralPubKey); - expect(decoded.note).toBe(note); - expect(decoded.identityProof).toEqual(identityProof); - }); - }); - - describe("Log Message Structure", () => { - it("should decode and decrypt a log message", () => { - const senderBoxKey = nacl.box.keyPair(); - const senderSignKey = nacl.sign.keyPair(); - const recipientKey = nacl.box.keyPair(); - - const message = "from on-chain log"; - - const ciphertext = encryptMessage( - message, - recipientKey.publicKey, - senderBoxKey.secretKey, - senderBoxKey.publicKey, - senderSignKey.secretKey, - senderSignKey.publicKey - ); - - const mockLog: LogMessage = { - sender: "0x" + "a".repeat(40), - ciphertext, - timestamp: Math.floor(Date.now() / 1000), - topic: "0x" + "d".repeat(64), - nonce: 1n, - }; - - const decrypted = decryptMessage( - mockLog.ciphertext, - recipientKey.secretKey, - senderSignKey.publicKey - ); - expect(decrypted).toBe(message); - }); - }); - - it("derives deterministic duplex topics (Alice & Bob compute the same) and checksum verifies", () => { - const alice = nacl.box.keyPair(); - const bob = nacl.box.keyPair(); - - // Bind topics to a specific handshake via tag (inResponseTo) - const tag = randomTagHex(); - const salt = Uint8Array.from(Buffer.from(tag.slice(2), "hex")); - - // Alice view (my=Alice, their=Bob) - const A = deriveDuplexTopics(alice.secretKey, bob.publicKey, salt); - // Bob view (my=Bob, their=Alice) - const B = deriveDuplexTopics(bob.secretKey, alice.publicKey, salt); - - // Deterministic agreement - expect(A.topicOut).toBe(B.topicOut); - expect(A.topicIn).toBe(B.topicIn); - expect(A.topicOut).not.toBe(A.topicIn); - expect(verifyDuplexTopicsChecksum(A.topicOut, A.topicIn, A.checksum)).toBe( - true - ); - }); - - it("changes in tag/salt produce different topics (per-handshake binding)", () => { - const alice = nacl.box.keyPair(); - const bob = nacl.box.keyPair(); - - const salt1 = Uint8Array.from(Buffer.from(randomTagHex().slice(2), "hex")); - const salt2 = Uint8Array.from(Buffer.from(randomTagHex().slice(2), "hex")); - - const T1 = deriveDuplexTopics(alice.secretKey, bob.publicKey, salt1); - const T2 = deriveDuplexTopics(alice.secretKey, bob.publicKey, salt2); - - expect(T1.topicOut).not.toBe(T2.topicOut); - expect(T1.topicIn).not.toBe(T2.topicIn); - }); -}); +// import { describe, it, expect } from "vitest"; +// import nacl from "tweetnacl"; +// import { +// encryptMessage, +// decryptMessage, +// encryptStructuredPayload, +// decryptStructuredPayload, +// decryptHandshakeResponse, +// decryptAndExtractHandshakeKeys, +// deriveDuplexTopics, +// verifyDuplexTopicsChecksum, +// } from "../src/crypto.js"; +// import { +// HandshakePayload, +// encodeHandshakePayload, +// decodeHandshakePayload, +// encodeHandshakeResponseContent, +// decodeHandshakeResponseContent, +// MessagePayload, +// HandshakeResponseContent, +// encodeUnifiedPubKeys, +// extractKeysFromHandshakePayload, +// extractKeysFromHandshakeResponse, +// parseHandshakeKeys, +// } from "../src/payload.js"; +// import { IdentityProof } from "../src/types.js"; +// import type { LogMessage } from "../src/types.js"; + +// function randomTagHex(): `0x${string}` { +// const b = nacl.randomBytes(32); +// return ("0x" + Buffer.from(b).toString("hex")) as `0x${string}`; +// } + +// describe("Encryption/Decryption", () => { +// describe("Message Encryption", () => { +// it("should encrypt and decrypt a message successfully", () => { +// const senderBoxKey = nacl.box.keyPair(); +// const senderSignKey = nacl.sign.keyPair(); +// const recipientKey = nacl.box.keyPair(); +// const message = "Hello VerbEth!"; + +// const encrypted = encryptMessage( +// message, +// recipientKey.publicKey, +// senderBoxKey.secretKey, +// senderBoxKey.publicKey, +// senderSignKey.secretKey, +// senderSignKey.publicKey +// ); + +// const decrypted = decryptMessage( +// encrypted, +// recipientKey.secretKey, +// senderSignKey.publicKey +// ); +// expect(decrypted).toBe(message); +// }); + +// it("should return null on decryption with wrong recipient key", () => { +// const senderBoxKey = nacl.box.keyPair(); +// const senderSignKey = nacl.sign.keyPair(); +// const recipientKey = nacl.box.keyPair(); +// const wrongKey = nacl.box.keyPair(); +// const message = "Sensitive Info"; + +// const encrypted = encryptMessage( +// message, +// recipientKey.publicKey, +// senderBoxKey.secretKey, +// senderBoxKey.publicKey, +// senderSignKey.secretKey, +// senderSignKey.publicKey +// ); + +// const decrypted = decryptMessage( +// encrypted, +// wrongKey.secretKey, +// senderSignKey.publicKey +// ); +// expect(decrypted).toBeNull(); +// }); + +// it("should fail to decrypt if payload is tampered", () => { +// const senderBoxKey = nacl.box.keyPair(); +// const senderSignKey = nacl.sign.keyPair(); +// const recipientKey = nacl.box.keyPair(); +// const message = "tamper test"; + +// let encrypted = encryptMessage( +// message, +// recipientKey.publicKey, +// senderBoxKey.secretKey, +// senderBoxKey.publicKey, +// senderSignKey.secretKey, +// senderSignKey.publicKey +// ); + +// const parsed = JSON.parse(encrypted); +// parsed.ct = Buffer.from("00".repeat(32), "hex").toString("base64"); +// const tampered = JSON.stringify(parsed); + +// const decrypted = decryptMessage( +// tampered, +// recipientKey.secretKey, +// senderSignKey.publicKey +// ); +// expect(decrypted).toBeNull(); +// }); + +// it("should work with the structured message format", () => { +// const senderBoxKey = nacl.box.keyPair(); +// const senderSignKey = nacl.sign.keyPair(); +// const recipientKey = nacl.box.keyPair(); + +// const messagePayload: MessagePayload = { +// content: "Hello structured VerbEth!", +// timestamp: Date.now(), +// messageType: "text", +// }; + +// const encrypted = encryptStructuredPayload( +// messagePayload, +// recipientKey.publicKey, +// senderBoxKey.secretKey, +// senderBoxKey.publicKey, +// senderSignKey.secretKey, +// senderSignKey.publicKey +// ); + +// const decrypted = decryptStructuredPayload( +// encrypted, +// recipientKey.secretKey, +// (obj) => obj as MessagePayload, +// senderSignKey.publicKey +// ); + +// expect(decrypted).toEqual(messagePayload); +// }); + +// it("should encrypt without signing keys (optional parameters)", () => { +// const senderBoxKey = nacl.box.keyPair(); +// const recipientKey = nacl.box.keyPair(); +// const message = "No signature test"; + +// const encrypted = encryptMessage( +// message, +// recipientKey.publicKey, +// senderBoxKey.secretKey, +// senderBoxKey.publicKey +// ); + +// const decrypted = decryptMessage(encrypted, recipientKey.secretKey); +// expect(decrypted).toBe(message); +// }); + +// it("should encrypt structured payload without signing keys", () => { +// const senderBoxKey = nacl.box.keyPair(); +// const recipientKey = nacl.box.keyPair(); + +// const messagePayload: MessagePayload = { +// content: "Unsigned structured message", +// timestamp: Date.now(), +// messageType: "text", +// }; + +// const encrypted = encryptStructuredPayload( +// messagePayload, +// recipientKey.publicKey, +// senderBoxKey.secretKey, +// senderBoxKey.publicKey +// ); + +// const decrypted = decryptStructuredPayload( +// encrypted, +// recipientKey.secretKey, +// (obj) => obj as MessagePayload +// ); + +// expect(decrypted).toEqual(messagePayload); +// }); +// }); + +// describe("Handshake Response Encryption", () => { +// it("should encrypt and decrypt handshake response content", () => { +// const initiatorEphemeralKey = nacl.box.keyPair(); +// const responderEphemeralKey = nacl.box.keyPair(); + +// const identityPubKey = new Uint8Array(32).fill(3); +// const signingPubKey = new Uint8Array(32).fill(7); +// const unifiedPubKeys = encodeUnifiedPubKeys( +// identityPubKey, +// signingPubKey +// ); + +// const ephemeralPubKey = new Uint8Array(32).fill(4); +// const note = "here is my response"; + +// const identityProof: IdentityProof = { +// message: "VerbEth Identity Key Identity v1\nAddress: 0x1234...", +// signature: "0x" + "1".repeat(130), +// }; + +// const responseContent: HandshakeResponseContent = { +// unifiedPubKeys, +// ephemeralPubKey, +// note, +// identityProof, +// }; + +// const encrypted = encryptStructuredPayload( +// responseContent, +// initiatorEphemeralKey.publicKey, +// responderEphemeralKey.secretKey, +// responderEphemeralKey.publicKey +// ); + +// const decrypted = decryptHandshakeResponse( +// encrypted, +// initiatorEphemeralKey.secretKey +// ); + +// expect(decrypted).not.toBeNull(); +// expect(decrypted!.unifiedPubKeys).toEqual(unifiedPubKeys); +// expect(decrypted!.ephemeralPubKey).toEqual(ephemeralPubKey); +// expect(decrypted!.note).toBe(note); +// expect(decrypted!.identityProof).toEqual(identityProof); +// }); + +// it("should handle handshake response with identity proof", () => { +// const initiatorEphemeralKey = nacl.box.keyPair(); +// const responderEphemeralKey = nacl.box.keyPair(); + +// const identityPubKey = new Uint8Array(32).fill(5); +// const signingPubKey = new Uint8Array(32).fill(8); +// const unifiedPubKeys = encodeUnifiedPubKeys( +// identityPubKey, +// signingPubKey +// ); + +// const ephemeralPubKey = new Uint8Array(32).fill(6); + +// const identityProof: IdentityProof = { +// message: "VerbEth Identity Key identity v1\nAddress: 0xabcd...", +// signature: "0x" + "2".repeat(130), +// }; + +// const responseContent: HandshakeResponseContent = { +// unifiedPubKeys, +// ephemeralPubKey, +// note: "with identity proof", +// identityProof, +// }; + +// const encrypted = encryptStructuredPayload( +// responseContent, +// initiatorEphemeralKey.publicKey, +// responderEphemeralKey.secretKey, +// responderEphemeralKey.publicKey +// ); + +// const decrypted = decryptHandshakeResponse( +// encrypted, +// initiatorEphemeralKey.secretKey +// ); + +// expect(decrypted).not.toBeNull(); +// expect(decrypted!.identityProof).toEqual(identityProof); +// }); +// }); + +// describe("decryptAndExtractHandshakeKeys", () => { +// it("should decrypt and extract all keys from handshake response", () => { +// const initiatorEphemeralKey = nacl.box.keyPair(); +// const responderEphemeralKey = nacl.box.keyPair(); + +// const identityPubKey = new Uint8Array(32).fill(10); +// const signingPubKey = new Uint8Array(32).fill(11); +// const unifiedPubKeys = encodeUnifiedPubKeys( +// identityPubKey, +// signingPubKey +// ); +// const ephemeralPubKey = new Uint8Array(32).fill(12); +// const note = "convenience function test"; + +// const identityProof: IdentityProof = { +// message: "VerbEth Identity Key Identity v1\nAddress: 0xtest...", +// signature: "0x" + "3".repeat(130), +// }; + +// const responseContent: HandshakeResponseContent = { +// unifiedPubKeys, +// ephemeralPubKey, +// note, +// identityProof, +// }; + +// const encrypted = encryptStructuredPayload( +// responseContent, +// initiatorEphemeralKey.publicKey, +// responderEphemeralKey.secretKey, +// responderEphemeralKey.publicKey +// ); + +// const result = decryptAndExtractHandshakeKeys( +// encrypted, +// initiatorEphemeralKey.secretKey +// ); + +// expect(result).not.toBeNull(); +// expect(result!.identityPubKey).toEqual(identityPubKey); +// expect(result!.signingPubKey).toEqual(signingPubKey); +// expect(result!.ephemeralPubKey).toEqual(ephemeralPubKey); +// expect(result!.note).toBe(note); +// expect(result!.identityProof).toEqual(identityProof); +// }); + +// it("should return null for invalid encrypted data", () => { +// const initiatorEphemeralKey = nacl.box.keyPair(); + +// // Create a valid-looking but unencryptable payload +// const invalidPayload = { +// v: 1, +// epk: Buffer.from(new Uint8Array(32).fill(1)).toString("base64"), +// n: Buffer.from(new Uint8Array(24).fill(2)).toString("base64"), +// ct: Buffer.from(new Uint8Array(16).fill(3)).toString("base64"), +// }; +// const invalidEncrypted = JSON.stringify(invalidPayload); + +// const result = decryptAndExtractHandshakeKeys( +// invalidEncrypted, +// initiatorEphemeralKey.secretKey +// ); + +// expect(result).toBeNull(); +// }); + +// it("should return null with wrong decryption key", () => { +// const initiatorEphemeralKey = nacl.box.keyPair(); +// const responderEphemeralKey = nacl.box.keyPair(); +// const wrongKey = nacl.box.keyPair(); + +// const identityPubKey = new Uint8Array(32).fill(13); +// const signingPubKey = new Uint8Array(32).fill(14); +// const unifiedPubKeys = encodeUnifiedPubKeys( +// identityPubKey, +// signingPubKey +// ); + +// const identityProof: IdentityProof = { +// message: "Wrong key test", +// signature: "0x" + "4".repeat(130), +// }; + +// const responseContent: HandshakeResponseContent = { +// unifiedPubKeys, +// ephemeralPubKey: new Uint8Array(32).fill(15), +// note: "should fail", +// identityProof, +// }; + +// const encrypted = encryptStructuredPayload( +// responseContent, +// initiatorEphemeralKey.publicKey, +// responderEphemeralKey.secretKey, +// responderEphemeralKey.publicKey +// ); + +// const result = decryptAndExtractHandshakeKeys( +// encrypted, +// wrongKey.secretKey +// ); + +// expect(result).toBeNull(); +// }); +// }); + +// describe("Key Extraction Functions", () => { +// it("should extract keys from handshake payload", () => { +// const identityPubKey = new Uint8Array(32).fill(20); +// const signingPubKey = new Uint8Array(32).fill(21); +// const ephemeralPubKey = new Uint8Array(32).fill(22); +// const unifiedPubKeys = encodeUnifiedPubKeys( +// identityPubKey, +// signingPubKey +// ); + +// const payload: HandshakePayload = { +// unifiedPubKeys, +// ephemeralPubKey, +// plaintextPayload: "test payload", +// }; + +// const extracted = extractKeysFromHandshakePayload(payload); + +// expect(extracted).not.toBeNull(); +// expect(extracted!.identityPubKey).toEqual(identityPubKey); +// expect(extracted!.signingPubKey).toEqual(signingPubKey); +// expect(extracted!.ephemeralPubKey).toEqual(ephemeralPubKey); +// }); + +// it("should extract keys from handshake response content", () => { +// const identityPubKey = new Uint8Array(32).fill(25); +// const signingPubKey = new Uint8Array(32).fill(26); +// const ephemeralPubKey = new Uint8Array(32).fill(27); +// const unifiedPubKeys = encodeUnifiedPubKeys( +// identityPubKey, +// signingPubKey +// ); + +// const identityProof: IdentityProof = { +// message: "Extract test", +// signature: "0x" + "5".repeat(130), +// }; + +// const content: HandshakeResponseContent = { +// unifiedPubKeys, +// ephemeralPubKey, +// note: "extract test", +// identityProof, +// }; + +// const extracted = extractKeysFromHandshakeResponse(content); + +// expect(extracted).not.toBeNull(); +// expect(extracted!.identityPubKey).toEqual(identityPubKey); +// expect(extracted!.signingPubKey).toEqual(signingPubKey); +// expect(extracted!.ephemeralPubKey).toEqual(ephemeralPubKey); +// }); + +// it("should return null for invalid unified keys in payload", () => { +// const invalidUnifiedKeys = new Uint8Array(30).fill(1); // Wrong size + +// const payload: HandshakePayload = { +// unifiedPubKeys: invalidUnifiedKeys, +// ephemeralPubKey: new Uint8Array(32).fill(2), +// plaintextPayload: "invalid test", +// }; + +// const extracted = extractKeysFromHandshakePayload(payload); +// expect(extracted).toBeNull(); +// }); + +// it("should return null for invalid unified keys in response content", () => { +// const invalidUnifiedKeys = new Uint8Array(30).fill(1); // Wrong size + +// const identityProof: IdentityProof = { +// message: "Invalid test", +// signature: "0x" + "6".repeat(130), +// }; + +// const content: HandshakeResponseContent = { +// unifiedPubKeys: invalidUnifiedKeys, +// ephemeralPubKey: new Uint8Array(32).fill(2), +// note: "invalid test", +// identityProof, +// }; + +// const extracted = extractKeysFromHandshakeResponse(content); +// expect(extracted).toBeNull(); +// }); +// }); + +// describe("Handshake Key Parsing", () => { +// it("should parse handshake keys from event correctly", () => { +// const identityPubKey = new Uint8Array(32).fill(30); +// const signingPubKey = new Uint8Array(32).fill(31); +// const unifiedPubKeys = encodeUnifiedPubKeys( +// identityPubKey, +// signingPubKey +// ); + +// const event = { +// pubKeys: "0x" + Buffer.from(unifiedPubKeys).toString("hex"), +// }; + +// const parsed = parseHandshakeKeys(event); + +// expect(parsed).not.toBeNull(); +// expect(parsed!.identityPubKey).toEqual(identityPubKey); +// expect(parsed!.signingPubKey).toEqual(signingPubKey); +// }); + +// it("should return null for invalid hex in pubKeys", () => { +// const event = { +// pubKeys: "0xinvalidhex", +// }; + +// const parsed = parseHandshakeKeys(event); +// expect(parsed).toBeNull(); +// }); + +// it("should return null for wrong size pubKeys", () => { +// const shortKeys = new Uint8Array(30).fill(1); // Wrong size + +// const event = { +// pubKeys: "0x" + Buffer.from(shortKeys).toString("hex"), +// }; + +// const parsed = parseHandshakeKeys(event); +// expect(parsed).toBeNull(); +// }); + +// it("should handle pubKeys without 0x prefix", () => { +// const identityPubKey = new Uint8Array(32).fill(35); +// const signingPubKey = new Uint8Array(32).fill(36); +// const unifiedPubKeys = encodeUnifiedPubKeys( +// identityPubKey, +// signingPubKey +// ); + +// const event = { +// pubKeys: "0x" + Buffer.from(unifiedPubKeys).toString("hex"), +// }; + +// const parsed = parseHandshakeKeys(event); + +// expect(parsed).not.toBeNull(); +// expect(parsed!.identityPubKey).toEqual(identityPubKey); +// expect(parsed!.signingPubKey).toEqual(signingPubKey); +// }); +// }); + +// describe("Error Handling", () => { +// it("should throw error for malformed JSON in decryptStructuredPayload", () => { +// const recipientKey = nacl.box.keyPair(); +// const malformedJson = "invalid json"; + +// expect(() => { +// decryptStructuredPayload( +// malformedJson, +// recipientKey.secretKey, +// (obj) => obj as MessagePayload +// ); +// }).toThrow(); +// }); + +// it("should throw error for missing fields in payload", () => { +// const recipientKey = nacl.box.keyPair(); +// const incompletePayload = JSON.stringify({ +// epk: Buffer.from(new Uint8Array(32)).toString("base64"), +// // Missing nonce and ciphertext +// }); + +// expect(() => { +// decryptStructuredPayload( +// incompletePayload, +// recipientKey.secretKey, +// (obj) => obj as MessagePayload +// ); +// }).toThrow(); +// }); + +// it("should throw error for invalid base64 in payload fields", () => { +// const recipientKey = nacl.box.keyPair(); +// const invalidPayload = JSON.stringify({ +// epk: "invalid-base64!", +// n: "invalid-base64!", +// ct: "invalid-base64!", +// }); + +// expect(() => { +// decryptStructuredPayload( +// invalidPayload, +// recipientKey.secretKey, +// (obj) => obj as MessagePayload +// ); +// }).toThrow(); +// }); + +// it("should return null when converter function throws error", () => { +// const senderBoxKey = nacl.box.keyPair(); +// const recipientKey = nacl.box.keyPair(); + +// const messagePayload: MessagePayload = { +// content: "Test message", +// timestamp: Date.now(), +// messageType: "text", +// }; + +// const encrypted = encryptStructuredPayload( +// messagePayload, +// recipientKey.publicKey, +// senderBoxKey.secretKey, +// senderBoxKey.publicKey +// ); + +// // Converter that throws error +// const throwingConverter = (obj: any) => { +// throw new Error("Converter error"); +// }; + +// expect(() => { +// decryptStructuredPayload( +// encrypted, +// recipientKey.secretKey, +// throwingConverter +// ); +// }).toThrow("Converter error"); +// }); + +// it("should throw error for decryptHandshakeResponse with missing identityProof", () => { +// const initiatorEphemeralKey = nacl.box.keyPair(); +// const responderEphemeralKey = nacl.box.keyPair(); + +// // Create content without identityProof +// const invalidContent = { +// unifiedPubKeys: encodeUnifiedPubKeys( +// new Uint8Array(32).fill(40), +// new Uint8Array(32).fill(41) +// ), +// ephemeralPubKey: new Uint8Array(32).fill(42), +// note: "missing proof", +// // No identityProof +// }; + +// const encrypted = encryptStructuredPayload( +// invalidContent, +// initiatorEphemeralKey.publicKey, +// responderEphemeralKey.secretKey, +// responderEphemeralKey.publicKey +// ); + +// expect(() => { +// decryptHandshakeResponse(encrypted, initiatorEphemeralKey.secretKey); +// }).toThrow("Invalid handshake response: missing identityProof"); +// }); +// }); + +// describe("Payload Encoding/Decoding", () => { +// it("should encode and decode handshake payload correctly", () => { +// const identityPubKey = new Uint8Array(32).fill(1); +// const signingPubKey = new Uint8Array(32).fill(9); +// const unifiedPubKeys = encodeUnifiedPubKeys( +// identityPubKey, +// signingPubKey +// ); + +// const payload: HandshakePayload = { +// unifiedPubKeys, +// ephemeralPubKey: new Uint8Array(32).fill(2), +// plaintextPayload: "hello bob", +// }; + +// const encoded = encodeHandshakePayload(payload); +// const decoded = decodeHandshakePayload(encoded); + +// expect(decoded.unifiedPubKeys).toEqual(payload.unifiedPubKeys); +// expect(decoded.ephemeralPubKey).toEqual(payload.ephemeralPubKey); +// expect(decoded.plaintextPayload).toBe("hello bob"); +// }); + +// it("should encode and decode response content correctly", () => { +// const identityPubKey = new Uint8Array(32).fill(3); +// const signingPubKey = new Uint8Array(32).fill(10); +// const unifiedPubKeys = encodeUnifiedPubKeys( +// identityPubKey, +// signingPubKey +// ); + +// const ephemeralPubKey = new Uint8Array(32).fill(4); +// const note = "here is my response"; + +// const identityProof: IdentityProof = { +// message: "VerbEth Identity Key Identity v1\nAddress: 0xtest...", +// signature: "0x" + "3".repeat(130), +// }; + +// const content: HandshakeResponseContent = { +// unifiedPubKeys, +// ephemeralPubKey, +// note, +// identityProof, +// }; + +// const encoded = encodeHandshakeResponseContent(content); +// const decoded = decodeHandshakeResponseContent(encoded); + +// expect(decoded.unifiedPubKeys).toEqual(unifiedPubKeys); +// expect(decoded.ephemeralPubKey).toEqual(ephemeralPubKey); +// expect(decoded.note).toBe(note); +// expect(decoded.identityProof).toEqual(identityProof); +// }); +// }); + +// describe("Log Message Structure", () => { +// it("should decode and decrypt a log message", () => { +// const senderBoxKey = nacl.box.keyPair(); +// const senderSignKey = nacl.sign.keyPair(); +// const recipientKey = nacl.box.keyPair(); + +// const message = "from on-chain log"; + +// const ciphertext = encryptMessage( +// message, +// recipientKey.publicKey, +// senderBoxKey.secretKey, +// senderBoxKey.publicKey, +// senderSignKey.secretKey, +// senderSignKey.publicKey +// ); + +// const mockLog: LogMessage = { +// sender: "0x" + "a".repeat(40), +// ciphertext, +// timestamp: Math.floor(Date.now() / 1000), +// topic: "0x" + "d".repeat(64), +// nonce: 1n, +// }; + +// const decrypted = decryptMessage( +// mockLog.ciphertext, +// recipientKey.secretKey, +// senderSignKey.publicKey +// ); +// expect(decrypted).toBe(message); +// }); +// }); + +// it("derives deterministic duplex topics (Alice & Bob compute the same) and checksum verifies", () => { +// const alice = nacl.box.keyPair(); +// const bob = nacl.box.keyPair(); + +// // Bind topics to a specific handshake via tag (inResponseTo) +// const tag = randomTagHex(); +// const salt = Uint8Array.from(Buffer.from(tag.slice(2), "hex")); + +// // Alice view (my=Alice, their=Bob) +// const A = deriveDuplexTopics(alice.secretKey, bob.publicKey, salt); +// // Bob view (my=Bob, their=Alice) +// const B = deriveDuplexTopics(bob.secretKey, alice.publicKey, salt); + +// // Deterministic agreement +// expect(A.topicOut).toBe(B.topicOut); +// expect(A.topicIn).toBe(B.topicIn); +// expect(A.topicOut).not.toBe(A.topicIn); +// expect(verifyDuplexTopicsChecksum(A.topicOut, A.topicIn, A.checksum)).toBe( +// true +// ); +// }); + +// it("changes in tag/salt produce different topics (per-handshake binding)", () => { +// const alice = nacl.box.keyPair(); +// const bob = nacl.box.keyPair(); + +// const salt1 = Uint8Array.from(Buffer.from(randomTagHex().slice(2), "hex")); +// const salt2 = Uint8Array.from(Buffer.from(randomTagHex().slice(2), "hex")); + +// const T1 = deriveDuplexTopics(alice.secretKey, bob.publicKey, salt1); +// const T2 = deriveDuplexTopics(alice.secretKey, bob.publicKey, salt2); + +// expect(T1.topicOut).not.toBe(T2.topicOut); +// expect(T1.topicIn).not.toBe(T2.topicIn); +// }); +// }); diff --git a/packages/sdk/test/utils.test.ts b/packages/sdk/test/utils.test.ts index 1625299..07e19b9 100644 --- a/packages/sdk/test/utils.test.ts +++ b/packages/sdk/test/utils.test.ts @@ -1,108 +1,108 @@ -import { describe, it, expect, vi } from "vitest"; -import nacl from "tweetnacl"; -import { JsonRpcProvider } from "ethers"; - -import { getNextNonce } from "../src/utils/nonce.js"; -import { convertPublicKeyToX25519 } from "../src/utils/x25519.js"; -import { isSmartContract1271, parseBindingMessage } from "../src/utils.js"; -import { ExecutorFactory } from "../src/index.js"; -import type { LogChainV1 } from "@verbeth/contracts/typechain-types"; - -const fakeProvider = { - async getCode(addr: string) { - return addr === "0xCcโ€ฆCc" ? "0x60016000" : "0x"; - }, - async call() { - return "0x1626ba7e" + "0".repeat(56); - }, - async resolveName(name: string) { - return name; - }, -} as unknown as JsonRpcProvider; - - -describe("getNextNonce", () => { - it("increments per (sender, topic) and returns bigint", () => { - const n1 = getNextNonce("0xAlice", "topic"); - const n2 = getNextNonce("0xAlice", "topic"); - const nOther = getNextNonce("0xBob", "topic"); - expect(n2).toBe(n1 + 1n); - expect(nOther).toBe(1n); - }); -}); - -describe("Utils Functions", () => { - it("isSmartContract1271 returns true for contract bytecode", async () => { - expect(await isSmartContract1271("0xCcโ€ฆCc", fakeProvider)).toBe(true); - expect(await isSmartContract1271("0xEeโ€ฆEe", fakeProvider)).toBe(false); - }); - - it("convertPublicKeyToX25519 returns 32-byte key", () => { - const raw = new Uint8Array(64).fill(1); - const out = convertPublicKeyToX25519(raw); - expect(out).toHaveLength(32); - }); -}); - - -describe("Unified Keys Utilities", () => { - it("should handle unified key operations", () => { - expect(typeof isSmartContract1271).toBe("function"); - }); -}); - -describe("parseBindingMessage", () => { - it("parses a well-formed binding message", () => { - const msg = [ - "VerbEth Key Binding v1", - "Address: 0x1234567890abcdef1234567890abcdef12345678", - "PkEd25519: 0x" + "11".repeat(32), - "PkX25519: 0x" + "22".repeat(32), - "Context: verbeth", - "Version: 1", - "ChainId: 8453", - "RpId: example.com", - ].join("\n"); - - const parsed = parseBindingMessage(msg); - - expect(parsed.header).toBe("VerbEth Key Binding v1"); - expect(parsed.address?.toLowerCase()).toBe("0x1234567890abcdef1234567890abcdef12345678"); - expect(parsed.pkEd25519).toBe("0x" + "11".repeat(32)); - expect(parsed.pkX25519).toBe("0x" + "22".repeat(32)); - expect(parsed.context).toBe("verbeth"); - expect(parsed.version).toBe("1"); - expect(parsed.chainId).toBe(8453); - expect(parsed.rpId).toBe("example.com"); - }); - - it("handles missing optional fields", () => { - const msg = [ - "VerbEth Key Binding v1", - "Address: 0xabcdefabcdefabcdefabcdefabcdefabcdefabcd", - ].join("\n"); - - const parsed = parseBindingMessage(msg); - - expect(parsed.header).toBe("VerbEth Key Binding v1"); - expect(parsed.address?.toLowerCase()).toBe("0xabcdefabcdefabcdefabcdefabcdefabcdefabcd"); - - expect(parsed.pkEd25519).toBeUndefined(); - expect(parsed.pkX25519).toBeUndefined(); - expect(parsed.context).toBeUndefined(); - expect(parsed.version).toBeUndefined(); - expect(parsed.chainId).toBeUndefined(); - expect(parsed.rpId).toBeUndefined(); - }); - - it("ignores lines without ':'", () => { - const msg = [ - "VerbEth Key Binding v1", - "This line has no colon", - "Address: 0x1234567890abcdef1234567890abcdef12345678", - ].join("\n"); - - const parsed = parseBindingMessage(msg); - expect(parsed.address?.toLowerCase()).toBe("0x1234567890abcdef1234567890abcdef12345678"); - }); -}); \ No newline at end of file +// import { describe, it, expect, vi } from "vitest"; +// import nacl from "tweetnacl"; +// import { JsonRpcProvider } from "ethers"; + +// import { getNextNonce } from "../src/utils/nonce.js"; +// import { convertPublicKeyToX25519 } from "../src/utils/x25519.js"; +// import { isSmartContract1271, parseBindingMessage } from "../src/utils.js"; +// import { ExecutorFactory } from "../src/index.js"; +// import type { LogChainV1 } from "@verbeth/contracts/typechain-types"; + +// const fakeProvider = { +// async getCode(addr: string) { +// return addr === "0xCcโ€ฆCc" ? "0x60016000" : "0x"; +// }, +// async call() { +// return "0x1626ba7e" + "0".repeat(56); +// }, +// async resolveName(name: string) { +// return name; +// }, +// } as unknown as JsonRpcProvider; + + +// describe("getNextNonce", () => { +// it("increments per (sender, topic) and returns bigint", () => { +// const n1 = getNextNonce("0xAlice", "topic"); +// const n2 = getNextNonce("0xAlice", "topic"); +// const nOther = getNextNonce("0xBob", "topic"); +// expect(n2).toBe(n1 + 1n); +// expect(nOther).toBe(1n); +// }); +// }); + +// describe("Utils Functions", () => { +// it("isSmartContract1271 returns true for contract bytecode", async () => { +// expect(await isSmartContract1271("0xCcโ€ฆCc", fakeProvider)).toBe(true); +// expect(await isSmartContract1271("0xEeโ€ฆEe", fakeProvider)).toBe(false); +// }); + +// it("convertPublicKeyToX25519 returns 32-byte key", () => { +// const raw = new Uint8Array(64).fill(1); +// const out = convertPublicKeyToX25519(raw); +// expect(out).toHaveLength(32); +// }); +// }); + + +// describe("Unified Keys Utilities", () => { +// it("should handle unified key operations", () => { +// expect(typeof isSmartContract1271).toBe("function"); +// }); +// }); + +// describe("parseBindingMessage", () => { +// it("parses a well-formed binding message", () => { +// const msg = [ +// "VerbEth Key Binding v1", +// "Address: 0x1234567890abcdef1234567890abcdef12345678", +// "PkEd25519: 0x" + "11".repeat(32), +// "PkX25519: 0x" + "22".repeat(32), +// "Context: verbeth", +// "Version: 1", +// "ChainId: 8453", +// "RpId: example.com", +// ].join("\n"); + +// const parsed = parseBindingMessage(msg); + +// expect(parsed.header).toBe("VerbEth Key Binding v1"); +// expect(parsed.address?.toLowerCase()).toBe("0x1234567890abcdef1234567890abcdef12345678"); +// expect(parsed.pkEd25519).toBe("0x" + "11".repeat(32)); +// expect(parsed.pkX25519).toBe("0x" + "22".repeat(32)); +// expect(parsed.context).toBe("verbeth"); +// expect(parsed.version).toBe("1"); +// expect(parsed.chainId).toBe(8453); +// expect(parsed.rpId).toBe("example.com"); +// }); + +// it("handles missing optional fields", () => { +// const msg = [ +// "VerbEth Key Binding v1", +// "Address: 0xabcdefabcdefabcdefabcdefabcdefabcdefabcd", +// ].join("\n"); + +// const parsed = parseBindingMessage(msg); + +// expect(parsed.header).toBe("VerbEth Key Binding v1"); +// expect(parsed.address?.toLowerCase()).toBe("0xabcdefabcdefabcdefabcdefabcdefabcdefabcd"); + +// expect(parsed.pkEd25519).toBeUndefined(); +// expect(parsed.pkX25519).toBeUndefined(); +// expect(parsed.context).toBeUndefined(); +// expect(parsed.version).toBeUndefined(); +// expect(parsed.chainId).toBeUndefined(); +// expect(parsed.rpId).toBeUndefined(); +// }); + +// it("ignores lines without ':'", () => { +// const msg = [ +// "VerbEth Key Binding v1", +// "This line has no colon", +// "Address: 0x1234567890abcdef1234567890abcdef12345678", +// ].join("\n"); + +// const parsed = parseBindingMessage(msg); +// expect(parsed.address?.toLowerCase()).toBe("0x1234567890abcdef1234567890abcdef12345678"); +// }); +// }); \ No newline at end of file diff --git a/packages/sdk/test/verify.test.ts b/packages/sdk/test/verify.test.ts index 31a9fca..12e5d29 100644 --- a/packages/sdk/test/verify.test.ts +++ b/packages/sdk/test/verify.test.ts @@ -1,355 +1,355 @@ -import { describe, it, expect } from "vitest"; -import { Wallet, HDNodeWallet, keccak256, toUtf8Bytes, hexlify } from "ethers"; -import nacl from "tweetnacl"; - -import { - verifyIdentityProof, - verifyHandshakeIdentity, - verifyHandshakeResponseIdentity, - verifyDerivedDuplexTopics, -} from "../src/verify.js"; -import { encryptStructuredPayload, deriveDuplexTopics } from "../src/crypto.js"; -import { - HandshakeResponseContent, - encodeUnifiedPubKeys, - parseHandshakeKeys, -} from "../src/payload.js"; -import { - IdentityProof, - HandshakeLog, - HandshakeResponseLog, -} from "../src/types.js"; -import { deriveIdentityWithUnifiedKeys } from "../src/identity.js"; - -const mockProvider: any = { - async request({ method, params }: { method: string; params?: any[] }) { - if (method === "eth_getCode") { - const address = params?.[0]; - return address && address.startsWith("0xCc") ? "0x60016000" : "0x"; - } - if (method === "eth_call") { - return "0x1"; - } - if (method === "eth_chainId") { - return "0x1"; - } - throw new Error("Unsupported method: " + method); - }, -}; - -function toBytes(hex: `0x${string}`): Uint8Array { - return Uint8Array.from(Buffer.from(hex.slice(2), "hex")); -} -function randomTagHex(): `0x${string}` { - const b = nacl.randomBytes(32); - return ("0x" + Buffer.from(b).toString("hex")) as `0x${string}`; -} - -function mockSafeAddress(eoaAddress: string): string { - const hash = keccak256(toUtf8Bytes("mock-safe:" + eoaAddress.toLowerCase())); - return "0x" + hash.slice(26); // take last 20 bytes (40 hex chars) -} - -describe("Verify Identity & Handshake (Unified)", () => { - describe("Identity Proof Verification", () => { - it("OK with correct unified keys", async () => { - const wallet: HDNodeWallet = Wallet.createRandom(); - const safeAddr = mockSafeAddress(wallet.address); +// import { describe, it, expect } from "vitest"; +// import { Wallet, HDNodeWallet, keccak256, toUtf8Bytes, hexlify } from "ethers"; +// import nacl from "tweetnacl"; + +// import { +// verifyIdentityProof, +// verifyHandshakeIdentity, +// verifyHandshakeResponseIdentity, +// verifyDerivedDuplexTopics, +// } from "../src/verify.js"; +// import { encryptStructuredPayload, deriveDuplexTopics } from "../src/crypto.js"; +// import { +// HandshakeResponseContent, +// encodeUnifiedPubKeys, +// parseHandshakeKeys, +// } from "../src/payload.js"; +// import { +// IdentityProof, +// HandshakeLog, +// HandshakeResponseLog, +// } from "../src/types.js"; +// import { deriveIdentityWithUnifiedKeys } from "../src/identity.js"; + +// const mockProvider: any = { +// async request({ method, params }: { method: string; params?: any[] }) { +// if (method === "eth_getCode") { +// const address = params?.[0]; +// return address && address.startsWith("0xCc") ? "0x60016000" : "0x"; +// } +// if (method === "eth_call") { +// return "0x1"; +// } +// if (method === "eth_chainId") { +// return "0x1"; +// } +// throw new Error("Unsupported method: " + method); +// }, +// }; + +// function toBytes(hex: `0x${string}`): Uint8Array { +// return Uint8Array.from(Buffer.from(hex.slice(2), "hex")); +// } +// function randomTagHex(): `0x${string}` { +// const b = nacl.randomBytes(32); +// return ("0x" + Buffer.from(b).toString("hex")) as `0x${string}`; +// } + +// function mockSafeAddress(eoaAddress: string): string { +// const hash = keccak256(toUtf8Bytes("mock-safe:" + eoaAddress.toLowerCase())); +// return "0x" + hash.slice(26); // take last 20 bytes (40 hex chars) +// } + +// describe("Verify Identity & Handshake (Unified)", () => { +// describe("Identity Proof Verification", () => { +// it("OK with correct unified keys", async () => { +// const wallet: HDNodeWallet = Wallet.createRandom(); +// const safeAddr = mockSafeAddress(wallet.address); - const { identityProof, identityPubKey, signingPubKey } = - await deriveIdentityWithUnifiedKeys(wallet, wallet.address, safeAddr); - - // Verify against the Safe address (executor) - const result = await verifyIdentityProof( - identityProof, - safeAddr, - { identityPubKey, signingPubKey }, - mockProvider - ); - - expect(result).toBe(true); - }); - - it("KO with wrong address", async () => { - const wallet1: HDNodeWallet = Wallet.createRandom(); - const wallet2: HDNodeWallet = Wallet.createRandom(); - const safeAddr1 = mockSafeAddress(wallet1.address); - const safeAddr2 = mockSafeAddress(wallet2.address); +// const { identityProof, identityPubKey, signingPubKey } = +// await deriveIdentityWithUnifiedKeys(wallet, wallet.address, safeAddr); + +// // Verify against the Safe address (executor) +// const result = await verifyIdentityProof( +// identityProof, +// safeAddr, +// { identityPubKey, signingPubKey }, +// mockProvider +// ); + +// expect(result).toBe(true); +// }); + +// it("KO with wrong address", async () => { +// const wallet1: HDNodeWallet = Wallet.createRandom(); +// const wallet2: HDNodeWallet = Wallet.createRandom(); +// const safeAddr1 = mockSafeAddress(wallet1.address); +// const safeAddr2 = mockSafeAddress(wallet2.address); - const { identityProof, identityPubKey, signingPubKey } = - await deriveIdentityWithUnifiedKeys(wallet1, wallet1.address, safeAddr1); - - // Verify against wrong Safe address - const result = await verifyIdentityProof( - identityProof, - safeAddr2, - { identityPubKey, signingPubKey }, - mockProvider - ); - - expect(result).toBe(false); - }); - - it("KO with wrong keys", async () => { - const wallet: HDNodeWallet = Wallet.createRandom(); - const safeAddr = mockSafeAddress(wallet.address); +// const { identityProof, identityPubKey, signingPubKey } = +// await deriveIdentityWithUnifiedKeys(wallet1, wallet1.address, safeAddr1); + +// // Verify against wrong Safe address +// const result = await verifyIdentityProof( +// identityProof, +// safeAddr2, +// { identityPubKey, signingPubKey }, +// mockProvider +// ); + +// expect(result).toBe(false); +// }); + +// it("KO with wrong keys", async () => { +// const wallet: HDNodeWallet = Wallet.createRandom(); +// const safeAddr = mockSafeAddress(wallet.address); - const { identityProof } = await deriveIdentityWithUnifiedKeys( - wallet, - wallet.address, - safeAddr - ); - - const wrongKeys = { - identityPubKey: new Uint8Array(32).fill(0xaa), - signingPubKey: new Uint8Array(32).fill(0xbb), - }; - - const result = await verifyIdentityProof( - identityProof, - safeAddr, - wrongKeys, - mockProvider - ); - - expect(result).toBe(false); - }); - }); - - describe("Handshake Verification", () => { - it("EOA flow with unified keys", async () => { - const wallet: HDNodeWallet = Wallet.createRandom(); - const safeAddr = mockSafeAddress(wallet.address); +// const { identityProof } = await deriveIdentityWithUnifiedKeys( +// wallet, +// wallet.address, +// safeAddr +// ); + +// const wrongKeys = { +// identityPubKey: new Uint8Array(32).fill(0xaa), +// signingPubKey: new Uint8Array(32).fill(0xbb), +// }; + +// const result = await verifyIdentityProof( +// identityProof, +// safeAddr, +// wrongKeys, +// mockProvider +// ); + +// expect(result).toBe(false); +// }); +// }); + +// describe("Handshake Verification", () => { +// it("EOA flow with unified keys", async () => { +// const wallet: HDNodeWallet = Wallet.createRandom(); +// const safeAddr = mockSafeAddress(wallet.address); - const { identityProof, unifiedPubKeys } = - await deriveIdentityWithUnifiedKeys(wallet, wallet.address, safeAddr); - - // Sender is the Safe address (since Safe sends the tx) - const handshakeEvent: HandshakeLog = { - recipientHash: keccak256(toUtf8Bytes("contact:0xdead")), - sender: safeAddr, - pubKeys: hexlify(unifiedPubKeys), - ephemeralPubKey: hexlify(nacl.box.keyPair().publicKey), - plaintextPayload: JSON.stringify({ - plaintextPayload: "Hi VerbEth", - identityProof, - }), - }; - - const result = await verifyHandshakeIdentity( - handshakeEvent, - mockProvider - ); - expect(result).toBe(true); - }); - - it("fails with invalid identity proof", async () => { - const wallet: HDNodeWallet = Wallet.createRandom(); - const safeAddr = mockSafeAddress(wallet.address); +// const { identityProof, unifiedPubKeys } = +// await deriveIdentityWithUnifiedKeys(wallet, wallet.address, safeAddr); + +// // Sender is the Safe address (since Safe sends the tx) +// const handshakeEvent: HandshakeLog = { +// recipientHash: keccak256(toUtf8Bytes("contact:0xdead")), +// sender: safeAddr, +// pubKeys: hexlify(unifiedPubKeys), +// ephemeralPubKey: hexlify(nacl.box.keyPair().publicKey), +// plaintextPayload: JSON.stringify({ +// plaintextPayload: "Hi VerbEth", +// identityProof, +// }), +// }; + +// const result = await verifyHandshakeIdentity( +// handshakeEvent, +// mockProvider +// ); +// expect(result).toBe(true); +// }); + +// it("fails with invalid identity proof", async () => { +// const wallet: HDNodeWallet = Wallet.createRandom(); +// const safeAddr = mockSafeAddress(wallet.address); - const { unifiedPubKeys } = await deriveIdentityWithUnifiedKeys( - wallet, - wallet.address, - safeAddr - ); - - const differentWallet: HDNodeWallet = Wallet.createRandom(); - const invalidMessage = "Invalid message for verification"; - const invalidSignature = await differentWallet.signMessage( - invalidMessage - ); - - const invalidIdentityProof: IdentityProof = { - message: invalidMessage, - signature: invalidSignature, - }; - - const handshakeEvent: HandshakeLog = { - recipientHash: keccak256(toUtf8Bytes("contact:0xdead")), - sender: safeAddr, - pubKeys: hexlify(unifiedPubKeys), - ephemeralPubKey: hexlify(nacl.box.keyPair().publicKey), - plaintextPayload: JSON.stringify({ - plaintextPayload: "Hi VerbEth", - identityProof: invalidIdentityProof, - }), - }; - - const result = await verifyHandshakeIdentity( - handshakeEvent, - mockProvider - ); - expect(result).toBe(false); - }); - }); - - describe("Handshake Response Verification", () => { - it("EOA flow with unified keys", async () => { - const responderWallet: HDNodeWallet = Wallet.createRandom(); - const responderSafeAddr = mockSafeAddress(responderWallet.address); +// const { unifiedPubKeys } = await deriveIdentityWithUnifiedKeys( +// wallet, +// wallet.address, +// safeAddr +// ); + +// const differentWallet: HDNodeWallet = Wallet.createRandom(); +// const invalidMessage = "Invalid message for verification"; +// const invalidSignature = await differentWallet.signMessage( +// invalidMessage +// ); + +// const invalidIdentityProof: IdentityProof = { +// message: invalidMessage, +// signature: invalidSignature, +// }; + +// const handshakeEvent: HandshakeLog = { +// recipientHash: keccak256(toUtf8Bytes("contact:0xdead")), +// sender: safeAddr, +// pubKeys: hexlify(unifiedPubKeys), +// ephemeralPubKey: hexlify(nacl.box.keyPair().publicKey), +// plaintextPayload: JSON.stringify({ +// plaintextPayload: "Hi VerbEth", +// identityProof: invalidIdentityProof, +// }), +// }; + +// const result = await verifyHandshakeIdentity( +// handshakeEvent, +// mockProvider +// ); +// expect(result).toBe(false); +// }); +// }); + +// describe("Handshake Response Verification", () => { +// it("EOA flow with unified keys", async () => { +// const responderWallet: HDNodeWallet = Wallet.createRandom(); +// const responderSafeAddr = mockSafeAddress(responderWallet.address); - const { identityProof, identityPubKey, unifiedPubKeys } = - await deriveIdentityWithUnifiedKeys( - responderWallet, - responderWallet.address, - responderSafeAddr - ); - - const aliceEphemeral = nacl.box.keyPair(); - const responderEphemeral = nacl.box.keyPair(); - - const responseContent: HandshakeResponseContent = { - unifiedPubKeys, - ephemeralPubKey: responderEphemeral.publicKey, - note: "pong", - identityProof, - }; - - const payload = encryptStructuredPayload( - responseContent, - aliceEphemeral.publicKey, - responderEphemeral.secretKey, - responderEphemeral.publicKey - ); - - // Responder is the Safe address - const responseEvent: HandshakeResponseLog = { - inResponseTo: keccak256(toUtf8Bytes("test-handshake")), - responder: responderSafeAddr, - responderEphemeralR: hexlify(responderEphemeral.publicKey), - ciphertext: payload, - }; - - const result = await verifyHandshakeResponseIdentity( - responseEvent, - identityPubKey, - aliceEphemeral.secretKey, - mockProvider - ); - - expect(result).toBe(true); - }); - - it("fails with wrong identity key", async () => { - const responderWallet: HDNodeWallet = Wallet.createRandom(); - const responderSafeAddr = mockSafeAddress(responderWallet.address); +// const { identityProof, identityPubKey, unifiedPubKeys } = +// await deriveIdentityWithUnifiedKeys( +// responderWallet, +// responderWallet.address, +// responderSafeAddr +// ); + +// const aliceEphemeral = nacl.box.keyPair(); +// const responderEphemeral = nacl.box.keyPair(); + +// const responseContent: HandshakeResponseContent = { +// unifiedPubKeys, +// ephemeralPubKey: responderEphemeral.publicKey, +// note: "pong", +// identityProof, +// }; + +// const payload = encryptStructuredPayload( +// responseContent, +// aliceEphemeral.publicKey, +// responderEphemeral.secretKey, +// responderEphemeral.publicKey +// ); + +// // Responder is the Safe address +// const responseEvent: HandshakeResponseLog = { +// inResponseTo: keccak256(toUtf8Bytes("test-handshake")), +// responder: responderSafeAddr, +// responderEphemeralR: hexlify(responderEphemeral.publicKey), +// ciphertext: payload, +// }; + +// const result = await verifyHandshakeResponseIdentity( +// responseEvent, +// identityPubKey, +// aliceEphemeral.secretKey, +// mockProvider +// ); + +// expect(result).toBe(true); +// }); + +// it("fails with wrong identity key", async () => { +// const responderWallet: HDNodeWallet = Wallet.createRandom(); +// const responderSafeAddr = mockSafeAddress(responderWallet.address); - const { identityProof, unifiedPubKeys } = - await deriveIdentityWithUnifiedKeys( - responderWallet, - responderWallet.address, - responderSafeAddr - ); - - const aliceEphemeral = nacl.box.keyPair(); - const responderEphemeral = nacl.box.keyPair(); - - const responseContent: HandshakeResponseContent = { - unifiedPubKeys, - ephemeralPubKey: responderEphemeral.publicKey, - note: "pong", - identityProof, - }; - - const payload = encryptStructuredPayload( - responseContent, - aliceEphemeral.publicKey, - responderEphemeral.secretKey, - responderEphemeral.publicKey - ); - - const responseEvent: HandshakeResponseLog = { - inResponseTo: keccak256(toUtf8Bytes("test-handshake")), - responder: responderSafeAddr, - responderEphemeralR: hexlify(responderEphemeral.publicKey), - ciphertext: payload, - }; - - const wrongIdentityKey = new Uint8Array(32).fill(0xff); - - const result = await verifyHandshakeResponseIdentity( - responseEvent, - wrongIdentityKey, - aliceEphemeral.secretKey, - mockProvider - ); - - expect(result).toBe(false); - }); - }); - - describe("Key Parsing", () => { - it("parseHandshakeKeys extracts unified keys correctly", () => { - const identityPubKey = new Uint8Array(32).fill(1); - const signingPubKey = new Uint8Array(32).fill(2); - const unifiedPubKeys = encodeUnifiedPubKeys( - identityPubKey, - signingPubKey - ); - - const event = { pubKeys: hexlify(unifiedPubKeys) }; - const parsed = parseHandshakeKeys(event); - - expect(parsed).not.toBeNull(); - expect(parsed!.identityPubKey).toEqual(identityPubKey); - expect(parsed!.signingPubKey).toEqual(signingPubKey); - }); - - it("parseHandshakeKeys returns null for invalid keys", () => { - const event = { pubKeys: "0x1234" }; - const parsed = parseHandshakeKeys(event); - expect(parsed).toBeNull(); - }); - }); - - it("verifyDerivedDuplexTopics accepts tag hex and validates checksum from TopicInfo", () => { - const alice = nacl.box.keyPair(); - const bob = nacl.box.keyPair(); - - const tag = randomTagHex(); - const salt = toBytes(tag); - - // Bob would embed TopicInfo in HSR - const { topicOut, topicIn, checksum } = deriveDuplexTopics( - bob.secretKey, - alice.publicKey, - salt - ); - const topicInfo = { out: topicOut, in: topicIn, chk: checksum }; - - // Alice verifies after decrypting HSR - const { topics, ok } = verifyDerivedDuplexTopics({ - myIdentitySecretKey: alice.secretKey, - theirIdentityPubKey: bob.publicKey, - tag, - topicInfo, - }); - - expect(ok).toBe(true); - expect(topics.topicOut).toBe(topicOut); - expect(topics.topicIn).toBe(topicIn); - }); - - it("verifyDerivedDuplexTopics works with raw salt (no tag) and throws with neither", () => { - const alice = nacl.box.keyPair(); - const bob = nacl.box.keyPair(); - - const salt = toBytes(randomTagHex()); - - const { topics } = verifyDerivedDuplexTopics({ - myIdentitySecretKey: alice.secretKey, - theirIdentityPubKey: bob.publicKey, - salt, - }); - - expect(topics.topicOut.startsWith("0x")).toBe(true); - expect(topics.topicIn.startsWith("0x")).toBe(true); - - expect(() => - verifyDerivedDuplexTopics({ - myIdentitySecretKey: alice.secretKey, - theirIdentityPubKey: bob.publicKey, - } as any) - ).toThrow(); - }); -}); \ No newline at end of file +// const { identityProof, unifiedPubKeys } = +// await deriveIdentityWithUnifiedKeys( +// responderWallet, +// responderWallet.address, +// responderSafeAddr +// ); + +// const aliceEphemeral = nacl.box.keyPair(); +// const responderEphemeral = nacl.box.keyPair(); + +// const responseContent: HandshakeResponseContent = { +// unifiedPubKeys, +// ephemeralPubKey: responderEphemeral.publicKey, +// note: "pong", +// identityProof, +// }; + +// const payload = encryptStructuredPayload( +// responseContent, +// aliceEphemeral.publicKey, +// responderEphemeral.secretKey, +// responderEphemeral.publicKey +// ); + +// const responseEvent: HandshakeResponseLog = { +// inResponseTo: keccak256(toUtf8Bytes("test-handshake")), +// responder: responderSafeAddr, +// responderEphemeralR: hexlify(responderEphemeral.publicKey), +// ciphertext: payload, +// }; + +// const wrongIdentityKey = new Uint8Array(32).fill(0xff); + +// const result = await verifyHandshakeResponseIdentity( +// responseEvent, +// wrongIdentityKey, +// aliceEphemeral.secretKey, +// mockProvider +// ); + +// expect(result).toBe(false); +// }); +// }); + +// describe("Key Parsing", () => { +// it("parseHandshakeKeys extracts unified keys correctly", () => { +// const identityPubKey = new Uint8Array(32).fill(1); +// const signingPubKey = new Uint8Array(32).fill(2); +// const unifiedPubKeys = encodeUnifiedPubKeys( +// identityPubKey, +// signingPubKey +// ); + +// const event = { pubKeys: hexlify(unifiedPubKeys) }; +// const parsed = parseHandshakeKeys(event); + +// expect(parsed).not.toBeNull(); +// expect(parsed!.identityPubKey).toEqual(identityPubKey); +// expect(parsed!.signingPubKey).toEqual(signingPubKey); +// }); + +// it("parseHandshakeKeys returns null for invalid keys", () => { +// const event = { pubKeys: "0x1234" }; +// const parsed = parseHandshakeKeys(event); +// expect(parsed).toBeNull(); +// }); +// }); + +// it("verifyDerivedDuplexTopics accepts tag hex and validates checksum from TopicInfo", () => { +// const alice = nacl.box.keyPair(); +// const bob = nacl.box.keyPair(); + +// const tag = randomTagHex(); +// const salt = toBytes(tag); + +// // Bob would embed TopicInfo in HSR +// const { topicOut, topicIn, checksum } = deriveDuplexTopics( +// bob.secretKey, +// alice.publicKey, +// salt +// ); +// const topicInfo = { out: topicOut, in: topicIn, chk: checksum }; + +// // Alice verifies after decrypting HSR +// const { topics, ok } = verifyDerivedDuplexTopics({ +// myIdentitySecretKey: alice.secretKey, +// theirIdentityPubKey: bob.publicKey, +// tag, +// topicInfo, +// }); + +// expect(ok).toBe(true); +// expect(topics.topicOut).toBe(topicOut); +// expect(topics.topicIn).toBe(topicIn); +// }); + +// it("verifyDerivedDuplexTopics works with raw salt (no tag) and throws with neither", () => { +// const alice = nacl.box.keyPair(); +// const bob = nacl.box.keyPair(); + +// const salt = toBytes(randomTagHex()); + +// const { topics } = verifyDerivedDuplexTopics({ +// myIdentitySecretKey: alice.secretKey, +// theirIdentityPubKey: bob.publicKey, +// salt, +// }); + +// expect(topics.topicOut.startsWith("0x")).toBe(true); +// expect(topics.topicIn.startsWith("0x")).toBe(true); + +// expect(() => +// verifyDerivedDuplexTopics({ +// myIdentitySecretKey: alice.secretKey, +// theirIdentityPubKey: bob.publicKey, +// } as any) +// ).toThrow(); +// }); +// }); \ No newline at end of file diff --git a/plan(done).md b/plan(done).md deleted file mode 100644 index 4fc167c..0000000 --- a/plan(done).md +++ /dev/null @@ -1,241 +0,0 @@ -# Verbeth SDK: Double Ratchet Implementation Plan - -## Overview - -This plan implements Signal-style Double Ratchet for bilateral forward secrecy and topic unlinkability. Compromising identity keys never allows decrypting past messagesโ€”not even message 0. - -**Scope**: Core Double Ratchet only. Post-quantum are separate future phases. - ---- - -## 1. Key Design Decisions - -### 1.1 Ephemeral-Only Initial Secret - -**Traditional Signal**: Initial secret includes identity keys โ†’ identity compromise exposes message 0. - -**Verbeth**: Initial secret is `DH(AliceEphemeral, BobRatchetEphemeral)` ONLY. -- No identity keys in initial secret -- Authentication via Ed25519 signatures on every message -- Identity compromise never decrypts any messages - -### 1.2 Two-Keypair Handshake (Unlinkability) - -Bob's `respondToHandshake` generates TWO separate keypairs: - -| Keypair | Purpose | Location | -|---------|---------|----------| -| `tagKeyPair (R, r)` | Compute `inResponseTo` tag | `R` on-chain as `responderEphemeralR` | -| `ratchetKeyPair` | First DH ratchet key | Public key inside encrypted payload | - -**Why**: Single keypair would let observers link `HandshakeResponse.R` to first message's DH header. With separation, no on-chain link exists between handshake and conversation. - -### 1.3 Session Keyed by Topics - -Sessions keyed by `conversationId = keccak256(sort([topicOut, topicIn]))`, not addresses. - -```typescript -interface RatchetSession { - conversationId: string; - topicOutbound: `0x${string}`; - topicInbound: `0x${string}`; - // ... ratchet state -} -``` - -Lookup: `session where topicInbound === event.topic` - -### 1.4 Immediate Session Commit (Skip-Key Resilient) - -**Original design**: Two-phase commit with sequential blocking. - -**Implemented design**: Immediate session commit after encryption. - -``` -1. Load session (from cache or DB) -2. Compute (nextState, header, ciphertext) -3. Save nextState to DB IMMEDIATELY -4. Send transaction -5. On SUCCESS: clean up pending record -6. On FAILURE: ratchet "slot" is burned, receiver handles via skip keys -``` - -**Why this works**: -- The ratchet protocol is designed for message loss -- Receivers handle gaps via skip-key mechanism -- Saving session immediately ensures subsequent messages use the advanced state -- Matches how Signal handles message failures - -### 1.5 Auth-Before-Ratchet (DoS Protection) - -**Attack**: Malicious `pn=999999, n=999999` forces millions of key derivations. - -**Defense**: Verify Ed25519 signature BEFORE any ratchet work. - -``` -1. Parse sig + header + ciphertext -2. Verify Ed25519(sig, header || ct, contact.signingPubKey) -3. IF invalid: reject (O(1) cost) -4. THEN attempt ratchet decrypt -``` - -### 1.6 Binary Encoding -Fixed overhead: ~105 bytes (vs ~200+ for JSON+base64). - -### 1.7 Skipped Keys: Reorg Tolerance, Not Offline Catch-Up - -**Common misconception**: Skipped keys handle offline periods. - -**Reality**: -- **Offline catch-up**: Process chain logs in order โ†’ chain key advances sequentially โ†’ no skipped keys -- **Skipped keys**: Handle block reorgs, out-of-order RPC responses, and failed transactions - -| Concept | Purpose | -|---------|---------| -| Chain key derivation | Sequential catch-up after offline | -| Skipped keys | Out-of-order delivery + tx failure tolerance | - -Bounds: -- `MAX_STORED_SKIPPED_KEYS = 1000` (memory limit) -- `MAX_SKIPPED_KEYS_AGE_MS = 24h` (TTL) - ---- - -## 2. State Loss & Recovery - -### 2.1 The Forward Secrecy Tradeoff - -**Fundamental truth**: Forward secrecy means lost local state = lost messages. - -The ratchet state is: -- **Stateful**: Each message advances the state irreversibly -- **Local-only**: Not stored on-chain or derivable from identity -- **Critical**: Without it, decryption is impossible - -### 2.2 When State Loss Occurs - -| Scenario | What's Lost | Recovery Path | -|----------|-------------|---------------| -| Browser IndexedDB cleared | Everything | Re-handshake all contacts | -| New device, same identity | Everything | Re-handshake all contacts | -| Corrupted database | Depends | Re-handshake affected contacts | -| Export then Import | Nothing | Seamless (ratchet state preserved) | - -### 2.3 Recovery: Just Re-Handshake - -No special "reset protocol" needed. The existing handshake flow handles recovery: - -``` -Alice (lost state) โ†’ sendHandshake(bob) โ†’ Bob accepts โ†’ New session -``` - -- New ephemeral keys generate new salt โ†’ new topics -- Old ratchet session orphaned in Bob's DB (harmless) -- Both parties continue with fresh session - -**UX implication**: Alice must manually re-initiate contact with each peer. This is acceptable; cloud sync (future) would eliminate this friction. - ---- - -# DH-Synchronized Topic Ratcheting - -Static topics enable long-term correlation of conversations by on-chain observers. Even with encrypted content, the repeated `topic` parameter in `MessageSent` events creates a linkable pattern. - -## Solution: DH-Synchronized Topic Ratcheting - -Derive new topics whenever a DH ratchet step occurs. The DH public key in message headers provides natural synchronizationโ€”both parties know when to rotate topics without additional coordination. - -## Key Insight - -The existing Double Ratchet already: -- Generates new DH keypairs on each turn (in `dhRatchetStep()`) -- Tracks `dhMyPublicKey` and `dhTheirPublicKey` -- Triggers on first message after receiving a new DH public key - -**Topic epochs = DH epochs.** When `dhTheirPublicKey` changes, derive new topics. - ---- - -# Security Notes - -1. **Deterministic** โ€” Both parties derive identical topics from `dhSend` -2. **No extra metadata** โ€” Epoch not transmitted; derived from DH state -3. **Unlinkable** โ€” After first DH step, new topic has no on-chain link to handshake -4. **Grace period** โ€” Prevents message loss without adding latency ---- - -## 4. Future Improvements - -### 4.1 Cloud Sync (Planned) - -**Problem**: Device loss = data loss. - -**Solution**: Encrypted cloud backup of full database state. - -``` -โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” -โ”‚ CLOUD SYNC FLOW โ”‚ -โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค -โ”‚ 1. Derive backup key: HKDF(identitySeed, "verbeth-backup") โ”‚ -โ”‚ 2. Serialize: { contacts, messages, ratchetSessions, ... } โ”‚ -โ”‚ 3. Encrypt: AES-GCM(backupKey, serializedData) โ”‚ -โ”‚ 4. Upload to user's cloud storage (Drive/iCloud/S3) โ”‚ -โ”‚ 5. On new device: download, decrypt, import โ”‚ -โ”‚ 6. Ratchet state restored โ†’ no reset needed โ”‚ -โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ -``` - -**Key properties**: -- Backup key derived from identity โ†’ only owner can decrypt -- Cloud provider never sees plaintext -- Backup includes ratchet state โ†’ seamless device migration -- Optional: encrypted sync on every state change - -**Implementation scope**: Separate feature, not part of core ratchet. - -### 4.2 Topic Ratcheting (Phase 2) - -Periodic topic rotation for enhanced metadata privacy. - -### 4.3 Post-Quantum (Phase 3) - -ML-KEM hybrid for quantum resistance. - ---- - -## 5. Success Criteria - -### Cryptographic โœ… -- [x] Identity key compromise never decrypts past messages (including message 0) -- [x] Post-compromise security: session recovers after key compromise -- [x] DoS resistance: unauthenticated messages rejected in O(1) -- [x] Unlinkability: on-chain R โ‰  message DH headers - -### State Management โœ… -- [x] Immediate session commit with skip-key resilience -- [x] Session caching: in-memory cache + DB persistence -- [x] Session keyed by topics (not addresses) -- [x] Confirmation matching by txHash - -### Resilience โœ… -- [x] Long offline periods: process in order, no skipped keys needed -- [x] Skipped keys for reorg tolerance (24h TTL) -- [x] Batch message processing with shared session cache - -### Session Reset โณ DEFERRED (handled implicitly by existing handshake) -- [x] New handshake to existing contact creates fresh session -- [x] Old session orphaned (no functional impact) -- [ ] *(Nice-to-have)* Detect missing sessions on startup -- [ ] *(Nice-to-have)* UI hint for "existing contact requests new session" -- [ ] *(Nice-to-have)* Cleanup orphaned sessions - ---- - -## 6. What's NOT in Scope - -| Feature | Phase | -|---------|-------| -| Topic ratcheting | Phase 2 | -| Post-quantum (ML-KEM) | Phase 3 | -| Cloud sync | Future | -| Export/import encryption | Future (current export is plaintext JSON) | \ No newline at end of file From 47c5994e7fa981be4807c7df84b5fcbd03f87e63 Mon Sep 17 00:00:00 2001 From: Marco Esposito Date: Sat, 17 Jan 2026 12:00:09 +0100 Subject: [PATCH 16/51] cleaning removed duplex topics --- apps/demo/src/hooks/useChatActions.ts | 39 +- apps/demo/src/hooks/useMessageProcessor.ts | 15 +- .../src/services/EventProcessorService.ts | 46 +- packages/sdk/src/client/VerbethClient.ts | 156 +- packages/sdk/src/client/index.ts | 7 +- packages/sdk/test/crypto.test.ts | 1333 +++++++---------- packages/sdk/test/utils.test.ts | 216 +-- packages/sdk/test/verify.test.ts | 934 +++++++----- 8 files changed, 1431 insertions(+), 1315 deletions(-) diff --git a/apps/demo/src/hooks/useChatActions.ts b/apps/demo/src/hooks/useChatActions.ts index 0326dac..14763af 100644 --- a/apps/demo/src/hooks/useChatActions.ts +++ b/apps/demo/src/hooks/useChatActions.ts @@ -1,5 +1,5 @@ // src/hooks/useChatActions.ts -// CLEANED VERSION - pickOutboundTopic removed, topics come directly from SDK +// CLEANED VERSION - uses VerbethClient for all session creation /** * Chat Actions Hook. @@ -10,17 +10,12 @@ * - Retry/cancel failed messages * - Queue status management * - * CHANGE: acceptHandshake now receives topics directly from VerbethClient - * instead of using pickOutboundTopic on duplexTopics. + * Uses VerbethClient for session creation. */ import { useCallback } from "react"; import { hexlify } from "ethers"; -import { - // REMOVED: pickOutboundTopic - no longer needed - VerbethClient, - initSessionAsResponder, -} from "@verbeth/sdk"; +import type { VerbethClient } from "@verbeth/sdk"; import { dbService } from "../services/DbService.js"; import { Contact, @@ -162,9 +157,7 @@ export const useChatActions = ({ /** * Accept a handshake from another user. - * Creates ratchet session and establishes contact. - * - * UPDATED: Now receives topicOutbound/topicInbound directly from SDK + * Creates ratchet session using VerbethClient and establishes contact. */ const acceptHandshake = useCallback( async (handshake: any, responseMessage: string) => { @@ -175,10 +168,7 @@ export const useChatActions = ({ try { const { - tx, - // CHANGED: Now receive topics directly instead of duplexTopics - topicOutbound, - topicInbound, + salt, responderEphemeralSecret, responderEphemeralPublic, } = await verbethClient.acceptHandshake( @@ -187,20 +177,13 @@ export const useChatActions = ({ responseMessage ); - // REMOVED: Topic selection via pickOutboundTopic - // const topicOutbound = pickOutboundTopic(false, duplexTopics); - // const topicInbound = pickOutboundTopic(true, duplexTopics); - - // Topics now come directly from the SDK - - const ratchetSession = initSessionAsResponder({ - myAddress: verbethClient.userAddress, + // Create session using VerbethClient (handles topic derivation internally) + const ratchetSession = verbethClient.createResponderSession({ contactAddress: handshake.sender, - myResponderEphemeralSecret: responderEphemeralSecret, - myResponderEphemeralPublic: responderEphemeralPublic, - theirHandshakeEphemeralPubKey: handshake.ephemeralPubKey, - topicOutbound, - topicInbound, + responderEphemeralSecret, + responderEphemeralPublic, + initiatorEphemeralPubKey: handshake.ephemeralPubKey, + salt, }); // Save session - SDK will pick it up via SessionStore adapter diff --git a/apps/demo/src/hooks/useMessageProcessor.ts b/apps/demo/src/hooks/useMessageProcessor.ts index 7ec75ce..269c5c1 100644 --- a/apps/demo/src/hooks/useMessageProcessor.ts +++ b/apps/demo/src/hooks/useMessageProcessor.ts @@ -6,8 +6,7 @@ * Manages messaging state (messages, contacts, pendingHandshakes) and * orchestrates event processing via EventProcessorService. * - * SIMPLIFIED: Event processing now uses VerbethClient which handles - * session management internally. + * Uses VerbethClient for session management and decryption. */ import { useState, useEffect, useCallback } from "react"; @@ -78,7 +77,7 @@ export const useMessageProcessor = ({ }, [address, onLog]); // =========================================================================== - // Event Processing - SIMPLIFIED + // Event Processing // =========================================================================== const processEvents = useCallback( @@ -116,11 +115,11 @@ export const useMessageProcessor = ({ } // ----------------------------------------------------------------- - // HANDSHAKE RESPONSE + // HANDSHAKE RESPONSE - requires verbethClient for session creation // ----------------------------------------------------------------- case "handshake_response": { - if (!identityKeyPair) { - onLog(`โŒ Cannot process handshake response: identityKeyPair is null`); + if (!identityKeyPair || !verbethClient) { + onLog(`โŒ Cannot process handshake response: missing dependencies`); break; } @@ -128,8 +127,8 @@ export const useMessageProcessor = ({ event, address, readProvider, - identityKeyPair, identityContext, + verbethClient, onLog ); @@ -193,8 +192,6 @@ export const useMessageProcessor = ({ } } } - - // Note: No need to persist session cache anymore - SDK handles it internally }, [address, readProvider, identityKeyPair, identityContext, emitterAddress, verbethClient, onLog] ); diff --git a/apps/demo/src/services/EventProcessorService.ts b/apps/demo/src/services/EventProcessorService.ts index d04fc97..944df45 100644 --- a/apps/demo/src/services/EventProcessorService.ts +++ b/apps/demo/src/services/EventProcessorService.ts @@ -1,31 +1,22 @@ // src/services/EventProcessorService.ts -// CLEANED VERSION - duplexTopics removed, topics derived from ephemeral DH +// CLEANED VERSION - uses VerbethClient for session creation /** * Event Processing Service. * * Handles decoding, verification, decryption, and persistence of blockchain events. - * Uses VerbethClient SDK methods for simplified session management. - * - * CHANGE: processHandshakeResponseEvent now derives topics from ephemeral DH - * instead of using verifyDerivedDuplexTopics. + * Uses VerbethClient SDK methods for session management and topic derivation. */ import { AbiCoder, getBytes } from "ethers"; import { type IdentityContext, - type IdentityKeyPair, type VerbethClient, parseHandshakePayload, parseBindingMessage, verifyHandshakeIdentity, decodeUnifiedPubKeys, verifyAndExtractHandshakeResponseKeys, - // REMOVED: pickOutboundTopic - initSessionAsInitiator, - // NEW: for topic derivation - dh, - deriveTopicFromDH, } from "@verbeth/sdk"; import { dbService } from "./DbService.js"; @@ -212,15 +203,15 @@ export async function processHandshakeEvent( // ============================================================================= // Handshake Response Processing -// UPDATED: Now derives topics from ephemeral DH instead of identity keys +// Uses VerbethClient.createInitiatorSession for topic derivation // ============================================================================= export async function processHandshakeResponseEvent( event: ProcessedEvent, address: string, readProvider: any, - identityKeyPair: IdentityKeyPair, identityContext: IdentityContext, + verbethClient: VerbethClient, onLog: (msg: string) => void ): Promise { try { @@ -272,24 +263,13 @@ export async function processHandshakeResponseEvent( } // ========================================================================= - // NEW: Derive initial topics from ephemeral shared secret - // This replaces the old verifyDerivedDuplexTopics + pickOutboundTopic + // Create session using VerbethClient (handles topic derivation internally) // ========================================================================= - const ephemeralShared = dh(initiatorEphemeralSecret, result.keys.ephemeralPubKey); - const salt = getBytes(inResponseTo); // Use tag as salt - - // Topics are derived from initiator's perspective (no swap needed here) - const topicOutbound = deriveTopicFromDH(ephemeralShared, 'outbound', salt); - const topicInbound = deriveTopicFromDH(ephemeralShared, 'inbound', salt); - - // Initialize ratchet session as initiator - const ratchetSession = initSessionAsInitiator({ - myAddress: address, + const ratchetSession = verbethClient.createInitiatorSession({ contactAddress: contact.address, - myHandshakeEphemeralSecret: initiatorEphemeralSecret, - theirResponderEphemeralPubKey: result.keys.ephemeralPubKey, - topicOutbound, - topicInbound, + initiatorEphemeralSecret, + responderEphemeralPubKey: result.keys.ephemeralPubKey, + inResponseToTag: inResponseTo as `0x${string}`, }); // Save session to DB (SDK will pick it up via SessionStore) @@ -343,14 +323,14 @@ export async function processHandshakeResponseEvent( } // ============================================================================= -// Message Processing - FIXED: Uses txHash lookup like old code +// Message Processing - Uses VerbethClient for decryption // ============================================================================= /** * Process a message event using VerbethClient's decryptMessage. * * For outgoing messages: - * - Look up pending record by txHash (same as old code) + * - Look up pending record by txHash * - Finalize the pending record * - Use pending.id to update the message (which IS the optimistic message ID) */ @@ -388,12 +368,12 @@ export async function processMessageEvent( ); // ========================================================================= - // OUTGOING MESSAGE CONFIRMATION - Use txHash lookup like old code + // OUTGOING MESSAGE CONFIRMATION - Use txHash lookup // ========================================================================= if (isOurMessage) { onLog(`๐Ÿ”„ Confirming outgoing message: tx=${log.transactionHash.slice(0, 10)}...`); - // Look up pending by txHash (same as old code!) + // Look up pending by txHash const pending = await dbService.getPendingOutboundByTxHash(log.transactionHash); if (pending && pending.status === "submitted") { diff --git a/packages/sdk/src/client/VerbethClient.ts b/packages/sdk/src/client/VerbethClient.ts index 788cc64..5c3a045 100644 --- a/packages/sdk/src/client/VerbethClient.ts +++ b/packages/sdk/src/client/VerbethClient.ts @@ -6,21 +6,16 @@ * * Provides a unified API for: * - Handshake operations (sendHandshake, acceptHandshake) + * - Session creation for both initiator and responder * - Message encryption/decryption with session management * - Two-phase commit for message sending * - Transaction confirmation handling - * - * CHANGE: acceptHandshake now returns topicOutbound/topicInbound directly, - * derived from the ephemeral DH shared secret (same approach as post-handshake - * topic ratcheting). */ import { hexlify, getBytes } from 'ethers'; import { initiateHandshake, respondToHandshake } from '../send.js'; -// REMOVED: deriveDuplexTopics import import type { IExecutor } from '../executor.js'; import type { IdentityKeyPair, IdentityProof } from '../types.js'; -// REMOVED: DuplexTopics from types import type { Signer } from 'ethers'; import * as crypto from '../crypto.js'; @@ -34,7 +29,8 @@ import { ratchetEncrypt } from '../ratchet/encrypt.js'; import { ratchetDecrypt } from '../ratchet/decrypt.js'; import { packageRatchetPayload, parseRatchetPayload, isRatchetPayload } from '../ratchet/codec.js'; import { verifyMessageSignature } from '../ratchet/auth.js'; -import { dh, deriveTopicFromDH } from '../ratchet/kdf.js'; // NEW: for topic derivation +import { dh, deriveTopicFromDH } from '../ratchet/kdf.js'; +import { initSessionAsInitiator, initSessionAsResponder } from '../ratchet/session.js'; import type { RatchetSession } from '../ratchet/types.js'; import { SessionManager } from './SessionManager.js'; @@ -52,6 +48,21 @@ import type { SerializedSessionInfo, } from './types.js'; +export interface CreateInitiatorSessionParams { + contactAddress: string; + initiatorEphemeralSecret: Uint8Array; + responderEphemeralPubKey: Uint8Array; + inResponseToTag: `0x${string}`; +} + +export interface CreateResponderSessionParams { + contactAddress: string; + responderEphemeralSecret: Uint8Array; + responderEphemeralPublic: Uint8Array; + initiatorEphemeralPubKey: Uint8Array; + salt: Uint8Array; +} + export class VerbethClient { private readonly executor: IExecutor; private readonly identityKeyPair: IdentityKeyPair; @@ -72,22 +83,19 @@ export class VerbethClient { } /** - * Configure session storage. - * Must be called before using prepareMessage/decryptMessage/sendMessage. + * to be called before using prepareMessage/decryptMessage/sendMessage. */ setSessionStore(store: SessionStore): void { this.sessionManager = new SessionManager(store); } /** - * Configure pending message storage. - * Must be called before using sendMessage/confirmTx/revertTx. + * to be called before using sendMessage/confirmTx/revertTx. */ setPendingStore(store: PendingStore): void { this.pendingManager = new PendingManager(store); } - hasSessionStore(): boolean { return !!this.sessionManager; } @@ -101,7 +109,7 @@ export class VerbethClient { * Initiates a handshake with a recipient. * * Generates an ephemeral keypair for this handshake. - * The ephemeralKeyPair.secretKey MUST be stored for ratchet session initialization + * The ephemeralKeyPair.secretKey must be stored for ratchet session initialization * when the response arrives. * * @param recipientAddress - Blockchain address of the recipient @@ -127,7 +135,7 @@ export class VerbethClient { /** * Accepts a handshake from an initiator. * - * UPDATED: Now derives topics from ephemeral DH shared secret (same approach + * Derives topics from ephemeral DH shared secret (same approach * as post-handshake topic ratcheting). Returns topicOutbound/topicInbound * directly instead of duplexTopics structure. * @@ -154,19 +162,14 @@ export class VerbethClient { note, identityProof: this.identityProof, signer: this.signer, - // REMOVED: initiatorIdentityPubKey - no longer used for topic derivation }); - // NEW: Derive initial topics from ephemeral shared secret - // This is consistent with post-handshake topic ratcheting in ratchet/kdf.ts - const ephemeralShared = dh(responderEphemeralSecret, initiatorEphemeralPubKey); - - // Use salt (the tag) for topic derivation, same as conversationId derivation - // Labels are from INITIATOR's perspective, so we SWAP for responder: - // - Responder's outbound = initiator's inbound - // - Responder's inbound = initiator's outbound - const topicOutbound = deriveTopicFromDH(ephemeralShared, 'inbound', salt); - const topicInbound = deriveTopicFromDH(ephemeralShared, 'outbound', salt); + const { topicOutbound, topicInbound } = this.deriveTopicsFromDH( + responderEphemeralSecret, + initiatorEphemeralPubKey, + salt, + false // responder swaps labels + ); return { tx, @@ -179,6 +182,106 @@ export class VerbethClient { }; } + // =========================================================================== + // Session Creation - Encapsulates DH and topic derivation + // =========================================================================== + + /** + * Create a ratchet session as the handshake initiator. + * + * Call this after receiving and validating a handshake response. + * Handles topic derivation from ephemeral DH internally. + * + * @param params - Session creation parameters + * @returns Ready-to-save RatchetSession + */ + createInitiatorSession(params: CreateInitiatorSessionParams): RatchetSession { + const { contactAddress, initiatorEphemeralSecret, responderEphemeralPubKey, inResponseToTag } = params; + + const salt = getBytes(inResponseToTag); + const { topicOutbound, topicInbound } = this.deriveTopicsFromDH( + initiatorEphemeralSecret, + responderEphemeralPubKey, + salt, + true // initiator: no swap + ); + + return initSessionAsInitiator({ + myAddress: this.address, + contactAddress, + myHandshakeEphemeralSecret: initiatorEphemeralSecret, + theirResponderEphemeralPubKey: responderEphemeralPubKey, + topicOutbound, + topicInbound, + }); + } + + /** + * Create a ratchet session as the handshake responder. + * + * Call this after sending a handshake response. + * Handles topic derivation from ephemeral DH internally. + * + * @param params - Session creation parameters + * @returns Ready-to-save RatchetSession + */ + createResponderSession(params: CreateResponderSessionParams): RatchetSession { + const { contactAddress, responderEphemeralSecret, responderEphemeralPublic, initiatorEphemeralPubKey, salt } = params; + + const { topicOutbound, topicInbound } = this.deriveTopicsFromDH( + responderEphemeralSecret, + initiatorEphemeralPubKey, + salt, + false // responder swaps labels + ); + + return initSessionAsResponder({ + myAddress: this.address, + contactAddress, + myResponderEphemeralSecret: responderEphemeralSecret, + myResponderEphemeralPublic: responderEphemeralPublic, + theirHandshakeEphemeralPubKey: initiatorEphemeralPubKey, + topicOutbound, + topicInbound, + }); + } + + /** + * Derive topics from DH shared secret. + * + * @param mySecret - My ephemeral secret key + * @param theirPublic - Their ephemeral public key + * @param salt - Salt for topic derivation (typically the tag bytes) + * @param isInitiator - Whether this party is the initiator (affects label swap) + * @returns Derived outbound and inbound topics + */ + private deriveTopicsFromDH( + mySecret: Uint8Array, + theirPublic: Uint8Array, + salt: Uint8Array, + isInitiator: boolean + ): { topicOutbound: `0x${string}`; topicInbound: `0x${string}` } { + const ephemeralShared = dh(mySecret, theirPublic); + + // Labels are from initiator's perspective + // Initiator: outbound='outbound', inbound='inbound' + // Responder: outbound='inbound', inbound='outbound' (swapped) + if (isInitiator) { + return { + topicOutbound: deriveTopicFromDH(ephemeralShared, 'outbound', salt), + topicInbound: deriveTopicFromDH(ephemeralShared, 'inbound', salt), + }; + } else { + return { + topicOutbound: deriveTopicFromDH(ephemeralShared, 'inbound', salt), + topicInbound: deriveTopicFromDH(ephemeralShared, 'outbound', salt), + }; + } + } + + // =========================================================================== + // Message Operations + // =========================================================================== /** * Prepare a message for sending (encrypt without submitting). @@ -222,7 +325,6 @@ export class VerbethClient { encryptResult.ciphertext ); - // Immediately persist session state await this.sessionManager.save(encryptResult.session); const prepared: PreparedMessage = { @@ -241,7 +343,7 @@ export class VerbethClient { } // Session already saved in prepareMessage for forward secrecy. - // This method can be used for additional bookkeeping if needed. + // So this method can be used for additional bookkeeping if needed. async commitMessage(_prepared: PreparedMessage): Promise { } diff --git a/packages/sdk/src/client/index.ts b/packages/sdk/src/client/index.ts index 2f0122f..97c6fa2 100644 --- a/packages/sdk/src/client/index.ts +++ b/packages/sdk/src/client/index.ts @@ -22,4 +22,9 @@ export type { ConfirmResult, SerializedSessionInfo, -} from './types.js'; \ No newline at end of file +} from './types.js'; + +export type { + CreateInitiatorSessionParams, + CreateResponderSessionParams, +} from './VerbethClient.js'; \ No newline at end of file diff --git a/packages/sdk/test/crypto.test.ts b/packages/sdk/test/crypto.test.ts index 4b73e60..a463c14 100644 --- a/packages/sdk/test/crypto.test.ts +++ b/packages/sdk/test/crypto.test.ts @@ -1,754 +1,579 @@ -// import { describe, it, expect } from "vitest"; -// import nacl from "tweetnacl"; -// import { -// encryptMessage, -// decryptMessage, -// encryptStructuredPayload, -// decryptStructuredPayload, -// decryptHandshakeResponse, -// decryptAndExtractHandshakeKeys, -// deriveDuplexTopics, -// verifyDuplexTopicsChecksum, -// } from "../src/crypto.js"; -// import { -// HandshakePayload, -// encodeHandshakePayload, -// decodeHandshakePayload, -// encodeHandshakeResponseContent, -// decodeHandshakeResponseContent, -// MessagePayload, -// HandshakeResponseContent, -// encodeUnifiedPubKeys, -// extractKeysFromHandshakePayload, -// extractKeysFromHandshakeResponse, -// parseHandshakeKeys, -// } from "../src/payload.js"; -// import { IdentityProof } from "../src/types.js"; -// import type { LogMessage } from "../src/types.js"; - -// function randomTagHex(): `0x${string}` { -// const b = nacl.randomBytes(32); -// return ("0x" + Buffer.from(b).toString("hex")) as `0x${string}`; -// } - -// describe("Encryption/Decryption", () => { -// describe("Message Encryption", () => { -// it("should encrypt and decrypt a message successfully", () => { -// const senderBoxKey = nacl.box.keyPair(); -// const senderSignKey = nacl.sign.keyPair(); -// const recipientKey = nacl.box.keyPair(); -// const message = "Hello VerbEth!"; - -// const encrypted = encryptMessage( -// message, -// recipientKey.publicKey, -// senderBoxKey.secretKey, -// senderBoxKey.publicKey, -// senderSignKey.secretKey, -// senderSignKey.publicKey -// ); - -// const decrypted = decryptMessage( -// encrypted, -// recipientKey.secretKey, -// senderSignKey.publicKey -// ); -// expect(decrypted).toBe(message); -// }); - -// it("should return null on decryption with wrong recipient key", () => { -// const senderBoxKey = nacl.box.keyPair(); -// const senderSignKey = nacl.sign.keyPair(); -// const recipientKey = nacl.box.keyPair(); -// const wrongKey = nacl.box.keyPair(); -// const message = "Sensitive Info"; - -// const encrypted = encryptMessage( -// message, -// recipientKey.publicKey, -// senderBoxKey.secretKey, -// senderBoxKey.publicKey, -// senderSignKey.secretKey, -// senderSignKey.publicKey -// ); - -// const decrypted = decryptMessage( -// encrypted, -// wrongKey.secretKey, -// senderSignKey.publicKey -// ); -// expect(decrypted).toBeNull(); -// }); - -// it("should fail to decrypt if payload is tampered", () => { -// const senderBoxKey = nacl.box.keyPair(); -// const senderSignKey = nacl.sign.keyPair(); -// const recipientKey = nacl.box.keyPair(); -// const message = "tamper test"; - -// let encrypted = encryptMessage( -// message, -// recipientKey.publicKey, -// senderBoxKey.secretKey, -// senderBoxKey.publicKey, -// senderSignKey.secretKey, -// senderSignKey.publicKey -// ); - -// const parsed = JSON.parse(encrypted); -// parsed.ct = Buffer.from("00".repeat(32), "hex").toString("base64"); -// const tampered = JSON.stringify(parsed); - -// const decrypted = decryptMessage( -// tampered, -// recipientKey.secretKey, -// senderSignKey.publicKey -// ); -// expect(decrypted).toBeNull(); -// }); - -// it("should work with the structured message format", () => { -// const senderBoxKey = nacl.box.keyPair(); -// const senderSignKey = nacl.sign.keyPair(); -// const recipientKey = nacl.box.keyPair(); - -// const messagePayload: MessagePayload = { -// content: "Hello structured VerbEth!", -// timestamp: Date.now(), -// messageType: "text", -// }; - -// const encrypted = encryptStructuredPayload( -// messagePayload, -// recipientKey.publicKey, -// senderBoxKey.secretKey, -// senderBoxKey.publicKey, -// senderSignKey.secretKey, -// senderSignKey.publicKey -// ); - -// const decrypted = decryptStructuredPayload( -// encrypted, -// recipientKey.secretKey, -// (obj) => obj as MessagePayload, -// senderSignKey.publicKey -// ); - -// expect(decrypted).toEqual(messagePayload); -// }); - -// it("should encrypt without signing keys (optional parameters)", () => { -// const senderBoxKey = nacl.box.keyPair(); -// const recipientKey = nacl.box.keyPair(); -// const message = "No signature test"; - -// const encrypted = encryptMessage( -// message, -// recipientKey.publicKey, -// senderBoxKey.secretKey, -// senderBoxKey.publicKey -// ); - -// const decrypted = decryptMessage(encrypted, recipientKey.secretKey); -// expect(decrypted).toBe(message); -// }); - -// it("should encrypt structured payload without signing keys", () => { -// const senderBoxKey = nacl.box.keyPair(); -// const recipientKey = nacl.box.keyPair(); - -// const messagePayload: MessagePayload = { -// content: "Unsigned structured message", -// timestamp: Date.now(), -// messageType: "text", -// }; - -// const encrypted = encryptStructuredPayload( -// messagePayload, -// recipientKey.publicKey, -// senderBoxKey.secretKey, -// senderBoxKey.publicKey -// ); - -// const decrypted = decryptStructuredPayload( -// encrypted, -// recipientKey.secretKey, -// (obj) => obj as MessagePayload -// ); - -// expect(decrypted).toEqual(messagePayload); -// }); -// }); - -// describe("Handshake Response Encryption", () => { -// it("should encrypt and decrypt handshake response content", () => { -// const initiatorEphemeralKey = nacl.box.keyPair(); -// const responderEphemeralKey = nacl.box.keyPair(); - -// const identityPubKey = new Uint8Array(32).fill(3); -// const signingPubKey = new Uint8Array(32).fill(7); -// const unifiedPubKeys = encodeUnifiedPubKeys( -// identityPubKey, -// signingPubKey -// ); - -// const ephemeralPubKey = new Uint8Array(32).fill(4); -// const note = "here is my response"; - -// const identityProof: IdentityProof = { -// message: "VerbEth Identity Key Identity v1\nAddress: 0x1234...", -// signature: "0x" + "1".repeat(130), -// }; - -// const responseContent: HandshakeResponseContent = { -// unifiedPubKeys, -// ephemeralPubKey, -// note, -// identityProof, -// }; - -// const encrypted = encryptStructuredPayload( -// responseContent, -// initiatorEphemeralKey.publicKey, -// responderEphemeralKey.secretKey, -// responderEphemeralKey.publicKey -// ); - -// const decrypted = decryptHandshakeResponse( -// encrypted, -// initiatorEphemeralKey.secretKey -// ); - -// expect(decrypted).not.toBeNull(); -// expect(decrypted!.unifiedPubKeys).toEqual(unifiedPubKeys); -// expect(decrypted!.ephemeralPubKey).toEqual(ephemeralPubKey); -// expect(decrypted!.note).toBe(note); -// expect(decrypted!.identityProof).toEqual(identityProof); -// }); - -// it("should handle handshake response with identity proof", () => { -// const initiatorEphemeralKey = nacl.box.keyPair(); -// const responderEphemeralKey = nacl.box.keyPair(); - -// const identityPubKey = new Uint8Array(32).fill(5); -// const signingPubKey = new Uint8Array(32).fill(8); -// const unifiedPubKeys = encodeUnifiedPubKeys( -// identityPubKey, -// signingPubKey -// ); - -// const ephemeralPubKey = new Uint8Array(32).fill(6); - -// const identityProof: IdentityProof = { -// message: "VerbEth Identity Key identity v1\nAddress: 0xabcd...", -// signature: "0x" + "2".repeat(130), -// }; - -// const responseContent: HandshakeResponseContent = { -// unifiedPubKeys, -// ephemeralPubKey, -// note: "with identity proof", -// identityProof, -// }; - -// const encrypted = encryptStructuredPayload( -// responseContent, -// initiatorEphemeralKey.publicKey, -// responderEphemeralKey.secretKey, -// responderEphemeralKey.publicKey -// ); - -// const decrypted = decryptHandshakeResponse( -// encrypted, -// initiatorEphemeralKey.secretKey -// ); - -// expect(decrypted).not.toBeNull(); -// expect(decrypted!.identityProof).toEqual(identityProof); -// }); -// }); - -// describe("decryptAndExtractHandshakeKeys", () => { -// it("should decrypt and extract all keys from handshake response", () => { -// const initiatorEphemeralKey = nacl.box.keyPair(); -// const responderEphemeralKey = nacl.box.keyPair(); - -// const identityPubKey = new Uint8Array(32).fill(10); -// const signingPubKey = new Uint8Array(32).fill(11); -// const unifiedPubKeys = encodeUnifiedPubKeys( -// identityPubKey, -// signingPubKey -// ); -// const ephemeralPubKey = new Uint8Array(32).fill(12); -// const note = "convenience function test"; - -// const identityProof: IdentityProof = { -// message: "VerbEth Identity Key Identity v1\nAddress: 0xtest...", -// signature: "0x" + "3".repeat(130), -// }; - -// const responseContent: HandshakeResponseContent = { -// unifiedPubKeys, -// ephemeralPubKey, -// note, -// identityProof, -// }; - -// const encrypted = encryptStructuredPayload( -// responseContent, -// initiatorEphemeralKey.publicKey, -// responderEphemeralKey.secretKey, -// responderEphemeralKey.publicKey -// ); - -// const result = decryptAndExtractHandshakeKeys( -// encrypted, -// initiatorEphemeralKey.secretKey -// ); - -// expect(result).not.toBeNull(); -// expect(result!.identityPubKey).toEqual(identityPubKey); -// expect(result!.signingPubKey).toEqual(signingPubKey); -// expect(result!.ephemeralPubKey).toEqual(ephemeralPubKey); -// expect(result!.note).toBe(note); -// expect(result!.identityProof).toEqual(identityProof); -// }); - -// it("should return null for invalid encrypted data", () => { -// const initiatorEphemeralKey = nacl.box.keyPair(); - -// // Create a valid-looking but unencryptable payload -// const invalidPayload = { -// v: 1, -// epk: Buffer.from(new Uint8Array(32).fill(1)).toString("base64"), -// n: Buffer.from(new Uint8Array(24).fill(2)).toString("base64"), -// ct: Buffer.from(new Uint8Array(16).fill(3)).toString("base64"), -// }; -// const invalidEncrypted = JSON.stringify(invalidPayload); - -// const result = decryptAndExtractHandshakeKeys( -// invalidEncrypted, -// initiatorEphemeralKey.secretKey -// ); - -// expect(result).toBeNull(); -// }); - -// it("should return null with wrong decryption key", () => { -// const initiatorEphemeralKey = nacl.box.keyPair(); -// const responderEphemeralKey = nacl.box.keyPair(); -// const wrongKey = nacl.box.keyPair(); - -// const identityPubKey = new Uint8Array(32).fill(13); -// const signingPubKey = new Uint8Array(32).fill(14); -// const unifiedPubKeys = encodeUnifiedPubKeys( -// identityPubKey, -// signingPubKey -// ); - -// const identityProof: IdentityProof = { -// message: "Wrong key test", -// signature: "0x" + "4".repeat(130), -// }; - -// const responseContent: HandshakeResponseContent = { -// unifiedPubKeys, -// ephemeralPubKey: new Uint8Array(32).fill(15), -// note: "should fail", -// identityProof, -// }; - -// const encrypted = encryptStructuredPayload( -// responseContent, -// initiatorEphemeralKey.publicKey, -// responderEphemeralKey.secretKey, -// responderEphemeralKey.publicKey -// ); - -// const result = decryptAndExtractHandshakeKeys( -// encrypted, -// wrongKey.secretKey -// ); - -// expect(result).toBeNull(); -// }); -// }); - -// describe("Key Extraction Functions", () => { -// it("should extract keys from handshake payload", () => { -// const identityPubKey = new Uint8Array(32).fill(20); -// const signingPubKey = new Uint8Array(32).fill(21); -// const ephemeralPubKey = new Uint8Array(32).fill(22); -// const unifiedPubKeys = encodeUnifiedPubKeys( -// identityPubKey, -// signingPubKey -// ); - -// const payload: HandshakePayload = { -// unifiedPubKeys, -// ephemeralPubKey, -// plaintextPayload: "test payload", -// }; - -// const extracted = extractKeysFromHandshakePayload(payload); - -// expect(extracted).not.toBeNull(); -// expect(extracted!.identityPubKey).toEqual(identityPubKey); -// expect(extracted!.signingPubKey).toEqual(signingPubKey); -// expect(extracted!.ephemeralPubKey).toEqual(ephemeralPubKey); -// }); - -// it("should extract keys from handshake response content", () => { -// const identityPubKey = new Uint8Array(32).fill(25); -// const signingPubKey = new Uint8Array(32).fill(26); -// const ephemeralPubKey = new Uint8Array(32).fill(27); -// const unifiedPubKeys = encodeUnifiedPubKeys( -// identityPubKey, -// signingPubKey -// ); - -// const identityProof: IdentityProof = { -// message: "Extract test", -// signature: "0x" + "5".repeat(130), -// }; - -// const content: HandshakeResponseContent = { -// unifiedPubKeys, -// ephemeralPubKey, -// note: "extract test", -// identityProof, -// }; - -// const extracted = extractKeysFromHandshakeResponse(content); - -// expect(extracted).not.toBeNull(); -// expect(extracted!.identityPubKey).toEqual(identityPubKey); -// expect(extracted!.signingPubKey).toEqual(signingPubKey); -// expect(extracted!.ephemeralPubKey).toEqual(ephemeralPubKey); -// }); - -// it("should return null for invalid unified keys in payload", () => { -// const invalidUnifiedKeys = new Uint8Array(30).fill(1); // Wrong size - -// const payload: HandshakePayload = { -// unifiedPubKeys: invalidUnifiedKeys, -// ephemeralPubKey: new Uint8Array(32).fill(2), -// plaintextPayload: "invalid test", -// }; - -// const extracted = extractKeysFromHandshakePayload(payload); -// expect(extracted).toBeNull(); -// }); - -// it("should return null for invalid unified keys in response content", () => { -// const invalidUnifiedKeys = new Uint8Array(30).fill(1); // Wrong size - -// const identityProof: IdentityProof = { -// message: "Invalid test", -// signature: "0x" + "6".repeat(130), -// }; - -// const content: HandshakeResponseContent = { -// unifiedPubKeys: invalidUnifiedKeys, -// ephemeralPubKey: new Uint8Array(32).fill(2), -// note: "invalid test", -// identityProof, -// }; - -// const extracted = extractKeysFromHandshakeResponse(content); -// expect(extracted).toBeNull(); -// }); -// }); - -// describe("Handshake Key Parsing", () => { -// it("should parse handshake keys from event correctly", () => { -// const identityPubKey = new Uint8Array(32).fill(30); -// const signingPubKey = new Uint8Array(32).fill(31); -// const unifiedPubKeys = encodeUnifiedPubKeys( -// identityPubKey, -// signingPubKey -// ); - -// const event = { -// pubKeys: "0x" + Buffer.from(unifiedPubKeys).toString("hex"), -// }; - -// const parsed = parseHandshakeKeys(event); - -// expect(parsed).not.toBeNull(); -// expect(parsed!.identityPubKey).toEqual(identityPubKey); -// expect(parsed!.signingPubKey).toEqual(signingPubKey); -// }); - -// it("should return null for invalid hex in pubKeys", () => { -// const event = { -// pubKeys: "0xinvalidhex", -// }; - -// const parsed = parseHandshakeKeys(event); -// expect(parsed).toBeNull(); -// }); - -// it("should return null for wrong size pubKeys", () => { -// const shortKeys = new Uint8Array(30).fill(1); // Wrong size - -// const event = { -// pubKeys: "0x" + Buffer.from(shortKeys).toString("hex"), -// }; - -// const parsed = parseHandshakeKeys(event); -// expect(parsed).toBeNull(); -// }); - -// it("should handle pubKeys without 0x prefix", () => { -// const identityPubKey = new Uint8Array(32).fill(35); -// const signingPubKey = new Uint8Array(32).fill(36); -// const unifiedPubKeys = encodeUnifiedPubKeys( -// identityPubKey, -// signingPubKey -// ); - -// const event = { -// pubKeys: "0x" + Buffer.from(unifiedPubKeys).toString("hex"), -// }; - -// const parsed = parseHandshakeKeys(event); - -// expect(parsed).not.toBeNull(); -// expect(parsed!.identityPubKey).toEqual(identityPubKey); -// expect(parsed!.signingPubKey).toEqual(signingPubKey); -// }); -// }); - -// describe("Error Handling", () => { -// it("should throw error for malformed JSON in decryptStructuredPayload", () => { -// const recipientKey = nacl.box.keyPair(); -// const malformedJson = "invalid json"; - -// expect(() => { -// decryptStructuredPayload( -// malformedJson, -// recipientKey.secretKey, -// (obj) => obj as MessagePayload -// ); -// }).toThrow(); -// }); - -// it("should throw error for missing fields in payload", () => { -// const recipientKey = nacl.box.keyPair(); -// const incompletePayload = JSON.stringify({ -// epk: Buffer.from(new Uint8Array(32)).toString("base64"), -// // Missing nonce and ciphertext -// }); - -// expect(() => { -// decryptStructuredPayload( -// incompletePayload, -// recipientKey.secretKey, -// (obj) => obj as MessagePayload -// ); -// }).toThrow(); -// }); - -// it("should throw error for invalid base64 in payload fields", () => { -// const recipientKey = nacl.box.keyPair(); -// const invalidPayload = JSON.stringify({ -// epk: "invalid-base64!", -// n: "invalid-base64!", -// ct: "invalid-base64!", -// }); - -// expect(() => { -// decryptStructuredPayload( -// invalidPayload, -// recipientKey.secretKey, -// (obj) => obj as MessagePayload -// ); -// }).toThrow(); -// }); - -// it("should return null when converter function throws error", () => { -// const senderBoxKey = nacl.box.keyPair(); -// const recipientKey = nacl.box.keyPair(); - -// const messagePayload: MessagePayload = { -// content: "Test message", -// timestamp: Date.now(), -// messageType: "text", -// }; - -// const encrypted = encryptStructuredPayload( -// messagePayload, -// recipientKey.publicKey, -// senderBoxKey.secretKey, -// senderBoxKey.publicKey -// ); - -// // Converter that throws error -// const throwingConverter = (obj: any) => { -// throw new Error("Converter error"); -// }; - -// expect(() => { -// decryptStructuredPayload( -// encrypted, -// recipientKey.secretKey, -// throwingConverter -// ); -// }).toThrow("Converter error"); -// }); - -// it("should throw error for decryptHandshakeResponse with missing identityProof", () => { -// const initiatorEphemeralKey = nacl.box.keyPair(); -// const responderEphemeralKey = nacl.box.keyPair(); - -// // Create content without identityProof -// const invalidContent = { -// unifiedPubKeys: encodeUnifiedPubKeys( -// new Uint8Array(32).fill(40), -// new Uint8Array(32).fill(41) -// ), -// ephemeralPubKey: new Uint8Array(32).fill(42), -// note: "missing proof", -// // No identityProof -// }; - -// const encrypted = encryptStructuredPayload( -// invalidContent, -// initiatorEphemeralKey.publicKey, -// responderEphemeralKey.secretKey, -// responderEphemeralKey.publicKey -// ); - -// expect(() => { -// decryptHandshakeResponse(encrypted, initiatorEphemeralKey.secretKey); -// }).toThrow("Invalid handshake response: missing identityProof"); -// }); -// }); - -// describe("Payload Encoding/Decoding", () => { -// it("should encode and decode handshake payload correctly", () => { -// const identityPubKey = new Uint8Array(32).fill(1); -// const signingPubKey = new Uint8Array(32).fill(9); -// const unifiedPubKeys = encodeUnifiedPubKeys( -// identityPubKey, -// signingPubKey -// ); - -// const payload: HandshakePayload = { -// unifiedPubKeys, -// ephemeralPubKey: new Uint8Array(32).fill(2), -// plaintextPayload: "hello bob", -// }; - -// const encoded = encodeHandshakePayload(payload); -// const decoded = decodeHandshakePayload(encoded); - -// expect(decoded.unifiedPubKeys).toEqual(payload.unifiedPubKeys); -// expect(decoded.ephemeralPubKey).toEqual(payload.ephemeralPubKey); -// expect(decoded.plaintextPayload).toBe("hello bob"); -// }); - -// it("should encode and decode response content correctly", () => { -// const identityPubKey = new Uint8Array(32).fill(3); -// const signingPubKey = new Uint8Array(32).fill(10); -// const unifiedPubKeys = encodeUnifiedPubKeys( -// identityPubKey, -// signingPubKey -// ); - -// const ephemeralPubKey = new Uint8Array(32).fill(4); -// const note = "here is my response"; - -// const identityProof: IdentityProof = { -// message: "VerbEth Identity Key Identity v1\nAddress: 0xtest...", -// signature: "0x" + "3".repeat(130), -// }; - -// const content: HandshakeResponseContent = { -// unifiedPubKeys, -// ephemeralPubKey, -// note, -// identityProof, -// }; - -// const encoded = encodeHandshakeResponseContent(content); -// const decoded = decodeHandshakeResponseContent(encoded); - -// expect(decoded.unifiedPubKeys).toEqual(unifiedPubKeys); -// expect(decoded.ephemeralPubKey).toEqual(ephemeralPubKey); -// expect(decoded.note).toBe(note); -// expect(decoded.identityProof).toEqual(identityProof); -// }); -// }); - -// describe("Log Message Structure", () => { -// it("should decode and decrypt a log message", () => { -// const senderBoxKey = nacl.box.keyPair(); -// const senderSignKey = nacl.sign.keyPair(); -// const recipientKey = nacl.box.keyPair(); - -// const message = "from on-chain log"; - -// const ciphertext = encryptMessage( -// message, -// recipientKey.publicKey, -// senderBoxKey.secretKey, -// senderBoxKey.publicKey, -// senderSignKey.secretKey, -// senderSignKey.publicKey -// ); - -// const mockLog: LogMessage = { -// sender: "0x" + "a".repeat(40), -// ciphertext, -// timestamp: Math.floor(Date.now() / 1000), -// topic: "0x" + "d".repeat(64), -// nonce: 1n, -// }; - -// const decrypted = decryptMessage( -// mockLog.ciphertext, -// recipientKey.secretKey, -// senderSignKey.publicKey -// ); -// expect(decrypted).toBe(message); -// }); -// }); - -// it("derives deterministic duplex topics (Alice & Bob compute the same) and checksum verifies", () => { -// const alice = nacl.box.keyPair(); -// const bob = nacl.box.keyPair(); - -// // Bind topics to a specific handshake via tag (inResponseTo) -// const tag = randomTagHex(); -// const salt = Uint8Array.from(Buffer.from(tag.slice(2), "hex")); - -// // Alice view (my=Alice, their=Bob) -// const A = deriveDuplexTopics(alice.secretKey, bob.publicKey, salt); -// // Bob view (my=Bob, their=Alice) -// const B = deriveDuplexTopics(bob.secretKey, alice.publicKey, salt); - -// // Deterministic agreement -// expect(A.topicOut).toBe(B.topicOut); -// expect(A.topicIn).toBe(B.topicIn); -// expect(A.topicOut).not.toBe(A.topicIn); -// expect(verifyDuplexTopicsChecksum(A.topicOut, A.topicIn, A.checksum)).toBe( -// true -// ); -// }); - -// it("changes in tag/salt produce different topics (per-handshake binding)", () => { -// const alice = nacl.box.keyPair(); -// const bob = nacl.box.keyPair(); - -// const salt1 = Uint8Array.from(Buffer.from(randomTagHex().slice(2), "hex")); -// const salt2 = Uint8Array.from(Buffer.from(randomTagHex().slice(2), "hex")); - -// const T1 = deriveDuplexTopics(alice.secretKey, bob.publicKey, salt1); -// const T2 = deriveDuplexTopics(alice.secretKey, bob.publicKey, salt2); - -// expect(T1.topicOut).not.toBe(T2.topicOut); -// expect(T1.topicIn).not.toBe(T2.topicIn); -// }); -// }); +import { describe, it, expect } from "vitest"; +import nacl from "tweetnacl"; +import { + encryptStructuredPayload, + decryptStructuredPayload, + decryptHandshakeResponse, + decryptAndExtractHandshakeKeys, +} from "../src/crypto.js"; +import { + HandshakePayload, + encodeHandshakePayload, + decodeHandshakePayload, + encodeHandshakeResponseContent, + decodeHandshakeResponseContent, + MessagePayload, + HandshakeResponseContent, + encodeUnifiedPubKeys, + extractKeysFromHandshakePayload, + extractKeysFromHandshakeResponse, + parseHandshakeKeys, +} from "../src/payload.js"; +import { IdentityProof } from "../src/types.js"; + +describe("Encryption/Decryption", () => { + describe("Structured Payload Encryption", () => { + it("should encrypt and decrypt structured message format", () => { + const senderBoxKey = nacl.box.keyPair(); + const senderSignKey = nacl.sign.keyPair(); + const recipientKey = nacl.box.keyPair(); + + const messagePayload: MessagePayload = { + content: "Hello structured VerbEth!", + timestamp: Date.now(), + messageType: "text", + }; + + const encrypted = encryptStructuredPayload( + messagePayload, + recipientKey.publicKey, + senderBoxKey.secretKey, + senderBoxKey.publicKey, + senderSignKey.secretKey, + senderSignKey.publicKey + ); + + const decrypted = decryptStructuredPayload( + encrypted, + recipientKey.secretKey, + (obj) => obj as MessagePayload, + senderSignKey.publicKey + ); + + expect(decrypted).toEqual(messagePayload); + }); + + it("should encrypt structured payload without signing keys", () => { + const senderBoxKey = nacl.box.keyPair(); + const recipientKey = nacl.box.keyPair(); + + const messagePayload: MessagePayload = { + content: "Unsigned structured message", + timestamp: Date.now(), + messageType: "text", + }; + + const encrypted = encryptStructuredPayload( + messagePayload, + recipientKey.publicKey, + senderBoxKey.secretKey, + senderBoxKey.publicKey + ); + + const decrypted = decryptStructuredPayload( + encrypted, + recipientKey.secretKey, + (obj) => obj as MessagePayload + ); + + expect(decrypted).toEqual(messagePayload); + }); + + it("should return null on decryption with wrong recipient key", () => { + const senderBoxKey = nacl.box.keyPair(); + const recipientKey = nacl.box.keyPair(); + const wrongKey = nacl.box.keyPair(); + + const messagePayload: MessagePayload = { + content: "Test message", + timestamp: Date.now(), + messageType: "text", + }; + + const encrypted = encryptStructuredPayload( + messagePayload, + recipientKey.publicKey, + senderBoxKey.secretKey, + senderBoxKey.publicKey + ); + + const decrypted = decryptStructuredPayload( + encrypted, + wrongKey.secretKey, + (obj) => obj as MessagePayload + ); + + expect(decrypted).toBeNull(); + }); + }); + + describe("Handshake Response Encryption", () => { + it("should encrypt and decrypt handshake response content", () => { + const initiatorEphemeralKey = nacl.box.keyPair(); + const responderEphemeralKey = nacl.box.keyPair(); + + const identityPubKey = new Uint8Array(32).fill(3); + const signingPubKey = new Uint8Array(32).fill(7); + const unifiedPubKeys = encodeUnifiedPubKeys(identityPubKey, signingPubKey); + + const ephemeralPubKey = new Uint8Array(32).fill(4); + const note = "here is my response"; + + const identityProof: IdentityProof = { + message: "VerbEth Identity Key Identity v1\nAddress: 0x1234...", + signature: "0x" + "1".repeat(130), + }; + + const responseContent: HandshakeResponseContent = { + unifiedPubKeys, + ephemeralPubKey, + note, + identityProof, + }; + + const encrypted = encryptStructuredPayload( + responseContent, + initiatorEphemeralKey.publicKey, + responderEphemeralKey.secretKey, + responderEphemeralKey.publicKey + ); + + const decrypted = decryptHandshakeResponse( + encrypted, + initiatorEphemeralKey.secretKey + ); + + expect(decrypted).not.toBeNull(); + expect(decrypted!.unifiedPubKeys).toEqual(unifiedPubKeys); + expect(decrypted!.ephemeralPubKey).toEqual(ephemeralPubKey); + expect(decrypted!.note).toBe(note); + expect(decrypted!.identityProof).toEqual(identityProof); + }); + + it("should handle handshake response with identity proof", () => { + const initiatorEphemeralKey = nacl.box.keyPair(); + const responderEphemeralKey = nacl.box.keyPair(); + + const identityPubKey = new Uint8Array(32).fill(5); + const signingPubKey = new Uint8Array(32).fill(8); + const unifiedPubKeys = encodeUnifiedPubKeys(identityPubKey, signingPubKey); + + const ephemeralPubKey = new Uint8Array(32).fill(6); + + const identityProof: IdentityProof = { + message: "VerbEth Identity Key identity v1\nAddress: 0xabcd...", + signature: "0x" + "2".repeat(130), + }; + + const responseContent: HandshakeResponseContent = { + unifiedPubKeys, + ephemeralPubKey, + note: "with identity proof", + identityProof, + }; + + const encrypted = encryptStructuredPayload( + responseContent, + initiatorEphemeralKey.publicKey, + responderEphemeralKey.secretKey, + responderEphemeralKey.publicKey + ); + + const decrypted = decryptHandshakeResponse( + encrypted, + initiatorEphemeralKey.secretKey + ); + + expect(decrypted).not.toBeNull(); + expect(decrypted!.identityProof).toEqual(identityProof); + }); + }); + + describe("decryptAndExtractHandshakeKeys", () => { + it("should decrypt and extract all keys from handshake response", () => { + const initiatorEphemeralKey = nacl.box.keyPair(); + const responderEphemeralKey = nacl.box.keyPair(); + + const identityPubKey = new Uint8Array(32).fill(10); + const signingPubKey = new Uint8Array(32).fill(11); + const unifiedPubKeys = encodeUnifiedPubKeys(identityPubKey, signingPubKey); + const ephemeralPubKey = new Uint8Array(32).fill(12); + const note = "convenience function test"; + + const identityProof: IdentityProof = { + message: "VerbEth Identity Key Identity v1\nAddress: 0xtest...", + signature: "0x" + "3".repeat(130), + }; + + const responseContent: HandshakeResponseContent = { + unifiedPubKeys, + ephemeralPubKey, + note, + identityProof, + }; + + const encrypted = encryptStructuredPayload( + responseContent, + initiatorEphemeralKey.publicKey, + responderEphemeralKey.secretKey, + responderEphemeralKey.publicKey + ); + + const result = decryptAndExtractHandshakeKeys( + encrypted, + initiatorEphemeralKey.secretKey + ); + + expect(result).not.toBeNull(); + expect(result!.identityPubKey).toEqual(identityPubKey); + expect(result!.signingPubKey).toEqual(signingPubKey); + expect(result!.ephemeralPubKey).toEqual(ephemeralPubKey); + expect(result!.note).toBe(note); + expect(result!.identityProof).toEqual(identityProof); + }); + + it("should return null for invalid encrypted data", () => { + const initiatorEphemeralKey = nacl.box.keyPair(); + + const invalidPayload = { + v: 1, + epk: Buffer.from(new Uint8Array(32).fill(1)).toString("base64"), + n: Buffer.from(new Uint8Array(24).fill(2)).toString("base64"), + ct: Buffer.from(new Uint8Array(16).fill(3)).toString("base64"), + }; + const invalidEncrypted = JSON.stringify(invalidPayload); + + const result = decryptAndExtractHandshakeKeys( + invalidEncrypted, + initiatorEphemeralKey.secretKey + ); + + expect(result).toBeNull(); + }); + + it("should return null with wrong decryption key", () => { + const initiatorEphemeralKey = nacl.box.keyPair(); + const responderEphemeralKey = nacl.box.keyPair(); + const wrongKey = nacl.box.keyPair(); + + const identityPubKey = new Uint8Array(32).fill(13); + const signingPubKey = new Uint8Array(32).fill(14); + const unifiedPubKeys = encodeUnifiedPubKeys(identityPubKey, signingPubKey); + + const identityProof: IdentityProof = { + message: "Wrong key test", + signature: "0x" + "4".repeat(130), + }; + + const responseContent: HandshakeResponseContent = { + unifiedPubKeys, + ephemeralPubKey: new Uint8Array(32).fill(15), + note: "should fail", + identityProof, + }; + + const encrypted = encryptStructuredPayload( + responseContent, + initiatorEphemeralKey.publicKey, + responderEphemeralKey.secretKey, + responderEphemeralKey.publicKey + ); + + const result = decryptAndExtractHandshakeKeys( + encrypted, + wrongKey.secretKey + ); + + expect(result).toBeNull(); + }); + }); + + describe("Key Extraction Functions", () => { + it("should extract keys from handshake payload", () => { + const identityPubKey = new Uint8Array(32).fill(20); + const signingPubKey = new Uint8Array(32).fill(21); + const ephemeralPubKey = new Uint8Array(32).fill(22); + const unifiedPubKeys = encodeUnifiedPubKeys(identityPubKey, signingPubKey); + + const payload: HandshakePayload = { + unifiedPubKeys, + ephemeralPubKey, + plaintextPayload: "test payload", + }; + + const extracted = extractKeysFromHandshakePayload(payload); + + expect(extracted).not.toBeNull(); + expect(extracted!.identityPubKey).toEqual(identityPubKey); + expect(extracted!.signingPubKey).toEqual(signingPubKey); + expect(extracted!.ephemeralPubKey).toEqual(ephemeralPubKey); + }); + + it("should extract keys from handshake response content", () => { + const identityPubKey = new Uint8Array(32).fill(25); + const signingPubKey = new Uint8Array(32).fill(26); + const ephemeralPubKey = new Uint8Array(32).fill(27); + const unifiedPubKeys = encodeUnifiedPubKeys(identityPubKey, signingPubKey); + + const identityProof: IdentityProof = { + message: "Extract test", + signature: "0x" + "5".repeat(130), + }; + + const content: HandshakeResponseContent = { + unifiedPubKeys, + ephemeralPubKey, + note: "extract test", + identityProof, + }; + + const extracted = extractKeysFromHandshakeResponse(content); + + expect(extracted).not.toBeNull(); + expect(extracted!.identityPubKey).toEqual(identityPubKey); + expect(extracted!.signingPubKey).toEqual(signingPubKey); + expect(extracted!.ephemeralPubKey).toEqual(ephemeralPubKey); + }); + + it("should return null for invalid unified keys in payload", () => { + const invalidUnifiedKeys = new Uint8Array(30).fill(1); // Wrong size + + const payload: HandshakePayload = { + unifiedPubKeys: invalidUnifiedKeys, + ephemeralPubKey: new Uint8Array(32).fill(2), + plaintextPayload: "invalid test", + }; + + const extracted = extractKeysFromHandshakePayload(payload); + expect(extracted).toBeNull(); + }); + + it("should return null for invalid unified keys in response content", () => { + const invalidUnifiedKeys = new Uint8Array(30).fill(1); // Wrong size + + const identityProof: IdentityProof = { + message: "Invalid test", + signature: "0x" + "6".repeat(130), + }; + + const content: HandshakeResponseContent = { + unifiedPubKeys: invalidUnifiedKeys, + ephemeralPubKey: new Uint8Array(32).fill(2), + note: "invalid test", + identityProof, + }; + + const extracted = extractKeysFromHandshakeResponse(content); + expect(extracted).toBeNull(); + }); + }); + + describe("Handshake Key Parsing", () => { + it("should parse handshake keys from event correctly", () => { + const identityPubKey = new Uint8Array(32).fill(30); + const signingPubKey = new Uint8Array(32).fill(31); + const unifiedPubKeys = encodeUnifiedPubKeys(identityPubKey, signingPubKey); + + const event = { + pubKeys: "0x" + Buffer.from(unifiedPubKeys).toString("hex"), + }; + + const parsed = parseHandshakeKeys(event); + + expect(parsed).not.toBeNull(); + expect(parsed!.identityPubKey).toEqual(identityPubKey); + expect(parsed!.signingPubKey).toEqual(signingPubKey); + }); + + it("should return null for invalid hex in pubKeys", () => { + const event = { + pubKeys: "0xinvalidhex", + }; + + const parsed = parseHandshakeKeys(event); + expect(parsed).toBeNull(); + }); + + it("should return null for wrong size pubKeys", () => { + const shortKeys = new Uint8Array(30).fill(1); // Wrong size + + const event = { + pubKeys: "0x" + Buffer.from(shortKeys).toString("hex"), + }; + + const parsed = parseHandshakeKeys(event); + expect(parsed).toBeNull(); + }); + + it("should handle pubKeys with 0x prefix", () => { + const identityPubKey = new Uint8Array(32).fill(35); + const signingPubKey = new Uint8Array(32).fill(36); + const unifiedPubKeys = encodeUnifiedPubKeys(identityPubKey, signingPubKey); + + const event = { + pubKeys: "0x" + Buffer.from(unifiedPubKeys).toString("hex"), + }; + + const parsed = parseHandshakeKeys(event); + + expect(parsed).not.toBeNull(); + expect(parsed!.identityPubKey).toEqual(identityPubKey); + expect(parsed!.signingPubKey).toEqual(signingPubKey); + }); + }); + + describe("Error Handling", () => { + it("should throw error for malformed JSON in decryptStructuredPayload", () => { + const recipientKey = nacl.box.keyPair(); + const malformedJson = "invalid json"; + + expect(() => { + decryptStructuredPayload( + malformedJson, + recipientKey.secretKey, + (obj) => obj as MessagePayload + ); + }).toThrow(); + }); + + it("should throw error for missing fields in payload", () => { + const recipientKey = nacl.box.keyPair(); + const incompletePayload = JSON.stringify({ + epk: Buffer.from(new Uint8Array(32)).toString("base64"), + // Missing nonce and ciphertext + }); + + expect(() => { + decryptStructuredPayload( + incompletePayload, + recipientKey.secretKey, + (obj) => obj as MessagePayload + ); + }).toThrow(); + }); + + it("should throw error for invalid base64 in payload fields", () => { + const recipientKey = nacl.box.keyPair(); + const invalidPayload = JSON.stringify({ + epk: "invalid-base64!", + n: "invalid-base64!", + ct: "invalid-base64!", + }); + + expect(() => { + decryptStructuredPayload( + invalidPayload, + recipientKey.secretKey, + (obj) => obj as MessagePayload + ); + }).toThrow(); + }); + + it("should throw error when converter function throws error", () => { + const senderBoxKey = nacl.box.keyPair(); + const recipientKey = nacl.box.keyPair(); + + const messagePayload: MessagePayload = { + content: "Test message", + timestamp: Date.now(), + messageType: "text", + }; + + const encrypted = encryptStructuredPayload( + messagePayload, + recipientKey.publicKey, + senderBoxKey.secretKey, + senderBoxKey.publicKey + ); + + const throwingConverter = () => { + throw new Error("Converter error"); + }; + + expect(() => { + decryptStructuredPayload( + encrypted, + recipientKey.secretKey, + throwingConverter + ); + }).toThrow("Converter error"); + }); + + it("should throw error for decryptHandshakeResponse with missing identityProof", () => { + const initiatorEphemeralKey = nacl.box.keyPair(); + const responderEphemeralKey = nacl.box.keyPair(); + + // Create content without identityProof + const invalidContent = { + unifiedPubKeys: encodeUnifiedPubKeys( + new Uint8Array(32).fill(40), + new Uint8Array(32).fill(41) + ), + ephemeralPubKey: new Uint8Array(32).fill(42), + note: "missing proof", + // No identityProof + }; + + const encrypted = encryptStructuredPayload( + invalidContent, + initiatorEphemeralKey.publicKey, + responderEphemeralKey.secretKey, + responderEphemeralKey.publicKey + ); + + expect(() => { + decryptHandshakeResponse(encrypted, initiatorEphemeralKey.secretKey); + }).toThrow("Invalid handshake response: missing identityProof"); + }); + }); + + describe("Payload Encoding/Decoding", () => { + it("should encode and decode handshake payload correctly", () => { + const identityPubKey = new Uint8Array(32).fill(1); + const signingPubKey = new Uint8Array(32).fill(9); + const unifiedPubKeys = encodeUnifiedPubKeys(identityPubKey, signingPubKey); + + const payload: HandshakePayload = { + unifiedPubKeys, + ephemeralPubKey: new Uint8Array(32).fill(2), + plaintextPayload: "hello bob", + }; + + const encoded = encodeHandshakePayload(payload); + const decoded = decodeHandshakePayload(encoded); + + expect(decoded.unifiedPubKeys).toEqual(payload.unifiedPubKeys); + expect(decoded.ephemeralPubKey).toEqual(payload.ephemeralPubKey); + expect(decoded.plaintextPayload).toBe("hello bob"); + }); + + it("should encode and decode response content correctly", () => { + const identityPubKey = new Uint8Array(32).fill(3); + const signingPubKey = new Uint8Array(32).fill(10); + const unifiedPubKeys = encodeUnifiedPubKeys(identityPubKey, signingPubKey); + + const ephemeralPubKey = new Uint8Array(32).fill(4); + const note = "here is my response"; + + const identityProof: IdentityProof = { + message: "VerbEth Identity Key Identity v1\nAddress: 0xtest...", + signature: "0x" + "3".repeat(130), + }; + + const content: HandshakeResponseContent = { + unifiedPubKeys, + ephemeralPubKey, + note, + identityProof, + }; + + const encoded = encodeHandshakeResponseContent(content); + const decoded = decodeHandshakeResponseContent(encoded); + + expect(decoded.unifiedPubKeys).toEqual(unifiedPubKeys); + expect(decoded.ephemeralPubKey).toEqual(ephemeralPubKey); + expect(decoded.note).toBe(note); + expect(decoded.identityProof).toEqual(identityProof); + }); + }); +}); \ No newline at end of file diff --git a/packages/sdk/test/utils.test.ts b/packages/sdk/test/utils.test.ts index 07e19b9..1625299 100644 --- a/packages/sdk/test/utils.test.ts +++ b/packages/sdk/test/utils.test.ts @@ -1,108 +1,108 @@ -// import { describe, it, expect, vi } from "vitest"; -// import nacl from "tweetnacl"; -// import { JsonRpcProvider } from "ethers"; - -// import { getNextNonce } from "../src/utils/nonce.js"; -// import { convertPublicKeyToX25519 } from "../src/utils/x25519.js"; -// import { isSmartContract1271, parseBindingMessage } from "../src/utils.js"; -// import { ExecutorFactory } from "../src/index.js"; -// import type { LogChainV1 } from "@verbeth/contracts/typechain-types"; - -// const fakeProvider = { -// async getCode(addr: string) { -// return addr === "0xCcโ€ฆCc" ? "0x60016000" : "0x"; -// }, -// async call() { -// return "0x1626ba7e" + "0".repeat(56); -// }, -// async resolveName(name: string) { -// return name; -// }, -// } as unknown as JsonRpcProvider; - - -// describe("getNextNonce", () => { -// it("increments per (sender, topic) and returns bigint", () => { -// const n1 = getNextNonce("0xAlice", "topic"); -// const n2 = getNextNonce("0xAlice", "topic"); -// const nOther = getNextNonce("0xBob", "topic"); -// expect(n2).toBe(n1 + 1n); -// expect(nOther).toBe(1n); -// }); -// }); - -// describe("Utils Functions", () => { -// it("isSmartContract1271 returns true for contract bytecode", async () => { -// expect(await isSmartContract1271("0xCcโ€ฆCc", fakeProvider)).toBe(true); -// expect(await isSmartContract1271("0xEeโ€ฆEe", fakeProvider)).toBe(false); -// }); - -// it("convertPublicKeyToX25519 returns 32-byte key", () => { -// const raw = new Uint8Array(64).fill(1); -// const out = convertPublicKeyToX25519(raw); -// expect(out).toHaveLength(32); -// }); -// }); - - -// describe("Unified Keys Utilities", () => { -// it("should handle unified key operations", () => { -// expect(typeof isSmartContract1271).toBe("function"); -// }); -// }); - -// describe("parseBindingMessage", () => { -// it("parses a well-formed binding message", () => { -// const msg = [ -// "VerbEth Key Binding v1", -// "Address: 0x1234567890abcdef1234567890abcdef12345678", -// "PkEd25519: 0x" + "11".repeat(32), -// "PkX25519: 0x" + "22".repeat(32), -// "Context: verbeth", -// "Version: 1", -// "ChainId: 8453", -// "RpId: example.com", -// ].join("\n"); - -// const parsed = parseBindingMessage(msg); - -// expect(parsed.header).toBe("VerbEth Key Binding v1"); -// expect(parsed.address?.toLowerCase()).toBe("0x1234567890abcdef1234567890abcdef12345678"); -// expect(parsed.pkEd25519).toBe("0x" + "11".repeat(32)); -// expect(parsed.pkX25519).toBe("0x" + "22".repeat(32)); -// expect(parsed.context).toBe("verbeth"); -// expect(parsed.version).toBe("1"); -// expect(parsed.chainId).toBe(8453); -// expect(parsed.rpId).toBe("example.com"); -// }); - -// it("handles missing optional fields", () => { -// const msg = [ -// "VerbEth Key Binding v1", -// "Address: 0xabcdefabcdefabcdefabcdefabcdefabcdefabcd", -// ].join("\n"); - -// const parsed = parseBindingMessage(msg); - -// expect(parsed.header).toBe("VerbEth Key Binding v1"); -// expect(parsed.address?.toLowerCase()).toBe("0xabcdefabcdefabcdefabcdefabcdefabcdefabcd"); - -// expect(parsed.pkEd25519).toBeUndefined(); -// expect(parsed.pkX25519).toBeUndefined(); -// expect(parsed.context).toBeUndefined(); -// expect(parsed.version).toBeUndefined(); -// expect(parsed.chainId).toBeUndefined(); -// expect(parsed.rpId).toBeUndefined(); -// }); - -// it("ignores lines without ':'", () => { -// const msg = [ -// "VerbEth Key Binding v1", -// "This line has no colon", -// "Address: 0x1234567890abcdef1234567890abcdef12345678", -// ].join("\n"); - -// const parsed = parseBindingMessage(msg); -// expect(parsed.address?.toLowerCase()).toBe("0x1234567890abcdef1234567890abcdef12345678"); -// }); -// }); \ No newline at end of file +import { describe, it, expect, vi } from "vitest"; +import nacl from "tweetnacl"; +import { JsonRpcProvider } from "ethers"; + +import { getNextNonce } from "../src/utils/nonce.js"; +import { convertPublicKeyToX25519 } from "../src/utils/x25519.js"; +import { isSmartContract1271, parseBindingMessage } from "../src/utils.js"; +import { ExecutorFactory } from "../src/index.js"; +import type { LogChainV1 } from "@verbeth/contracts/typechain-types"; + +const fakeProvider = { + async getCode(addr: string) { + return addr === "0xCcโ€ฆCc" ? "0x60016000" : "0x"; + }, + async call() { + return "0x1626ba7e" + "0".repeat(56); + }, + async resolveName(name: string) { + return name; + }, +} as unknown as JsonRpcProvider; + + +describe("getNextNonce", () => { + it("increments per (sender, topic) and returns bigint", () => { + const n1 = getNextNonce("0xAlice", "topic"); + const n2 = getNextNonce("0xAlice", "topic"); + const nOther = getNextNonce("0xBob", "topic"); + expect(n2).toBe(n1 + 1n); + expect(nOther).toBe(1n); + }); +}); + +describe("Utils Functions", () => { + it("isSmartContract1271 returns true for contract bytecode", async () => { + expect(await isSmartContract1271("0xCcโ€ฆCc", fakeProvider)).toBe(true); + expect(await isSmartContract1271("0xEeโ€ฆEe", fakeProvider)).toBe(false); + }); + + it("convertPublicKeyToX25519 returns 32-byte key", () => { + const raw = new Uint8Array(64).fill(1); + const out = convertPublicKeyToX25519(raw); + expect(out).toHaveLength(32); + }); +}); + + +describe("Unified Keys Utilities", () => { + it("should handle unified key operations", () => { + expect(typeof isSmartContract1271).toBe("function"); + }); +}); + +describe("parseBindingMessage", () => { + it("parses a well-formed binding message", () => { + const msg = [ + "VerbEth Key Binding v1", + "Address: 0x1234567890abcdef1234567890abcdef12345678", + "PkEd25519: 0x" + "11".repeat(32), + "PkX25519: 0x" + "22".repeat(32), + "Context: verbeth", + "Version: 1", + "ChainId: 8453", + "RpId: example.com", + ].join("\n"); + + const parsed = parseBindingMessage(msg); + + expect(parsed.header).toBe("VerbEth Key Binding v1"); + expect(parsed.address?.toLowerCase()).toBe("0x1234567890abcdef1234567890abcdef12345678"); + expect(parsed.pkEd25519).toBe("0x" + "11".repeat(32)); + expect(parsed.pkX25519).toBe("0x" + "22".repeat(32)); + expect(parsed.context).toBe("verbeth"); + expect(parsed.version).toBe("1"); + expect(parsed.chainId).toBe(8453); + expect(parsed.rpId).toBe("example.com"); + }); + + it("handles missing optional fields", () => { + const msg = [ + "VerbEth Key Binding v1", + "Address: 0xabcdefabcdefabcdefabcdefabcdefabcdefabcd", + ].join("\n"); + + const parsed = parseBindingMessage(msg); + + expect(parsed.header).toBe("VerbEth Key Binding v1"); + expect(parsed.address?.toLowerCase()).toBe("0xabcdefabcdefabcdefabcdefabcdefabcdefabcd"); + + expect(parsed.pkEd25519).toBeUndefined(); + expect(parsed.pkX25519).toBeUndefined(); + expect(parsed.context).toBeUndefined(); + expect(parsed.version).toBeUndefined(); + expect(parsed.chainId).toBeUndefined(); + expect(parsed.rpId).toBeUndefined(); + }); + + it("ignores lines without ':'", () => { + const msg = [ + "VerbEth Key Binding v1", + "This line has no colon", + "Address: 0x1234567890abcdef1234567890abcdef12345678", + ].join("\n"); + + const parsed = parseBindingMessage(msg); + expect(parsed.address?.toLowerCase()).toBe("0x1234567890abcdef1234567890abcdef12345678"); + }); +}); \ No newline at end of file diff --git a/packages/sdk/test/verify.test.ts b/packages/sdk/test/verify.test.ts index 12e5d29..a463c14 100644 --- a/packages/sdk/test/verify.test.ts +++ b/packages/sdk/test/verify.test.ts @@ -1,355 +1,579 @@ -// import { describe, it, expect } from "vitest"; -// import { Wallet, HDNodeWallet, keccak256, toUtf8Bytes, hexlify } from "ethers"; -// import nacl from "tweetnacl"; - -// import { -// verifyIdentityProof, -// verifyHandshakeIdentity, -// verifyHandshakeResponseIdentity, -// verifyDerivedDuplexTopics, -// } from "../src/verify.js"; -// import { encryptStructuredPayload, deriveDuplexTopics } from "../src/crypto.js"; -// import { -// HandshakeResponseContent, -// encodeUnifiedPubKeys, -// parseHandshakeKeys, -// } from "../src/payload.js"; -// import { -// IdentityProof, -// HandshakeLog, -// HandshakeResponseLog, -// } from "../src/types.js"; -// import { deriveIdentityWithUnifiedKeys } from "../src/identity.js"; - -// const mockProvider: any = { -// async request({ method, params }: { method: string; params?: any[] }) { -// if (method === "eth_getCode") { -// const address = params?.[0]; -// return address && address.startsWith("0xCc") ? "0x60016000" : "0x"; -// } -// if (method === "eth_call") { -// return "0x1"; -// } -// if (method === "eth_chainId") { -// return "0x1"; -// } -// throw new Error("Unsupported method: " + method); -// }, -// }; - -// function toBytes(hex: `0x${string}`): Uint8Array { -// return Uint8Array.from(Buffer.from(hex.slice(2), "hex")); -// } -// function randomTagHex(): `0x${string}` { -// const b = nacl.randomBytes(32); -// return ("0x" + Buffer.from(b).toString("hex")) as `0x${string}`; -// } - -// function mockSafeAddress(eoaAddress: string): string { -// const hash = keccak256(toUtf8Bytes("mock-safe:" + eoaAddress.toLowerCase())); -// return "0x" + hash.slice(26); // take last 20 bytes (40 hex chars) -// } - -// describe("Verify Identity & Handshake (Unified)", () => { -// describe("Identity Proof Verification", () => { -// it("OK with correct unified keys", async () => { -// const wallet: HDNodeWallet = Wallet.createRandom(); -// const safeAddr = mockSafeAddress(wallet.address); - -// const { identityProof, identityPubKey, signingPubKey } = -// await deriveIdentityWithUnifiedKeys(wallet, wallet.address, safeAddr); - -// // Verify against the Safe address (executor) -// const result = await verifyIdentityProof( -// identityProof, -// safeAddr, -// { identityPubKey, signingPubKey }, -// mockProvider -// ); - -// expect(result).toBe(true); -// }); - -// it("KO with wrong address", async () => { -// const wallet1: HDNodeWallet = Wallet.createRandom(); -// const wallet2: HDNodeWallet = Wallet.createRandom(); -// const safeAddr1 = mockSafeAddress(wallet1.address); -// const safeAddr2 = mockSafeAddress(wallet2.address); - -// const { identityProof, identityPubKey, signingPubKey } = -// await deriveIdentityWithUnifiedKeys(wallet1, wallet1.address, safeAddr1); - -// // Verify against wrong Safe address -// const result = await verifyIdentityProof( -// identityProof, -// safeAddr2, -// { identityPubKey, signingPubKey }, -// mockProvider -// ); - -// expect(result).toBe(false); -// }); - -// it("KO with wrong keys", async () => { -// const wallet: HDNodeWallet = Wallet.createRandom(); -// const safeAddr = mockSafeAddress(wallet.address); - -// const { identityProof } = await deriveIdentityWithUnifiedKeys( -// wallet, -// wallet.address, -// safeAddr -// ); - -// const wrongKeys = { -// identityPubKey: new Uint8Array(32).fill(0xaa), -// signingPubKey: new Uint8Array(32).fill(0xbb), -// }; - -// const result = await verifyIdentityProof( -// identityProof, -// safeAddr, -// wrongKeys, -// mockProvider -// ); - -// expect(result).toBe(false); -// }); -// }); - -// describe("Handshake Verification", () => { -// it("EOA flow with unified keys", async () => { -// const wallet: HDNodeWallet = Wallet.createRandom(); -// const safeAddr = mockSafeAddress(wallet.address); - -// const { identityProof, unifiedPubKeys } = -// await deriveIdentityWithUnifiedKeys(wallet, wallet.address, safeAddr); - -// // Sender is the Safe address (since Safe sends the tx) -// const handshakeEvent: HandshakeLog = { -// recipientHash: keccak256(toUtf8Bytes("contact:0xdead")), -// sender: safeAddr, -// pubKeys: hexlify(unifiedPubKeys), -// ephemeralPubKey: hexlify(nacl.box.keyPair().publicKey), -// plaintextPayload: JSON.stringify({ -// plaintextPayload: "Hi VerbEth", -// identityProof, -// }), -// }; - -// const result = await verifyHandshakeIdentity( -// handshakeEvent, -// mockProvider -// ); -// expect(result).toBe(true); -// }); - -// it("fails with invalid identity proof", async () => { -// const wallet: HDNodeWallet = Wallet.createRandom(); -// const safeAddr = mockSafeAddress(wallet.address); - -// const { unifiedPubKeys } = await deriveIdentityWithUnifiedKeys( -// wallet, -// wallet.address, -// safeAddr -// ); - -// const differentWallet: HDNodeWallet = Wallet.createRandom(); -// const invalidMessage = "Invalid message for verification"; -// const invalidSignature = await differentWallet.signMessage( -// invalidMessage -// ); - -// const invalidIdentityProof: IdentityProof = { -// message: invalidMessage, -// signature: invalidSignature, -// }; - -// const handshakeEvent: HandshakeLog = { -// recipientHash: keccak256(toUtf8Bytes("contact:0xdead")), -// sender: safeAddr, -// pubKeys: hexlify(unifiedPubKeys), -// ephemeralPubKey: hexlify(nacl.box.keyPair().publicKey), -// plaintextPayload: JSON.stringify({ -// plaintextPayload: "Hi VerbEth", -// identityProof: invalidIdentityProof, -// }), -// }; - -// const result = await verifyHandshakeIdentity( -// handshakeEvent, -// mockProvider -// ); -// expect(result).toBe(false); -// }); -// }); - -// describe("Handshake Response Verification", () => { -// it("EOA flow with unified keys", async () => { -// const responderWallet: HDNodeWallet = Wallet.createRandom(); -// const responderSafeAddr = mockSafeAddress(responderWallet.address); - -// const { identityProof, identityPubKey, unifiedPubKeys } = -// await deriveIdentityWithUnifiedKeys( -// responderWallet, -// responderWallet.address, -// responderSafeAddr -// ); - -// const aliceEphemeral = nacl.box.keyPair(); -// const responderEphemeral = nacl.box.keyPair(); - -// const responseContent: HandshakeResponseContent = { -// unifiedPubKeys, -// ephemeralPubKey: responderEphemeral.publicKey, -// note: "pong", -// identityProof, -// }; - -// const payload = encryptStructuredPayload( -// responseContent, -// aliceEphemeral.publicKey, -// responderEphemeral.secretKey, -// responderEphemeral.publicKey -// ); - -// // Responder is the Safe address -// const responseEvent: HandshakeResponseLog = { -// inResponseTo: keccak256(toUtf8Bytes("test-handshake")), -// responder: responderSafeAddr, -// responderEphemeralR: hexlify(responderEphemeral.publicKey), -// ciphertext: payload, -// }; - -// const result = await verifyHandshakeResponseIdentity( -// responseEvent, -// identityPubKey, -// aliceEphemeral.secretKey, -// mockProvider -// ); - -// expect(result).toBe(true); -// }); - -// it("fails with wrong identity key", async () => { -// const responderWallet: HDNodeWallet = Wallet.createRandom(); -// const responderSafeAddr = mockSafeAddress(responderWallet.address); - -// const { identityProof, unifiedPubKeys } = -// await deriveIdentityWithUnifiedKeys( -// responderWallet, -// responderWallet.address, -// responderSafeAddr -// ); - -// const aliceEphemeral = nacl.box.keyPair(); -// const responderEphemeral = nacl.box.keyPair(); - -// const responseContent: HandshakeResponseContent = { -// unifiedPubKeys, -// ephemeralPubKey: responderEphemeral.publicKey, -// note: "pong", -// identityProof, -// }; - -// const payload = encryptStructuredPayload( -// responseContent, -// aliceEphemeral.publicKey, -// responderEphemeral.secretKey, -// responderEphemeral.publicKey -// ); - -// const responseEvent: HandshakeResponseLog = { -// inResponseTo: keccak256(toUtf8Bytes("test-handshake")), -// responder: responderSafeAddr, -// responderEphemeralR: hexlify(responderEphemeral.publicKey), -// ciphertext: payload, -// }; - -// const wrongIdentityKey = new Uint8Array(32).fill(0xff); - -// const result = await verifyHandshakeResponseIdentity( -// responseEvent, -// wrongIdentityKey, -// aliceEphemeral.secretKey, -// mockProvider -// ); - -// expect(result).toBe(false); -// }); -// }); - -// describe("Key Parsing", () => { -// it("parseHandshakeKeys extracts unified keys correctly", () => { -// const identityPubKey = new Uint8Array(32).fill(1); -// const signingPubKey = new Uint8Array(32).fill(2); -// const unifiedPubKeys = encodeUnifiedPubKeys( -// identityPubKey, -// signingPubKey -// ); - -// const event = { pubKeys: hexlify(unifiedPubKeys) }; -// const parsed = parseHandshakeKeys(event); - -// expect(parsed).not.toBeNull(); -// expect(parsed!.identityPubKey).toEqual(identityPubKey); -// expect(parsed!.signingPubKey).toEqual(signingPubKey); -// }); - -// it("parseHandshakeKeys returns null for invalid keys", () => { -// const event = { pubKeys: "0x1234" }; -// const parsed = parseHandshakeKeys(event); -// expect(parsed).toBeNull(); -// }); -// }); - -// it("verifyDerivedDuplexTopics accepts tag hex and validates checksum from TopicInfo", () => { -// const alice = nacl.box.keyPair(); -// const bob = nacl.box.keyPair(); - -// const tag = randomTagHex(); -// const salt = toBytes(tag); - -// // Bob would embed TopicInfo in HSR -// const { topicOut, topicIn, checksum } = deriveDuplexTopics( -// bob.secretKey, -// alice.publicKey, -// salt -// ); -// const topicInfo = { out: topicOut, in: topicIn, chk: checksum }; - -// // Alice verifies after decrypting HSR -// const { topics, ok } = verifyDerivedDuplexTopics({ -// myIdentitySecretKey: alice.secretKey, -// theirIdentityPubKey: bob.publicKey, -// tag, -// topicInfo, -// }); - -// expect(ok).toBe(true); -// expect(topics.topicOut).toBe(topicOut); -// expect(topics.topicIn).toBe(topicIn); -// }); - -// it("verifyDerivedDuplexTopics works with raw salt (no tag) and throws with neither", () => { -// const alice = nacl.box.keyPair(); -// const bob = nacl.box.keyPair(); - -// const salt = toBytes(randomTagHex()); - -// const { topics } = verifyDerivedDuplexTopics({ -// myIdentitySecretKey: alice.secretKey, -// theirIdentityPubKey: bob.publicKey, -// salt, -// }); - -// expect(topics.topicOut.startsWith("0x")).toBe(true); -// expect(topics.topicIn.startsWith("0x")).toBe(true); - -// expect(() => -// verifyDerivedDuplexTopics({ -// myIdentitySecretKey: alice.secretKey, -// theirIdentityPubKey: bob.publicKey, -// } as any) -// ).toThrow(); -// }); -// }); \ No newline at end of file +import { describe, it, expect } from "vitest"; +import nacl from "tweetnacl"; +import { + encryptStructuredPayload, + decryptStructuredPayload, + decryptHandshakeResponse, + decryptAndExtractHandshakeKeys, +} from "../src/crypto.js"; +import { + HandshakePayload, + encodeHandshakePayload, + decodeHandshakePayload, + encodeHandshakeResponseContent, + decodeHandshakeResponseContent, + MessagePayload, + HandshakeResponseContent, + encodeUnifiedPubKeys, + extractKeysFromHandshakePayload, + extractKeysFromHandshakeResponse, + parseHandshakeKeys, +} from "../src/payload.js"; +import { IdentityProof } from "../src/types.js"; + +describe("Encryption/Decryption", () => { + describe("Structured Payload Encryption", () => { + it("should encrypt and decrypt structured message format", () => { + const senderBoxKey = nacl.box.keyPair(); + const senderSignKey = nacl.sign.keyPair(); + const recipientKey = nacl.box.keyPair(); + + const messagePayload: MessagePayload = { + content: "Hello structured VerbEth!", + timestamp: Date.now(), + messageType: "text", + }; + + const encrypted = encryptStructuredPayload( + messagePayload, + recipientKey.publicKey, + senderBoxKey.secretKey, + senderBoxKey.publicKey, + senderSignKey.secretKey, + senderSignKey.publicKey + ); + + const decrypted = decryptStructuredPayload( + encrypted, + recipientKey.secretKey, + (obj) => obj as MessagePayload, + senderSignKey.publicKey + ); + + expect(decrypted).toEqual(messagePayload); + }); + + it("should encrypt structured payload without signing keys", () => { + const senderBoxKey = nacl.box.keyPair(); + const recipientKey = nacl.box.keyPair(); + + const messagePayload: MessagePayload = { + content: "Unsigned structured message", + timestamp: Date.now(), + messageType: "text", + }; + + const encrypted = encryptStructuredPayload( + messagePayload, + recipientKey.publicKey, + senderBoxKey.secretKey, + senderBoxKey.publicKey + ); + + const decrypted = decryptStructuredPayload( + encrypted, + recipientKey.secretKey, + (obj) => obj as MessagePayload + ); + + expect(decrypted).toEqual(messagePayload); + }); + + it("should return null on decryption with wrong recipient key", () => { + const senderBoxKey = nacl.box.keyPair(); + const recipientKey = nacl.box.keyPair(); + const wrongKey = nacl.box.keyPair(); + + const messagePayload: MessagePayload = { + content: "Test message", + timestamp: Date.now(), + messageType: "text", + }; + + const encrypted = encryptStructuredPayload( + messagePayload, + recipientKey.publicKey, + senderBoxKey.secretKey, + senderBoxKey.publicKey + ); + + const decrypted = decryptStructuredPayload( + encrypted, + wrongKey.secretKey, + (obj) => obj as MessagePayload + ); + + expect(decrypted).toBeNull(); + }); + }); + + describe("Handshake Response Encryption", () => { + it("should encrypt and decrypt handshake response content", () => { + const initiatorEphemeralKey = nacl.box.keyPair(); + const responderEphemeralKey = nacl.box.keyPair(); + + const identityPubKey = new Uint8Array(32).fill(3); + const signingPubKey = new Uint8Array(32).fill(7); + const unifiedPubKeys = encodeUnifiedPubKeys(identityPubKey, signingPubKey); + + const ephemeralPubKey = new Uint8Array(32).fill(4); + const note = "here is my response"; + + const identityProof: IdentityProof = { + message: "VerbEth Identity Key Identity v1\nAddress: 0x1234...", + signature: "0x" + "1".repeat(130), + }; + + const responseContent: HandshakeResponseContent = { + unifiedPubKeys, + ephemeralPubKey, + note, + identityProof, + }; + + const encrypted = encryptStructuredPayload( + responseContent, + initiatorEphemeralKey.publicKey, + responderEphemeralKey.secretKey, + responderEphemeralKey.publicKey + ); + + const decrypted = decryptHandshakeResponse( + encrypted, + initiatorEphemeralKey.secretKey + ); + + expect(decrypted).not.toBeNull(); + expect(decrypted!.unifiedPubKeys).toEqual(unifiedPubKeys); + expect(decrypted!.ephemeralPubKey).toEqual(ephemeralPubKey); + expect(decrypted!.note).toBe(note); + expect(decrypted!.identityProof).toEqual(identityProof); + }); + + it("should handle handshake response with identity proof", () => { + const initiatorEphemeralKey = nacl.box.keyPair(); + const responderEphemeralKey = nacl.box.keyPair(); + + const identityPubKey = new Uint8Array(32).fill(5); + const signingPubKey = new Uint8Array(32).fill(8); + const unifiedPubKeys = encodeUnifiedPubKeys(identityPubKey, signingPubKey); + + const ephemeralPubKey = new Uint8Array(32).fill(6); + + const identityProof: IdentityProof = { + message: "VerbEth Identity Key identity v1\nAddress: 0xabcd...", + signature: "0x" + "2".repeat(130), + }; + + const responseContent: HandshakeResponseContent = { + unifiedPubKeys, + ephemeralPubKey, + note: "with identity proof", + identityProof, + }; + + const encrypted = encryptStructuredPayload( + responseContent, + initiatorEphemeralKey.publicKey, + responderEphemeralKey.secretKey, + responderEphemeralKey.publicKey + ); + + const decrypted = decryptHandshakeResponse( + encrypted, + initiatorEphemeralKey.secretKey + ); + + expect(decrypted).not.toBeNull(); + expect(decrypted!.identityProof).toEqual(identityProof); + }); + }); + + describe("decryptAndExtractHandshakeKeys", () => { + it("should decrypt and extract all keys from handshake response", () => { + const initiatorEphemeralKey = nacl.box.keyPair(); + const responderEphemeralKey = nacl.box.keyPair(); + + const identityPubKey = new Uint8Array(32).fill(10); + const signingPubKey = new Uint8Array(32).fill(11); + const unifiedPubKeys = encodeUnifiedPubKeys(identityPubKey, signingPubKey); + const ephemeralPubKey = new Uint8Array(32).fill(12); + const note = "convenience function test"; + + const identityProof: IdentityProof = { + message: "VerbEth Identity Key Identity v1\nAddress: 0xtest...", + signature: "0x" + "3".repeat(130), + }; + + const responseContent: HandshakeResponseContent = { + unifiedPubKeys, + ephemeralPubKey, + note, + identityProof, + }; + + const encrypted = encryptStructuredPayload( + responseContent, + initiatorEphemeralKey.publicKey, + responderEphemeralKey.secretKey, + responderEphemeralKey.publicKey + ); + + const result = decryptAndExtractHandshakeKeys( + encrypted, + initiatorEphemeralKey.secretKey + ); + + expect(result).not.toBeNull(); + expect(result!.identityPubKey).toEqual(identityPubKey); + expect(result!.signingPubKey).toEqual(signingPubKey); + expect(result!.ephemeralPubKey).toEqual(ephemeralPubKey); + expect(result!.note).toBe(note); + expect(result!.identityProof).toEqual(identityProof); + }); + + it("should return null for invalid encrypted data", () => { + const initiatorEphemeralKey = nacl.box.keyPair(); + + const invalidPayload = { + v: 1, + epk: Buffer.from(new Uint8Array(32).fill(1)).toString("base64"), + n: Buffer.from(new Uint8Array(24).fill(2)).toString("base64"), + ct: Buffer.from(new Uint8Array(16).fill(3)).toString("base64"), + }; + const invalidEncrypted = JSON.stringify(invalidPayload); + + const result = decryptAndExtractHandshakeKeys( + invalidEncrypted, + initiatorEphemeralKey.secretKey + ); + + expect(result).toBeNull(); + }); + + it("should return null with wrong decryption key", () => { + const initiatorEphemeralKey = nacl.box.keyPair(); + const responderEphemeralKey = nacl.box.keyPair(); + const wrongKey = nacl.box.keyPair(); + + const identityPubKey = new Uint8Array(32).fill(13); + const signingPubKey = new Uint8Array(32).fill(14); + const unifiedPubKeys = encodeUnifiedPubKeys(identityPubKey, signingPubKey); + + const identityProof: IdentityProof = { + message: "Wrong key test", + signature: "0x" + "4".repeat(130), + }; + + const responseContent: HandshakeResponseContent = { + unifiedPubKeys, + ephemeralPubKey: new Uint8Array(32).fill(15), + note: "should fail", + identityProof, + }; + + const encrypted = encryptStructuredPayload( + responseContent, + initiatorEphemeralKey.publicKey, + responderEphemeralKey.secretKey, + responderEphemeralKey.publicKey + ); + + const result = decryptAndExtractHandshakeKeys( + encrypted, + wrongKey.secretKey + ); + + expect(result).toBeNull(); + }); + }); + + describe("Key Extraction Functions", () => { + it("should extract keys from handshake payload", () => { + const identityPubKey = new Uint8Array(32).fill(20); + const signingPubKey = new Uint8Array(32).fill(21); + const ephemeralPubKey = new Uint8Array(32).fill(22); + const unifiedPubKeys = encodeUnifiedPubKeys(identityPubKey, signingPubKey); + + const payload: HandshakePayload = { + unifiedPubKeys, + ephemeralPubKey, + plaintextPayload: "test payload", + }; + + const extracted = extractKeysFromHandshakePayload(payload); + + expect(extracted).not.toBeNull(); + expect(extracted!.identityPubKey).toEqual(identityPubKey); + expect(extracted!.signingPubKey).toEqual(signingPubKey); + expect(extracted!.ephemeralPubKey).toEqual(ephemeralPubKey); + }); + + it("should extract keys from handshake response content", () => { + const identityPubKey = new Uint8Array(32).fill(25); + const signingPubKey = new Uint8Array(32).fill(26); + const ephemeralPubKey = new Uint8Array(32).fill(27); + const unifiedPubKeys = encodeUnifiedPubKeys(identityPubKey, signingPubKey); + + const identityProof: IdentityProof = { + message: "Extract test", + signature: "0x" + "5".repeat(130), + }; + + const content: HandshakeResponseContent = { + unifiedPubKeys, + ephemeralPubKey, + note: "extract test", + identityProof, + }; + + const extracted = extractKeysFromHandshakeResponse(content); + + expect(extracted).not.toBeNull(); + expect(extracted!.identityPubKey).toEqual(identityPubKey); + expect(extracted!.signingPubKey).toEqual(signingPubKey); + expect(extracted!.ephemeralPubKey).toEqual(ephemeralPubKey); + }); + + it("should return null for invalid unified keys in payload", () => { + const invalidUnifiedKeys = new Uint8Array(30).fill(1); // Wrong size + + const payload: HandshakePayload = { + unifiedPubKeys: invalidUnifiedKeys, + ephemeralPubKey: new Uint8Array(32).fill(2), + plaintextPayload: "invalid test", + }; + + const extracted = extractKeysFromHandshakePayload(payload); + expect(extracted).toBeNull(); + }); + + it("should return null for invalid unified keys in response content", () => { + const invalidUnifiedKeys = new Uint8Array(30).fill(1); // Wrong size + + const identityProof: IdentityProof = { + message: "Invalid test", + signature: "0x" + "6".repeat(130), + }; + + const content: HandshakeResponseContent = { + unifiedPubKeys: invalidUnifiedKeys, + ephemeralPubKey: new Uint8Array(32).fill(2), + note: "invalid test", + identityProof, + }; + + const extracted = extractKeysFromHandshakeResponse(content); + expect(extracted).toBeNull(); + }); + }); + + describe("Handshake Key Parsing", () => { + it("should parse handshake keys from event correctly", () => { + const identityPubKey = new Uint8Array(32).fill(30); + const signingPubKey = new Uint8Array(32).fill(31); + const unifiedPubKeys = encodeUnifiedPubKeys(identityPubKey, signingPubKey); + + const event = { + pubKeys: "0x" + Buffer.from(unifiedPubKeys).toString("hex"), + }; + + const parsed = parseHandshakeKeys(event); + + expect(parsed).not.toBeNull(); + expect(parsed!.identityPubKey).toEqual(identityPubKey); + expect(parsed!.signingPubKey).toEqual(signingPubKey); + }); + + it("should return null for invalid hex in pubKeys", () => { + const event = { + pubKeys: "0xinvalidhex", + }; + + const parsed = parseHandshakeKeys(event); + expect(parsed).toBeNull(); + }); + + it("should return null for wrong size pubKeys", () => { + const shortKeys = new Uint8Array(30).fill(1); // Wrong size + + const event = { + pubKeys: "0x" + Buffer.from(shortKeys).toString("hex"), + }; + + const parsed = parseHandshakeKeys(event); + expect(parsed).toBeNull(); + }); + + it("should handle pubKeys with 0x prefix", () => { + const identityPubKey = new Uint8Array(32).fill(35); + const signingPubKey = new Uint8Array(32).fill(36); + const unifiedPubKeys = encodeUnifiedPubKeys(identityPubKey, signingPubKey); + + const event = { + pubKeys: "0x" + Buffer.from(unifiedPubKeys).toString("hex"), + }; + + const parsed = parseHandshakeKeys(event); + + expect(parsed).not.toBeNull(); + expect(parsed!.identityPubKey).toEqual(identityPubKey); + expect(parsed!.signingPubKey).toEqual(signingPubKey); + }); + }); + + describe("Error Handling", () => { + it("should throw error for malformed JSON in decryptStructuredPayload", () => { + const recipientKey = nacl.box.keyPair(); + const malformedJson = "invalid json"; + + expect(() => { + decryptStructuredPayload( + malformedJson, + recipientKey.secretKey, + (obj) => obj as MessagePayload + ); + }).toThrow(); + }); + + it("should throw error for missing fields in payload", () => { + const recipientKey = nacl.box.keyPair(); + const incompletePayload = JSON.stringify({ + epk: Buffer.from(new Uint8Array(32)).toString("base64"), + // Missing nonce and ciphertext + }); + + expect(() => { + decryptStructuredPayload( + incompletePayload, + recipientKey.secretKey, + (obj) => obj as MessagePayload + ); + }).toThrow(); + }); + + it("should throw error for invalid base64 in payload fields", () => { + const recipientKey = nacl.box.keyPair(); + const invalidPayload = JSON.stringify({ + epk: "invalid-base64!", + n: "invalid-base64!", + ct: "invalid-base64!", + }); + + expect(() => { + decryptStructuredPayload( + invalidPayload, + recipientKey.secretKey, + (obj) => obj as MessagePayload + ); + }).toThrow(); + }); + + it("should throw error when converter function throws error", () => { + const senderBoxKey = nacl.box.keyPair(); + const recipientKey = nacl.box.keyPair(); + + const messagePayload: MessagePayload = { + content: "Test message", + timestamp: Date.now(), + messageType: "text", + }; + + const encrypted = encryptStructuredPayload( + messagePayload, + recipientKey.publicKey, + senderBoxKey.secretKey, + senderBoxKey.publicKey + ); + + const throwingConverter = () => { + throw new Error("Converter error"); + }; + + expect(() => { + decryptStructuredPayload( + encrypted, + recipientKey.secretKey, + throwingConverter + ); + }).toThrow("Converter error"); + }); + + it("should throw error for decryptHandshakeResponse with missing identityProof", () => { + const initiatorEphemeralKey = nacl.box.keyPair(); + const responderEphemeralKey = nacl.box.keyPair(); + + // Create content without identityProof + const invalidContent = { + unifiedPubKeys: encodeUnifiedPubKeys( + new Uint8Array(32).fill(40), + new Uint8Array(32).fill(41) + ), + ephemeralPubKey: new Uint8Array(32).fill(42), + note: "missing proof", + // No identityProof + }; + + const encrypted = encryptStructuredPayload( + invalidContent, + initiatorEphemeralKey.publicKey, + responderEphemeralKey.secretKey, + responderEphemeralKey.publicKey + ); + + expect(() => { + decryptHandshakeResponse(encrypted, initiatorEphemeralKey.secretKey); + }).toThrow("Invalid handshake response: missing identityProof"); + }); + }); + + describe("Payload Encoding/Decoding", () => { + it("should encode and decode handshake payload correctly", () => { + const identityPubKey = new Uint8Array(32).fill(1); + const signingPubKey = new Uint8Array(32).fill(9); + const unifiedPubKeys = encodeUnifiedPubKeys(identityPubKey, signingPubKey); + + const payload: HandshakePayload = { + unifiedPubKeys, + ephemeralPubKey: new Uint8Array(32).fill(2), + plaintextPayload: "hello bob", + }; + + const encoded = encodeHandshakePayload(payload); + const decoded = decodeHandshakePayload(encoded); + + expect(decoded.unifiedPubKeys).toEqual(payload.unifiedPubKeys); + expect(decoded.ephemeralPubKey).toEqual(payload.ephemeralPubKey); + expect(decoded.plaintextPayload).toBe("hello bob"); + }); + + it("should encode and decode response content correctly", () => { + const identityPubKey = new Uint8Array(32).fill(3); + const signingPubKey = new Uint8Array(32).fill(10); + const unifiedPubKeys = encodeUnifiedPubKeys(identityPubKey, signingPubKey); + + const ephemeralPubKey = new Uint8Array(32).fill(4); + const note = "here is my response"; + + const identityProof: IdentityProof = { + message: "VerbEth Identity Key Identity v1\nAddress: 0xtest...", + signature: "0x" + "3".repeat(130), + }; + + const content: HandshakeResponseContent = { + unifiedPubKeys, + ephemeralPubKey, + note, + identityProof, + }; + + const encoded = encodeHandshakeResponseContent(content); + const decoded = decodeHandshakeResponseContent(encoded); + + expect(decoded.unifiedPubKeys).toEqual(unifiedPubKeys); + expect(decoded.ephemeralPubKey).toEqual(ephemeralPubKey); + expect(decoded.note).toBe(note); + expect(decoded.identityProof).toEqual(identityProof); + }); + }); +}); \ No newline at end of file From 9c0531a359de10d908edcafb0dbef6f6803ba7b6 Mon Sep 17 00:00:00 2001 From: Marco Esposito Date: Sat, 24 Jan 2026 16:38:19 +0100 Subject: [PATCH 17/51] core: hybrid post-quantum key exchange --- .cluadeignore | 29 + .gitignore | 3 + apps/demo/src/App.tsx | 1 - apps/demo/src/components/IdentityCreation.tsx | 2 +- apps/demo/src/hooks/useChatActions.ts | 17 +- apps/demo/src/hooks/useInitIdentity.ts | 4 - .../src/services/EventProcessorService.ts | 19 +- apps/demo/src/types.ts | 8 +- apps/demo/vite.config.ts | 6 +- apps/docs/.gitignore | 20 + apps/docs/README.md | 41 + apps/docs/blog/2019-05-28-first-blog-post.md | 12 + apps/docs/blog/2019-05-29-long-blog-post.md | 44 + apps/docs/blog/2021-08-01-mdx-blog-post.mdx | 24 + .../docusaurus-plushie-banner.jpeg | Bin 0 -> 96122 bytes apps/docs/blog/2021-08-26-welcome/index.md | 29 + apps/docs/blog/authors.yml | 25 + apps/docs/blog/tags.yml | 19 + apps/docs/docs/intro.md | 47 + .../docs/docs/tutorial-basics/_category_.json | 8 + .../docs/tutorial-basics/congratulations.md | 23 + .../tutorial-basics/create-a-blog-post.md | 34 + .../docs/tutorial-basics/create-a-document.md | 57 + .../docs/tutorial-basics/create-a-page.md | 43 + .../docs/tutorial-basics/deploy-your-site.md | 31 + .../tutorial-basics/markdown-features.mdx | 152 + .../docs/docs/tutorial-extras/_category_.json | 7 + .../img/docsVersionDropdown.png | Bin 0 -> 25427 bytes .../tutorial-extras/img/localeDropdown.png | Bin 0 -> 27841 bytes .../tutorial-extras/manage-docs-versions.md | 55 + .../tutorial-extras/translate-your-site.md | 88 + apps/docs/docusaurus.config.ts | 150 + apps/docs/double-ratchet.md | 335 - apps/docs/metadata-privacy.md | 63 - apps/docs/package.json | 47 + apps/docs/replay-protection.md | 64 - apps/docs/sidebars.ts | 33 + .../src/components/HomepageFeatures/index.tsx | 71 + .../HomepageFeatures/styles.module.css | 11 + apps/docs/src/css/custom.css | 30 + apps/docs/src/pages/index.module.css | 23 + apps/docs/src/pages/index.tsx | 44 + apps/docs/src/pages/markdown-page.md | 7 + apps/docs/static/.nojekyll | 0 .../static/img/docusaurus-social-card.jpg | Bin 0 -> 55746 bytes apps/docs/static/img/docusaurus.png | Bin 0 -> 5142 bytes apps/docs/static/img/favicon.ico | Bin 0 -> 3626 bytes apps/docs/static/img/logo.svg | 1 + .../static/img/undraw_docusaurus_mountain.svg | 171 + .../static/img/undraw_docusaurus_react.svg | 170 + .../static/img/undraw_docusaurus_tree.svg | 40 + apps/docs/topic-ratcheting.md | 165 - apps/docs/tsconfig.json | 8 + packages/sdk/package.json | 1 + packages/sdk/src/client/PendingManager.ts | 4 - packages/sdk/src/client/VerbethClient.ts | 118 +- packages/sdk/src/client/types.ts | 7 +- packages/sdk/src/crypto.ts | 9 +- packages/sdk/src/index.ts | 4 +- packages/sdk/src/payload.ts | 36 +- packages/sdk/src/pq/kem.ts | 46 + packages/sdk/src/ratchet/index.ts | 1 + packages/sdk/src/ratchet/kdf.ts | 17 + packages/sdk/src/ratchet/session.ts | 40 +- packages/sdk/src/ratchet/types.ts | 4 + packages/sdk/src/send.ts | 109 +- packages/sdk/src/verify.ts | 13 +- packages/sdk/test/pq.test.ts | 264 + pnpm-lock.yaml | 25815 +++++++++++----- verbeth-client-plan.md | 1236 - 70 files changed, 20044 insertions(+), 9961 deletions(-) create mode 100644 .cluadeignore create mode 100644 apps/docs/.gitignore create mode 100644 apps/docs/README.md create mode 100644 apps/docs/blog/2019-05-28-first-blog-post.md create mode 100644 apps/docs/blog/2019-05-29-long-blog-post.md create mode 100644 apps/docs/blog/2021-08-01-mdx-blog-post.mdx create mode 100644 apps/docs/blog/2021-08-26-welcome/docusaurus-plushie-banner.jpeg create mode 100644 apps/docs/blog/2021-08-26-welcome/index.md create mode 100644 apps/docs/blog/authors.yml create mode 100644 apps/docs/blog/tags.yml create mode 100644 apps/docs/docs/intro.md create mode 100644 apps/docs/docs/tutorial-basics/_category_.json create mode 100644 apps/docs/docs/tutorial-basics/congratulations.md create mode 100644 apps/docs/docs/tutorial-basics/create-a-blog-post.md create mode 100644 apps/docs/docs/tutorial-basics/create-a-document.md create mode 100644 apps/docs/docs/tutorial-basics/create-a-page.md create mode 100644 apps/docs/docs/tutorial-basics/deploy-your-site.md create mode 100644 apps/docs/docs/tutorial-basics/markdown-features.mdx create mode 100644 apps/docs/docs/tutorial-extras/_category_.json create mode 100644 apps/docs/docs/tutorial-extras/img/docsVersionDropdown.png create mode 100644 apps/docs/docs/tutorial-extras/img/localeDropdown.png create mode 100644 apps/docs/docs/tutorial-extras/manage-docs-versions.md create mode 100644 apps/docs/docs/tutorial-extras/translate-your-site.md create mode 100644 apps/docs/docusaurus.config.ts delete mode 100644 apps/docs/double-ratchet.md delete mode 100644 apps/docs/metadata-privacy.md create mode 100644 apps/docs/package.json delete mode 100644 apps/docs/replay-protection.md create mode 100644 apps/docs/sidebars.ts create mode 100644 apps/docs/src/components/HomepageFeatures/index.tsx create mode 100644 apps/docs/src/components/HomepageFeatures/styles.module.css create mode 100644 apps/docs/src/css/custom.css create mode 100644 apps/docs/src/pages/index.module.css create mode 100644 apps/docs/src/pages/index.tsx create mode 100644 apps/docs/src/pages/markdown-page.md create mode 100644 apps/docs/static/.nojekyll create mode 100644 apps/docs/static/img/docusaurus-social-card.jpg create mode 100644 apps/docs/static/img/docusaurus.png create mode 100644 apps/docs/static/img/favicon.ico create mode 100644 apps/docs/static/img/logo.svg create mode 100644 apps/docs/static/img/undraw_docusaurus_mountain.svg create mode 100644 apps/docs/static/img/undraw_docusaurus_react.svg create mode 100644 apps/docs/static/img/undraw_docusaurus_tree.svg delete mode 100644 apps/docs/topic-ratcheting.md create mode 100644 apps/docs/tsconfig.json create mode 100644 packages/sdk/src/pq/kem.ts create mode 100644 packages/sdk/test/pq.test.ts delete mode 100644 verbeth-client-plan.md diff --git a/.cluadeignore b/.cluadeignore new file mode 100644 index 0000000..4799b82 --- /dev/null +++ b/.cluadeignore @@ -0,0 +1,29 @@ +node_modules +.env +dist + +dist + +# Hardhat files +/cache +/artifacts + +# TypeChain files +/typechain +/typechain-types + +# solidity-coverage files +/coverage +/coverage.json + +ignition/deployments/chain-31337 +ignition/deployments/chain-84532 +.aider* +.venv/ +.envrc +.python-version + +*apps/notes/ + +pnpm-lock.yaml +/tests \ No newline at end of file diff --git a/.gitignore b/.gitignore index 4a5b58c..c5536d7 100644 --- a/.gitignore +++ b/.gitignore @@ -22,3 +22,6 @@ ignition/deployments/chain-84532 .venv/ .envrc .python-version + +*apps/notes/ +.claudeignore \ No newline at end of file diff --git a/apps/demo/src/App.tsx b/apps/demo/src/App.tsx index a6c2a5f..27c1569 100644 --- a/apps/demo/src/App.tsx +++ b/apps/demo/src/App.tsx @@ -24,7 +24,6 @@ import { useSessionSetup } from './hooks/useSessionSetup.js'; import { useInitIdentity } from './hooks/useInitIdentity.js'; import { usePendingSessionReset } from './hooks/usePendingSessionReset.js'; import { PinnedResetRequest } from './components/PinnedResetRequest.js'; -// NEW: Import storage adapter configuration import { configureClientStorage } from './services/StorageAdapters.js'; export default function App() { diff --git a/apps/demo/src/components/IdentityCreation.tsx b/apps/demo/src/components/IdentityCreation.tsx index 526c476..bf1286e 100644 --- a/apps/demo/src/components/IdentityCreation.tsx +++ b/apps/demo/src/components/IdentityCreation.tsx @@ -200,7 +200,7 @@ export function IdentityCreation({
- {/* NEW: Mode Selection (before identity creation) */} + {/* Mode Selection (before identity creation) */} {needsModeSelection && !selectedMode && !signingStep && (
{ @@ -91,7 +91,7 @@ export const useChatActions = ({ setLoading(true); try { - const { tx, ephemeralKeyPair } = await verbethClient.sendHandshake( + const { tx, ephemeralKeyPair, kemKeyPair } = await verbethClient.sendHandshake( recipientAddress, message ); @@ -101,6 +101,7 @@ export const useChatActions = ({ ownerAddress: verbethClient.userAddress, status: "handshake_sent", handshakeEphemeralSecret: hexlify(ephemeralKeyPair.secretKey), + handshakeKemSecret: hexlify(kemKeyPair.secretKey), lastMessage: message, lastTimestamp: Date.now(), }; @@ -158,6 +159,7 @@ export const useChatActions = ({ /** * Accept a handshake from another user. * Creates ratchet session using VerbethClient and establishes contact. + * Supports PQ-hybrid: if initiator includes KEM, kemSharedSecret is derived. */ const acceptHandshake = useCallback( async (handshake: any, responseMessage: string) => { @@ -167,23 +169,28 @@ export const useChatActions = ({ } try { + // Use full ephemeral key (may include KEM public key) + const ephemeralKey = handshake.ephemeralPubKeyFull || handshake.ephemeralPubKey; + const { salt, responderEphemeralSecret, responderEphemeralPublic, + kemSharedSecret, } = await verbethClient.acceptHandshake( - handshake.ephemeralPubKey, + ephemeralKey, handshake.identityPubKey, responseMessage ); - // Create session using VerbethClient (handles topic derivation internally) + // Create session using VerbethClient (handles topic derivation and hybrid KDF) const ratchetSession = verbethClient.createResponderSession({ contactAddress: handshake.sender, responderEphemeralSecret, responderEphemeralPublic, - initiatorEphemeralPubKey: handshake.ephemeralPubKey, + initiatorEphemeralPubKey: ephemeralKey, salt, + kemSharedSecret, }); // Save session - SDK will pick it up via SessionStore adapter diff --git a/apps/demo/src/hooks/useInitIdentity.ts b/apps/demo/src/hooks/useInitIdentity.ts index 65f355e..c152657 100644 --- a/apps/demo/src/hooks/useInitIdentity.ts +++ b/apps/demo/src/hooks/useInitIdentity.ts @@ -92,7 +92,6 @@ export function useInitIdentity({ setNeedsSessionSetup(false); setIsSafeDeployed(false); setIsModuleEnabled(false); - // NEW setExecutionMode(null); setNeedsModeSelection(false); setEmitterAddress(null); @@ -244,9 +243,6 @@ export function useInitIdentity({ setContract(contractInstance); }, [walletClient, address, currentAccount, chainId, readProvider, addLog, switchToAccount]); - // =========================================================================== - // NEW: Mode-aware identity creation - // =========================================================================== const createIdentity = useCallback(async (selectedMode: ExecutionMode) => { if (!identitySigner || !address || !walletClient) { addLog('โœ— Missing signer/provider or address'); diff --git a/apps/demo/src/services/EventProcessorService.ts b/apps/demo/src/services/EventProcessorService.ts index 944df45..ff599c5 100644 --- a/apps/demo/src/services/EventProcessorService.ts +++ b/apps/demo/src/services/EventProcessorService.ts @@ -89,7 +89,11 @@ export async function processHandshakeEvent( const identityPubKey = decodedKeys.identityPubKey; const signingPubKey = decodedKeys.signingPubKey; - const ephemeralPubKey = getBytes(ephemeralPubKeyBytes); + const ephemeralPubKeyFull = getBytes(ephemeralPubKeyBytes); + // Extract X25519 part (first 32 bytes) for backward compatibility + const ephemeralPubKey = ephemeralPubKeyFull.length > 32 + ? ephemeralPubKeyFull.slice(0, 32) + : ephemeralPubKeyFull; const plaintextPayload = new TextDecoder().decode( getBytes(plaintextPayloadBytes) ); @@ -152,7 +156,8 @@ export async function processHandshakeEvent( emitterAddress: cleanSenderAddress, identityPubKey, signingPubKey, - ephemeralPubKey, + ephemeralPubKey, // X25519 only (32 bytes) + ephemeralPubKeyFull, // Full key (may include KEM - 1216 bytes) message: handshakeContent.plaintextPayload, timestamp: Date.now(), blockNumber: log.blockNumber, @@ -250,6 +255,11 @@ export async function processHandshakeResponseEvent( const initiatorEphemeralSecret = getBytes(contact.handshakeEphemeralSecret); + // Get stored KEM secret for PQ-hybrid decapsulation + const initiatorKemSecret = contact.handshakeKemSecret + ? getBytes(contact.handshakeKemSecret) + : undefined; + const result = await verifyAndExtractHandshakeResponseKeys( responseEvent, initiatorEphemeralSecret, @@ -263,13 +273,15 @@ export async function processHandshakeResponseEvent( } // ========================================================================= - // Create session using VerbethClient (handles topic derivation internally) + // Create session using VerbethClient (handles topic derivation and KEM internally) // ========================================================================= const ratchetSession = verbethClient.createInitiatorSession({ contactAddress: contact.address, initiatorEphemeralSecret, responderEphemeralPubKey: result.keys.ephemeralPubKey, inResponseToTag: inResponseTo as `0x${string}`, + kemCiphertext: result.keys.kemCiphertext, + initiatorKemSecret, }); // Save session to DB (SDK will pick it up via SessionStore) @@ -284,6 +296,7 @@ export async function processHandshakeResponseEvent( topicInbound: ratchetSession.currentTopicInbound, conversationId: ratchetSession.conversationId, handshakeEphemeralSecret: undefined, // Clear after use + handshakeKemSecret: undefined, // Clear after use lastMessage: result.keys.note || "Connection established", lastTimestamp: Date.now(), }; diff --git a/apps/demo/src/types.ts b/apps/demo/src/types.ts index 294b9f9..5e1b86d 100644 --- a/apps/demo/src/types.ts +++ b/apps/demo/src/types.ts @@ -44,7 +44,8 @@ export interface Contact { conversationId?: string; previousConversationId?: string; - handshakeEphemeralSecret?: string; + handshakeEphemeralSecret?: string; + handshakeKemSecret?: string; // ML-KEM secret for PQ-hybrid (hex) sessionResetAt?: number; } @@ -72,12 +73,13 @@ export interface Message { export interface PendingHandshake { id: string; - ownerAddress: string; + ownerAddress: string; emitterAddress?: string; sender: string; identityPubKey: Uint8Array; signingPubKey: Uint8Array; - ephemeralPubKey: Uint8Array; + ephemeralPubKey: Uint8Array; // X25519 part only (32 bytes) - for backward compat + ephemeralPubKeyFull: Uint8Array; // Full key (may be 1216 bytes with KEM) message: string; timestamp: number; blockNumber: number; diff --git a/apps/demo/vite.config.ts b/apps/demo/vite.config.ts index 5eee74c..072ce19 100644 --- a/apps/demo/vite.config.ts +++ b/apps/demo/vite.config.ts @@ -3,7 +3,11 @@ import react from "@vitejs/plugin-react"; export default defineConfig({ plugins: [react()], - + + define: { + global: "globalThis", + }, + server: { port: 3000, }, diff --git a/apps/docs/.gitignore b/apps/docs/.gitignore new file mode 100644 index 0000000..b2d6de3 --- /dev/null +++ b/apps/docs/.gitignore @@ -0,0 +1,20 @@ +# Dependencies +/node_modules + +# Production +/build + +# Generated files +.docusaurus +.cache-loader + +# Misc +.DS_Store +.env.local +.env.development.local +.env.test.local +.env.production.local + +npm-debug.log* +yarn-debug.log* +yarn-error.log* diff --git a/apps/docs/README.md b/apps/docs/README.md new file mode 100644 index 0000000..b28211a --- /dev/null +++ b/apps/docs/README.md @@ -0,0 +1,41 @@ +# Website + +This website is built using [Docusaurus](https://docusaurus.io/), a modern static website generator. + +## Installation + +```bash +yarn +``` + +## Local Development + +```bash +yarn start +``` + +This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server. + +## Build + +```bash +yarn build +``` + +This command generates static content into the `build` directory and can be served using any static contents hosting service. + +## Deployment + +Using SSH: + +```bash +USE_SSH=true yarn deploy +``` + +Not using SSH: + +```bash +GIT_USER= yarn deploy +``` + +If you are using GitHub pages for hosting, this command is a convenient way to build the website and push to the `gh-pages` branch. diff --git a/apps/docs/blog/2019-05-28-first-blog-post.md b/apps/docs/blog/2019-05-28-first-blog-post.md new file mode 100644 index 0000000..d3032ef --- /dev/null +++ b/apps/docs/blog/2019-05-28-first-blog-post.md @@ -0,0 +1,12 @@ +--- +slug: first-blog-post +title: First Blog Post +authors: [slorber, yangshun] +tags: [hola, docusaurus] +--- + +Lorem ipsum dolor sit amet... + + + +...consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet diff --git a/apps/docs/blog/2019-05-29-long-blog-post.md b/apps/docs/blog/2019-05-29-long-blog-post.md new file mode 100644 index 0000000..eb4435d --- /dev/null +++ b/apps/docs/blog/2019-05-29-long-blog-post.md @@ -0,0 +1,44 @@ +--- +slug: long-blog-post +title: Long Blog Post +authors: yangshun +tags: [hello, docusaurus] +--- + +This is the summary of a very long blog post, + +Use a `` comment to limit blog post size in the list view. + + + +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet + +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet + +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet + +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet + +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet + +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet + +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet + +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet + +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet + +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet + +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet + +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet + +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet + +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet + +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet + +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet diff --git a/apps/docs/blog/2021-08-01-mdx-blog-post.mdx b/apps/docs/blog/2021-08-01-mdx-blog-post.mdx new file mode 100644 index 0000000..0c4b4a4 --- /dev/null +++ b/apps/docs/blog/2021-08-01-mdx-blog-post.mdx @@ -0,0 +1,24 @@ +--- +slug: mdx-blog-post +title: MDX Blog Post +authors: [slorber] +tags: [docusaurus] +--- + +Blog posts support [Docusaurus Markdown features](https://docusaurus.io/docs/markdown-features), such as [MDX](https://mdxjs.com/). + +:::tip + +Use the power of React to create interactive blog posts. + +::: + +{/* truncate */} + +For example, use JSX to create an interactive button: + +```js + +``` + + diff --git a/apps/docs/blog/2021-08-26-welcome/docusaurus-plushie-banner.jpeg b/apps/docs/blog/2021-08-26-welcome/docusaurus-plushie-banner.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..11bda0928456b12f8e53d0ba5709212a4058d449 GIT binary patch literal 96122 zcmb4pbySp3_%AIb($d}CN{6sCNbJIblrCK=AuXwZ)Y2^7EXyvibPLiUv2=*iETNcDDZ-!M(5gfan1QF);-jEfp=>|F`_>!=WO^Jtthn$K}Goqr%0f!u{8e!-9i@ zhmU(NIR8g*@o?}7?okromonkv{J(|wy~6vi^xrZLIX*599wk2Ieb#lAbZ*fz97a4{ zJY7PbSOUsOwNy1OwNzXx4iXOC|2z)keOwmKpd-&ia_{g7{tN#ng-gPNcc1#tlkjM! zO6lT6;ZU0JB&4eA(n2(-bp-FTi8b+f7%9WKh({QCB8bELa9lXp#GSXVPIvbL=ZA)_ zoqe{#7VMtQs`;Ng5O8q3j-8IgrN#}94v)TX4^NlszBRSzdq}A`TxwFd3|y~ciPQw? z%W89mZQrCUNI$g^7Oh9(UFDIP_r7lI7lWz&hZ1*kZ$baGz-#@nL4S(s3tjnk2vk5* zGnL>!jFf8k?c!+McUT=ympT%ld*3}>E?g-5z9LI_yzT>@2o6r3i2v)t?KwGOxzsp5 z--7^Xa4<>>P6hlaW!G1-kpn0Y2dq(kdhFvvV+2FM0)3np}3GKzTt;)#GZ=Z?W z!}GMkBmSB3taZb*d{@PnL&d_l(Ks(Z2Nbb?3HFfuIKl`Y+P!9$uuAsc53|NzT!gCE z{M_rr@ucO9AC$3tNI(^d8!3^&0lCM-kw_(|g&{O!)%`pqf8E|0W;wYyy}6&z6(2B; zRYt1FlHZ2C7vc@FdKzC@n?}jobe2D9^;P-sa5`IfwpE1e6#N|6qQw8o+38045pxM* z_59Aq@8~>dJCtqhns#jEI~z0hACBNUZ;I~qj_$}bPXswGCwZz`c=)~lO#R;=sD(%9 za&bUY81NY4aNY25K5M9{QQ`EOS{V4jzXdWnDdV2b8HKe6T<|X$Q%nTAemPnPhtCab z@I(`E5U22@kW&(;Pynv}zWp62&;CfRX7N~Ze4eAlaDu!0dW=(x2_An*}x3G&V2kUsI=T|3LqH$PFPB?r*Kh zT<(BanS8n8ZL2f{u<*C=c;#&Iv3z05|BtwHPyLVX$JfSZ-nPRGyw_WdBUAS?NhDHJ zmzyA*oPZ~V;9d%;G25NPBOfQ-_D`B?F5{09Gw9nt9ehQ4_7uLZZQvbQt_P+|;LlMZ8=jss zF^Gm7)AuJd!9`>njaJZ$iVyWbd6|Twl_cKuZ2N()vsz1j@E37vPyKyt=e2GqZ^MR~ zXIy^LItyv$VNEn)MYm=|*3p-TDZIgKxoy7MI3JQa*lF%)ARPfF;fs*DQ?da`y7oEU zh_lgIWD}kW>MyGS)zaY65j&?~?T{j(I0L8nXp-HVZ_c&_z>K4Vi_<5qV_D*Pmntfm zcZuH8?M-w;z;3X$(8R`DMJ?#^m#o9ZLE0Ismu8& zDF)Q?Teh3z;(@8v6Q-&8=w`afg3mLQ85XKF=>ht;Mk<9C({@^a!<@Wn&e@#S*tGZT zflx~uFh89d7#69BINhL^;7=1nNyD(`#`N(kcJFxJH1wC-G z;3~)5?Zx+e8gBGJEGIZpXCR@*4E3T{e~F3|np7zaFTW*H$6lk=q&W<9@%|HhT)JsG zi?G)xD*Su@aGq|R2%ww6-{29RSlN?n22{r1v7(>8AqB`_W!ed6MbYgY>Lr~WdJ&67xXmBw;p)KRhD8c| zJPCE$_%TC!QMW^NN%e0n5R2!O>QuB$oNP`QHKU(-$F6g084quR%O&2C0<#jZqHNw4 zg}XntN)!#<#jr(XMe}^|UlLdeBP*t#i${&;_yuBmDs$W2O;1E|sSj=;W^ zSyF|!M=xm-QCXVU7mQ}V(~7UrsKOIK5r4^7F*g0VH)w1<|34dC_`UQC*oTu=+B`9* z4Jh>4me{%44wl;7BDJkvDDWJ6SL?-=_fdbjK&XRp5Vk`9;#>i?%Motv>V(|7;A}}O zU8%V37GK!!mZHZ`7L5Ns*ztfB%;y+ar#4rSN%qi@zDw*8HNT7L@UTW-9V>6VIrIS2`w$ZVxrD_Pvo4;!t)?he`;kX47HQS z-ZH7w(v&VJyMNj9a9hr72G+d({AQb?zG8>o3fA&C9sA)(_LXsqbK3q#_q2In;XuQA z;NKnzM$3uO)*k{JyOnxO7id4ceg~27qWT|x^KLg)9iN9N9QmA0xoo+VRJA$ z_etyG#Z~#aXRpU(?tAXq{@pX43OnVh@LXP_K@+?k9bogc$6N&(^|_I7ezWOoTLFK- zq`ji~=M!@gj*9u2?}O^~rbKuIaGHS#4~<7S&j`ui!Fw}>9T~O9Fj^ zyN};L5Oen^`4*<%c5`ifzl|RH{yv(l$yZoAGe7Vxi@NG$b$bfy@^r|37dNU}^yhDP zg3>=6>ltZV(tkMK&y2yjHjZAHEU1)`Px7LL-ApPAQyMeeb~^%^Tw+x_#AO& zwY9CqLCRqDuj8Hhori(`zOq4#X2@itHGeu;Oe8noy z;iV-)*{@MgVV=ZE;SQoB`g@sly`(oumzOeyw^%x9Ge`JZfNAQ3n*xKER#RJN$@N3` zX|n~{{3NG=HSLm3|GFI)m9jjMj&1 zi`#yIC*L7GD%~$4EPts}*Rd@VTe(M6jJF8MDif>-iGqb9>Q9zYo92egEmZacG>pIx zT3XS%Wn7uU37^#?IO>Y1N%%BY>lt24Jq!#rl0 zE|_4f751``XY#Kqndv+Y0tJc@_=K|OoS7Hcx$j7now-)jIS@SJ7Z`qR{;qwEN!yw( zrtTrDt}LdyQl>pCJEisU{ExS-0(RC(8z?xeh0uYie&4|@NL1Kt!PTFRbK~9VJLd%? zyjj}ixr`csCmc9SDb<>2>GnCHm-i(a=t69-_MDt5ksjAVU7k>i!(BOET#;8#cwKh0 zjS=YVlpYl!E7+!y;RpeY=C=*|<%&Oh2+5qCv^JIR3Of1ue9k7N`?6YW;A+{c(pyeP z^ZpjVK^#7%E}QYRtS*uaK_K$Oyoq3%xOCV3?n&qBv}Qc;N8FQ2O#u{>slaV21l1Fc)AyIlbfdX7AExO{F?eOvERYJb;Ni zckPYRgfT@0Y4PwO%7BY@l#2<^fKapIft)oU2O*-JU&?8;Z7Q467Gqyc1RGqTp3zqn z_F<{stV*oYnEE+<1}A|K7({3kbdJ=r67p>3|7YtA6(Iw>`GxKnm1Ve>A@&z9Vvu8H`OuD7{B zMq(lkGSK&awU^aqf~Hx?^P4cUl^^fU&*kPEt$t4z0-PMDv!U}pIKO<9Sv;GRJ{qnc zM#0V^%Zxa5H(Iv{@2xzz5#$zpTWxaaiu@Y4QU89(yi{9^PHM{|J_i?6y zgf4QjZLTyomqcSjIJKGS3lb zSwmVhHvq>|mo6iNA+%kh;XIm9P0(Wjl%N@e!Uo|`7fqKQ0Yb{?nwhp%!%@R7IgQ(J zLdJbRkfT+8-daWy0_~Aj4@&Z<8;^K*_MKdo=%J+qo&7AP5Y>3CZDQwLk>VrP-iE3l z8mvBgeWl{(67&r>s zolqo}wttX5$056wr+?q;8$fEMMrSIe%AQCqi$0{Qt{6t|=rBnTL`u#0;b>^^q~bHE zp{uMeEEOF+C@Bea`ih=v`oWzl`fF0@xNrw_gl78Y95SqUn_wnsHu&(x4lD7hc2>u& z+c4)a*}b=lY{4v4Y@S1w5Z2f!Jq8LAqHhf&HyFe+xH zbfYn zuHOaD(3Z44uZnBo`1Un7x{2QW9QCOpsNS-qWe%Q$F)qV<&9q&PJhD?RJ@V!6b{5RuzyJ7cBd?%j{&sd zks}NY{pGQJFNu*E%g=q^iNCa_pTISw{g5lr<;sbC9@&D4|{$QCRNde}1aaR*iIJ>SkWWj9GmQq+0=}_`Y_Ek-oPg#tRE%68|XT zB;g{AmDK0gbP&>?-)o<(f8r}>S&x@WpxLhLJ6!VHvd^8m{d!dr7T3pz$ zkn$>3T~Nk?bRK9XEGr-E(p1z!l=>NOIE93eV1Q}%M}o=Jc(kJdFI%%?IHjKWBv=F- zs0kf#$k+|N^0Kmxpqs_13OW!7mM)n&4n{0j?O}zqJVqRfO0L;*JN}9tgHPRp+@oVB zL^!D_@iZhfor|uMCvR_WYBUa3qK1;a0Sidz=3nvFUmND_0QX-%no0}PDmmBm$!Q>E22?Y^dsKW0G}?bkHM8iy?HUZJe3D3p>1 z{o>d|o2RGDul?wm_UifFO%C!~|FkRJ8a~u-1G`aKtr9TmNLt2fx<)$)zT|Y_bZ~;j zZ}|?5bT+5#t2#Z&ZjZ&(>}e~tx(OssxQ3R?$4(c{8| zA{yv+v62$*(TsZHW7*HdBc_*TZp57AA09eH5#R)*7`b!#100}{HOmdQKm_miUqlBW zZD@x|#G<>fCMXis0q5cF%MdAB0y4U4`ufgyXagAF75QILp?OQMg)oJ-I5tcXNTV3c z^LdROg=LH8OWSuduIFYH>yoIy>?K#m=7i9g&A;qZckd=Qq`Af993c<1HC+HF3?3TA z@mXTS>d{;Y^&|CQE)x8(;Ecs0QHElH1xI&d6&Uq}k*an~<;wvD&Gm?=IaRXC4_2t+ z687TAZDvFH`P_rv+O+vii*ILLDq&e;Enb4GCZxSUyr*?BG*S{dy(~hS+d8%Ae9{Q0 zDFTsg9%WffrG!4@g#5<1DSfOuyKOqS6anp;I0|{^ z)V|zlQP!t&b3wI~7AJ(b|n}V$)IB5Fya)0*qVbt^^Xy>&KoM5@G zgv~8hvW8mIQ#^U!=(x z9?eBPZ$ao`DWyTW$iz!Q`hLz+KZ&*med242vVjHA{9$>d~E!>k~8H`e}5Ob?c^7D<+;Pp*!^~!b~jcszphKaneeErmWa|Ii2Oi~ ztGB4PTrExmF%PO~Rlw{5G?R45H%J2)zC4d?gLsc0?I}+&@ z{srJv;THoXHj*l`5Q|Tga(WP!7MOqS|4vLj8TW$CZa(*>1?6`$ z@pb*I!r>YumfjryY$QPZ&5ybh7ImdJ=}jf0R&Il)Rm8;{T#`EZ(8$4xK5)i|(J2>A zM(ECw(3nO!P|NY%80nn9)0)$_wQ6EY)@tA=fiw6Ckl?6%O@ z>iR~gE<@*gj8f=2)9R#xOOTiDw+cG>OO%J1<=dA?ehZH`uc}v z5rU~T1mqht0WB?l44gV3*5~ubC7^VJ?0P zaXK-^Pxha#1TpdkU7p`ESsU|D+8lTCPuba3r1}NxZiE&_I8Tx1G@)B3Ie#b@e%d`@ znIB6?VVd@|FiiIY5+r1dt`0*7CSknIt4x^I8lcbofDCyRBVB4u4goFQzHpkSVflWC zwCjG0O1Gn0h4%24jU*=Xv{Dg1GblXO54Wq$@-$o{ecO2#8L)Ph46``+>pER>c+GW$ zM(_lX8sW#qMTjI&_xnpy7&J=2N6?X_`pi{1qV%(bZ`?B|_=-Wqy}i#QMBhD-9s2~c zy7b9>k)dilS&g_J-(ltH!~Gud%K0oYXy7WObRVqWIQWFXU?{rDV z3ggo;zJQqxIwniw*YYRCIa)*_EWpICGC#=Rny3r;`R@LdNvYW-FgcO%z3NicRCZ1~ zr^>u8=iAvGHtZ*OTiMpv9AW!t^yU%s#0J_1Jj(G-;n1NVwt|-9p@r5g=&hhj z1nyyZ3~Dv2^qB>>zG(RzSlG|YU8v?0scfBa?5rKq+S(q|BL=E&8z;zIi-JpLE}t{X zC$jXzp9eAMETY=;3mQg({0eFdgYQ^9w`8`P{pXzAibKLGsLZIHeGwLV?3;0NhcJD* zW=jF6I?uh7cnonu|01<_;8Y**Gym3BCvZ@ivavgH{8Ys)L0)!KpF3kN<)NbxWqoIg zk}H!2P(+*L^U;+}sAL7~{4z9T$5;N&FXJ@lEb!F(Tz^mLXIY+Xoa8TCE}?oMt@2dF zf>B7vRnrXYt*^{_10oHxyR&QIX*_A69}X}I)WsaK?lU?w zy$^EMqSM;=o9rGpvC;Y5hd$=({MVCGg0~qSRl?QF2fWElYI_6-(v`Ds8JXMNUh~@d zWH?o5p$-i}&}iI?V3Q`#uX{eS$DhkUlnCO>r#B_^e^(O7Q{_t^=vWq6c#OCzKhoO0 z>32c(onMuwu)W}-EUGQg%KW%{PX{kY`i8q`F3DM`^r z!$)9ld2-fLN3WUry+VwXhmA^BUOO{*tc=o0;~`%Ca<(w=m6pWoO?LAFnnITD$;4f1 zdH)T)1!-l2iUHo|F5wV+q=!``)Qy~Ut5}0LPVcL+PVN=`-kE|*wA&=vLJE}>MFf9) zLt!6O^ZQ)(vglM}uzOPd0QN`M;WPw^X&aoW#x|kYoR#)bCHgEbGjry|844*9YTYBCxxj0&FM9T;FV9bu>;C5|_XUj%`lRr>o+m|j2w35a*LG`KiegseN*Vq||f zpKo+14SwyV7d7ICZYcB%nnqii`@U>;LT4X6c&u$(mMQCPn=5W1>fVq*>-%eSmqRPC z!MqV{0CK-po#-m}|GiC9*)!(f7%0~@X2uh8`BJ~{dz*Ync9O1wkf5C)WL3naIzopG zHvd`1UOoEtlLa?}QOao@HL{F{mI*K65TO$*SkruGJ9cH}2ju9?KuX(8@a1Zyo$)6p zZyW0qF;H_NM7dV)Yj^I?H(w9Wej^ra@(z+8`+Jgw!rYedJu7|k=mo4iUFPzl(M6VS zbbu2fb6_=)UQm-WUL;&3oCNw^s!y0Hb?(x+elVSM>w^f#=jtvUb~6Iia>Q`3alZ4| z!j996r)(u@83OLDw6YetLb4iWm7+S)t#!mEva~OF7%~>=+DuYL@me!-;)J-gNC*Ur zA|;5H1@Y8rW7RV?MKh$mP_*+bS%!1)S_h2SJYQ~+R#cC`zu~d? zOI^f%5GtC|SSF%ErwSjA*`s8rtbF=>d9`-kELhy1S3P;&3;1gB$_sWdlY5=>)|YCs zaAGeo=f|WwwRBBaT#s|qO#D)%Q;5EdbB`@>l^)%EEnYRfsTcDFB&!5TF%z-b@a2FtQSU0aD;eRfc&CPic*R+ zQbd1TSU857kART6jzOmnmq^G8r~e1=S?LE$yfUi^VJk6D{f@%0hFYyxTKCqM!_Lku zY?H0EO#0bF4(UWmhPVFYySswtbAxQ}j15fDU32FbfyU}l-O@JSrLX?sX!Q*h5_tkQ zCtcr27j3zI(b3|TZI*t(-ta7BCGeIEc_ZQV{Wlg-iBLFWy!|NdWvue9$0BQj_1$Bp zr`qiuEt0~v+OhZwhq8Mi1 zIw8~;Sm0}2 z`#Z_V*`Gtl7e<#qj`xO|P7M?WmGffQxcNF+x<%-$!L__0mD(0f9Rop;vZfa(V)yz1 zE-cIPoYeHN29k7N$0WLjCYs!YP+iwDozf(gSe6H*1g^^7?82$E% zS+c>;5q8OK9qMVDD}$)M@dR40nw293G2)zguH2&?cwoLJ@+eF4v=>g#%A}>R(~ovXE-mGs73s_&xby_%f}MF1omBoV~8zG)9FCUxZl+03&8 zMo*Rg6u22p>bxtf#)@PI_~o$3n#$C2TEy|2cqEvo=<>YQ3@_0OPn8mh1#_wmn~5Yn z(=m}EIZ6e^^W+<*D*Jjsy+Jv`4jwSyeGF%ijP4W1RK5u=$1-9FkUWy?o?OtxR0Px>TvF0%+;luL8uZWYWuM&>2#N1M!zIM~ zhjVaUQF{cRG%+=sIXEzp>C($LdH*Y4BMVuE%5!^vX=7DW4mYLY6uXrMul&O?U)Dw# zT)+#OII#l7ZY~8)(sLEwpPp#0)67O3m?;PGuT61U+pnzyzr?t(-rRHH-%+c;ob;ZTF5`H3a7k^Wg8X94FwFi1kV+$_Yy zXTvfH$(d}PRhZAsIbAPRB9M;(jZWnP1ImuH&&>3^RlXX)u(sWW=FPKFU!tUjb@pL} zM|#Mo$rf7F^D~+khXrUzlW0<>wk`hb=gjg)=96tX2ReSt$^b7Zi2q0`^>L2Mr9tR% z440)8CVH`A)GyCarH4?V9@etZ*faJIXV6V}Fcnz?m-2gUUh~mrxZIeajFUNrlTk{Z zd8sQm@el1OA7qu!%gLx;NRQwm8FDb6!>VPO-c&0AgXL|~UNoYcW=DhKeWW1RH!C%o zA;q+nA4?I~DVn>yGN`g6aYj&?iA7Z#onO?v!NtxbNE^W&*y$}dlE!C{o7m@c%*fS0 zz_~2;b#I7Ri799%3IhVZ4E5H3XZZel*OWLYUV9D0Tcg>O##T|P>{`(AY+jFhL5fu` zuynS{@E;DK%W}HBYW8cB&UoQgH6{>)SrjCR^|%5U4({A*VAW|PXETk@a8a6(dRzwt z#{=^6uZG6(CCb&TCN=!S5#mZI6Qm5iRyHud%LsK8(y}cz$?%hxRVbYcSk(jQ)Hf*q zwl`RXgq%Vq2>?qiQLj(sikZ5M2--71+VIB4>t#QF5kY>+0 zvdrvFUKb|@`qYA_DY~F8uSs*wtSyZjru;0Jd3f;q2xc^|l4;ainHm0GyTBPE^x351Nfhu+U_zM%JNv5tRNY(SJLI>_cH|`_% zBv}sM>s)u6&ftbT2iCAIbVYfaUdPKoAvKRr(h$g%l=euf!4+uP{uuJ2-j;C-gh79tNgvD!v);u3L54L8bMpdHOxBezyB$J z6t|CIWiq(2k-xMuIlq+@%c*oUf)auDn&NzqLb-t?B`)P6`sEjdLaw{t=0WE!psHKgYc`L8 zG7f5fbN<5Tc|Sc;VfuD8K7LsFY}c)XgtW)}UzLZ%PN2{=X%SF}l%n5@+mX^Tghf)C zQT&=hLLvxe&MK4|eJ=aMDkZi-%i5#;LRBB}9{5$@0{+NM_YoNPz_<(gyMe8_SQH4* zYs|(<2TOk`SN+|6){TN8HLBf=AL?Q5Wca0h;$bU05=f4Q$Ce1foxm6^F#KFxsX?$Dq%n7L@)AR}- z&sp2&#EosZM2gM29vW25{lhV-Z1N)rJ*7vJCt41#dOcxI`~uT!F-f|GtYZ5$j>V<= zK@HEb<0GW9P6e=bcVm#Ty6$x8j)|034zm=W^ZG!o-(MwhvzB207jL{j#Wr zf3d4_jvjQH2}PJ^fXo642QaQa6SIkfo=`<$&eyhn3IQPVc8GcDB52|H1>8Iut^!rs zC*ZD{x=G}jXK(yQf)&(+qxcckLnigZ_sae;{8ma1@=cIYvEfv1*!;%B!dd$t&bjiX zjLpiO1-g7WV!!s2{{sGJM4)42K)c}T-{uU*qv<>aOU}lXLmg2AOHj#J zki~HRbZ)>CvNm`r6BJX`hu2KeqCd0XlcA$ofF_0`t48MYK62h`5peGP1hV>0lG|m| zgWJRC+n9plKb-fsjCaB)bz?)}0q9?6jnI+-?$-r+K$|Br+H^=3@NtAFT4l z2Pi-M&*wPOB{W@wZ-O;n;LC&fOFKV-3^r~IIPJgH(Qpu5xoI2h@Hq2uu%{?y_46MT z`3othZz2iH{As=P+;}S0rE#`E2WqQPfr4&cPe(9Ktb~6jBPFsV>h*v;I40yZ>^Xz|QmC-`*#T zuCmXO#@x)`YmiZR8qy(gIa|mxze9-8a>4X|+Ry(%r`IIcXF4{gloG(w0Zv|e)-5$B zFR9*Ql(r&d+E;8rd(IRG-B*ayI(PfB-?UL~Sow+1Y4{mk=}6!wG{<3bm8%d8uUrRX zmFS*Vz0j+ynQUc{u++Nh%~FHPUOSb49r9StxA6XyKILE2qHS&1_qO5K(7%#T@HtKcx?+ZQBOAI6 zjSor!Q1@$2J=(O_HaIy^gFP2A$xAdmljhq5dELa!}A8tv_9E>5Ol!F@<`mu)dHKWLPv8lunR z;OOt%(~^s#z~1uT!@rASj6#`Nmj}}IFv3aFcO!H^@q(MZJTTgRp^!Gf+__|qf~;VN zi>pFV$ZLa%?x)U?-2o`@C8FW}Sz-J?zzrs5rzwS@>I5oZ6ywRw%hp6$!RgmP|KjOf z!Sh%rRz+hvQp&hGy~Ukxr0p=@*{0=yDy-nJ>BKdX*G$(+(b3QMum+kWNg2&~*QLko z*W@&s%qtW~J;Y)|y`9@2H=L8(Ewaykmwe8eGoQM|69>+i-|K}6x>gKS#w+7x7QlqV zWPRPKP-iA@jC;mm8gxvChZQj)VB*g`$U?84Q`ZhG`5L zQy;))-`BdwToBd$!x@&Xywj>yJyqDa&Man!bBR~&6<*P2C(knRy+@s&_;u$^UKHfL zNBExjJ*17XN{9=moVp>;T)*+>pweV zkqpPE)($ap_+Oan)#DL9H~w}L?k(hvtBW4IV&9$Cr4Od_f)RzC^~L1!`|># z%$v-L4zH~s{FG?hm6~J@(`5 z@`I*$QL}m!U@6E;u3tZdA;Zy|LK$qFd~)|2nDUAgHx~`vsT?0SUx3qCZrY@j7kjfD*hyUc~L86s!14rk9 zgm*6%*gqkK0`bL+Zg+j~XHVFSQIBw7*$Z#)kkG2!y5a9)CjoMF^wVLI<^@ zIG0@Qu4%nMp-ild>IADcH2JQf~6e)%OI_(LGI%=;Kq6B!MtwqJ^yI{BcJTot62W z%=0 zbQhF7T1G#I`ri6IHd>meOq$Q8)X(GW#bd(F)mbI8kpinT ztcWRAGA676;jNDmc4Og6y_9kq(M=rWX@cp?m6rf0*rdu-)K<>Pl>UVBuCkK;` zE%u(=@;kY8LZ<%Va5u)$DW+4IR+nq}t^s|@&qsqC0%3oF0?sUF&WnEMCqfs>yj(5T znL-zyT3Tji@~Wl=s}l>LUS5xfJ{EDzVgjIvR62OTN4g;;v})iI#h>;DcD@91_qzDW z4k~tTj{CRg!qXZztF^-rE9H6ZkV_hxOJEk=Evxad%L7+x-rYG^W}-O~#KxuhzLF(Q zs@zanss)5G^SfRH11hS^wy?u*oxD&rZ7PiIDg?raN(ethc!mQqycn%QvGm*LuxCLD zSnd~+!|TdT&_PGUrD7M!_R2e-i#>k5rw$dZnE-)||r z{~(#lp0ApHDfmZ|v2cj{#F@HP=l}0w(_) zGeJ5XB1na1WHT-Z-S)q+lLKXa>`ib2Ks?g;6g6K7UV(DTZiQ6)YLAW~{sVO{hYd#3 zxUvg3(}g)twI|k_tgjwEIH^zN3E8*vHGATJvELu65&wMd`D?_S%K!-5w1suU8oUi` ze#ByP=JKgEAxBE((U*1&>YvH3Bymg9d5uVGeH@#^EbZs)3=vj* zwK7Csa~K^WrQcd8S1V4_4*G|KzI{^6qEcA(=|(7*p9RcL zvH#{5WVmcVY}8!{9QfO2t#ViWuM{KKGl8%<_ak8SSHNo3moDDO%2O5h$Y#+KsI|&? ze>BfDv$!X*$H?PlKE0qos)z)U-*J(|1BTX=yj(npJQR-8lIjmR~dItB?C2n@$pB!cNsR5 zK5{z!)dO;|_`@(l%_Dfkl9vsQpgZZ=+>PHA7I#=nI{A%u8aDU@(3|CE;ITiS_g}K+ z+j4HWL_5PSZR!s@B$tiWPD0Y0Z_}Fd-{&w@#=qKXeV*iq;n?4!o31ITo~peGdD6RP zL)JRZF7#(0r7Tb-Kr(K*VL&y?pk6%z%B2P3q%w?8Pi}!)7^{%(h3#lLetDvy86fV= zrzs3s^%Cwm**F+$JcQCJO8#;Rt$F>2{lVg71E1WJ5ODHmq}=-@={M!K)74q;j?S0e z{7ybdS+(1Cdd|64Th+$dym>)4mx78OKXo2~2b3+wzb|Fv(u^B4^*uj>xB}!R{kTk= z5X_rHExdjM(p>%_CNwOCEIDYjlpG%f)zddv6IYKmnwEl0@*iz!Y}9hgO_DFw*LREf zYcNJ!8GQ3yZMOKS^m=7-|Bv^A*d-P=>?-pQ$7r9g2zkL`vD&gc9(x<(oi=9c9fijw ztSC)C`wxeP^F~-QweLweujxbKcM@FW3#O~3o4dOo$jJxR>uHqeN;u!Xd-W=WMhY^4 zwzy-o=FUFO&d*6xIy=%{^8Z7(cCx}^13R{V#lww>EBP?0N)vi`_;Dcc+B3|g#X1c> z?~C|Le+_+~7RfF5=J8@31G7m zM=`oCXAzQ74^b>8J$whv-7@|-LM!YgpgMGINiCOaz`eVy+37UX05SMx+!HKgZ}EzE zXNHLfss0ZK$^>_^T_bD{@@p~lt~&2|Q+)m2Plw5B#Mq zZ%U1q1Enk~em{-#KOgChb5IgWUoza8W1|)l!K8=E_lMkx{V67XAqnBMY1pPw2~;c* z0sT#HyrV1RcXU45((e1-3Q7Au$iHSspbL&YRT&I!OI+b@jM>!dSg55jX{HyC%DIoW`z`S5PqL@5|`)uqbMf)IUiAjl;~6xqZl`ucoX92I1oFr{e5CZMaKqh zaBpKe73<%LGi-4hUkb>Ih1u==f!_p&GBIB?kIcGjBxUWhDz11}vH$R3IPQ!;Np_4V zc`ldT7@(aOVv{iUUPv>fSx-+WC|&F%{x8+j`!ebzQeg_aV(Q9*QWmnl#*CcP){tLU zR~k085wAh-AomA&?#&hkEAJCb7~%`-wDA4qci?Q~M(B+93x1=WkMj2SqdrsrWyz#} zI26mgu$dFH%geihk2g(DeoMDI4Y~kYfkO7@ozI?3bX%n19Sw~{u>@Oh+q{8R-47(q zPLm-teKi5*Hb&bS@|QZ}uC=~P+;IN6Gcs6uTs%6+Z%*d~kT(Tn)X;pA% z@}8fJt{Dg0EWPo+x@z|y_@zpXK0Y3g9X^UcDB8c`LLWjS5&h1~q00VQad&-}rYd=r zR|t2ZY8eGQI2`-Fd2P~DH1|kG4~#nixZCj|wWVA>OiyIeciM;`m~@F*R!=o31(^br*KA?tX^-F7{h&T8AWNnC z)f%$21ZI#-3XqVEC>E@qENo=z-09+Mk^O6uc5IdhslPlUAxa?+l>VvL|u z8XD#0Diu)I?e&Lmz^RRfM@}4F!fpj$Ra&D=fkE#uex+uWcBtLytOCZzVeCp4EIG&7 z1;)85WaVQ6;vBQ?O``-V{cpl;3l!E?bv8E1pf z*4-Cr;l6Of{#z-GK3{%o%^0`MZ@uHF}IQSMGprgcE&ew-Cphi;0hR`(ZS zXjyl6HW@|_ESk`<()^;l5zWoOmjChlmeTlaWRAGD=+4|^vEsmq&)?eRyTO;3nAaQVVFDfhL%CP|I)%{xfOuOruQNZ}KD?m$g{&_zMl)R6hSBpM$^)r{ zGSEAdwFY|ZtniZbSfz5I0#f(|s1rqAK!&cbO5;H%=|`e!>=D^;e5-DVZE6{8JDot5 zPP^(jzI+x|l4x$vDlpzojUBG3M8tRSD!AD?_?VtUK6@#Y|5@jUA=J!g<4Ka%)D3W4 zaxQe)eR;!hjBF(Ohl1o#rhOO%xfxh6Mpr@)NI*7@9ju()M@uy-dfJ{1!r-ie8XkRq zc3lN8jY`9c1^%QfgUb5(CJkLjFJGrmh;TNp)7GIzI0W>YRqMqn~7A3Kc3Xb6IsnPY)5Q z+NbAt(vD3^bM&3eHH$+PR@*C?l0)$&x8;|jcMH9z!9w1}p@J<{Vy#?+Yo*mKZ68Zi zOQ*bV5>6jt3`;2S68F-H0({j*N-#zP*pjnPn%$yBe-#-H5t(IuVzx~pt=_g#8m`h& zHn`MeHJo>=R$RHX=3vC}?PK(EiZJZe%liLmw7ew z9}2#c6s5xQ4=FCqY2`OF9Kk+fVaFT#SqnQ3{y)z``V!0W5K=r+9@f^Z&d3OR+R@BC z!>-!0eCND--r(&w23n6U#NDhVU_N-8L>EGvKayuTGkY!&q zNl|s@s~RtY=O}bfjBOTgE_KD80$3M)gi`Y6;DQ}4CU3gC7A>GBVk`P}KYrziiiA5l zoYydmN>Sge+r}7{Av1)H@Z)Pk95g})syE^(YU5tBWfhh z1QzZdYqg&?(|FH!XUd5POA-C77~7#x-2N$@J=T1 zxAtN;sT!ToKa`X*9?@p#UaT+ErD{tHk02)KgtND3R?u@E){-k`~{iv`-7Cb(UPvIz*x+y`H8^t|47Z4le2s+UkiDJYZ(N8!{YizpWTUjBdkS^RX z#0UJokY?3#(K)^rYgLA*6;bLp9n0oVrBfrSkkE!CcX4rXQ7&geQbxYKx(y|DO6^#F zeP-tSm8%bDDGVSh_UdE7J)o)g;ygr%tV~(CQ^|QAqE!)`$Ire055+cFm94?vrn$Gw zVw7OkDxeKLzMP37gkeu*uF$f+KSWNCew;;Fpi%Ee2-Zwiv0{fzOb8>ph#I49hDB17 zQU^_q0xWcY!4xmMc>NiFIL~vEZds67CBT72Y!0)SQ-{6bTIUuwB3SmrrNrMU= zZj%Or_i%oRoB4!V`3Jz!RqHs zEHAY2{A*C-hK+mqwCDT=T&V&gOUrd8`Hjl|*z#p4p3dM+gQH+pHoJQAs-jNHhRWMs zqNpT#bPlD^Day3yabbN^(7|1;(6Huam5Qstv@7KqlWby7UD}0w{$RVo3*2KIyiR)D zlc}-k*u-7{DBT0vF==T=``f`Kp{{YhPqThlC@>mHVZ0V$OgZ@#LrBXnGHxI{oTDyP zG`*4_{-a{R0+sLUnQ{kWEL-X?G&S?5$!GeFP{X{%El@ zN0y7Qh;!aS2Iqoa+F_UUeHxlL5w%W^yJ_G9Wq18sde^>(tP0oL85 zy5&d$<6$S|elkNp9&xGCSc2yUI3DnJ55V0|mcD&w8VXge6xo>AysBYrQ}y-y-QD}6 zq>h+>g8?R7nN$HbCC49kKanFY@ng+8Or02L?-=dYeL{+G{Fp`MH4W8CPB`lt>lf-( zpa%i&rbDjpm$y7pmyzja`=EF)UMGLW3N_V6Bq|g}8BfWI>OsYcU@>G9SolRNLa z17o9N-_<(uFKeW0MQ=(sW^qa167e-5*((q@jQWR?x7oyB>ER6>W0a6Sr~&Vk^RW%L zLf4|Cg(B&Wh{Xz@Bmu(8QNLV9(us+k?J)y5V#+aFH#T`W5OXNlG$NqGV`&Upg< z3HLO}e1}G0-4fWW|LhitCa(naUZrkxiPY5At-`?lRuX=Lx}gaB zLsmh|$EMgm$mn1Hh4Ma}2XCUl&B=Bl+Sc}Ta)~t+DoK##lYeoBG zjY>Ao4es9^4Vo%O37SozE6)u5uN9dyc58^UQCOD#^YOt>1$d0|GZOgwk3iykY3ihV zT}H^K>55;Wfb+FZePC4({9b^hMm=QUC|()QL*eZgau-W&MvCGpGaJ#t^myz)Rm7D+ zauZ>OI}GvUetbi3V>#E*W9~RUI4<{M?Dw_Dl#4qlIge~An7dAmCYj_?><4f4-0}G_ zwWY<7%pVLzk+mhDn}g#ic`fglH8=x3wN?c%i)<^P-z~oART{apnwNjty}HT{ZhH*g zYvtMh9XgSdQ;_ALz=2tfE0B;#3V>t__fEYGWCJ;)HA3k88h1>GUI$QQ2E~?N*!?~+5@A<5|!P`no!y(nP zEbQ7gl5`3>Ge9vTHnV!|^HC~9FV5Ry(X!to8(Y`;pG94H%X{6;zot{BzbgmhvdlX~ zI<&01@H(q`n~yrAtHg}%FiKBbsF3a?Y7RpA`Odlfb6xt=Gkt!_>ei6&9`~#k zX^hp@6K4!nI7vzrzprD2u-}tN6eamOC_{>uKF$vtRL>)^A5eUYhj4-7i-9baE+1fE z0LV&Mz)8&dx5^z+LJGT(>HT)~r-gj}eMqiL?bjsptZqhQN@}}mOT~M9grvZX;u@in zB-3zBZLIQvPWmx@fh0eS)R+`MicJOTeS>|>Zew4~g+oWjq^PNk%SL(7sC-=ihi;9& zIp@U3N&rN+&pJF!zhp_db*-00BPoIB#amiy+hl^>M;Q-@D+j+vQlycX^Z$(=iStnM z`I;BK%$P%*PJy5@kSj`E|aXm;pN7{3qg_jw0(b8EmBxvA~odK89odU>E? z<$q7s%0RGg`Y~uuvD#Tu6h2!W(n@kx$KVA0tHQcACy5KGK?lF@*s<0%t>5QUeN z{~O`|d7C}5CUfQPa~r1}A*@&E|ME#+C=Gw@@M?bsIKP>_aplB9CG+`T_M zfQFexK`k6JcqQ%0AVrj#D!l9iKBoqoa#=tZ$UaUz#IDxK07O?74zqa!6J353i`5;Ns zkO{}Z`qYu?e8fWPX|KuM-HzPRk=ndt*!Q<;b5Qs=B&R*V?}mn+jH^JdopCOxU~xyFVA z9^{5Lh4Sf>;5*T+0=|>Nkb&0Zzw(V4S8|-TT~rS?_G(E<0=v=ix6I58OgA2;I6tc{ zRCQSQZzz8R#!?|KpdwM8O?(a;y?ph^s6}C@aMF5Ug=VcG#kC6|lhzF%WWiW8Z!rb` zu{iZf66-I0z8Udamig4BQq;oY2S0ZGiF=a+>o=AB1uJegziiIzh&B?` z{h3qveWx{8Q3daH$@pJ`cu;>#=2Gf3t>J zwsT>#q~cLEZ4Adh8!-KDIPi$)OxyutdGl>lGQ^*`F)LPh{Cw|^Z|lWB6iXn}n@We@ zOA59NYzi@_a7vaMf*2DH#sYNs&0+K3E;}8QJl6iCsqrHZLhk}l^(arcJwH4|%<{qQ zEb+MYD(rXeshQ^Rl_VxlB&^(jv8m_uG1nxAt3|tGwm>|s{5eS2Ojz3U%yDtgIuP4& zWXJO&q%wZjU4P<3&T-l#X9x^G@LnOrptddyMrm-+?QNZ%rvi%5zEC{=wVx76O`b`7 zM=tsi`@_IuJ^xTuH&NOjWBaPbLdojE&%f-NGH*jBkb_v5_?uVa2l~Yna+=zkd-V4o z%AKYGl|pSIQ4!_U;Psl;d@@xYa^jkf+fD(;e^p?0y5(J$rP9`Hf2&dsg(&-Zs>>Sl zi|0%_ccxSHOO0DmFy|s{;?II-$=7wK^&WgdA{~}1VP;s_y>3jrTj}g)8^qJe!5K@k zR6j9EyLE{o)`AJv>NpOZOB)5DhK|Pj_2}q^4u%#S2gLngzutG7fYrDHLpsdRs44 zZ3m8$EKX(?q_qV}rgd5~0z2ndVfMkP#rOHt6qcq?pe@^QR9^71Ah+XwNQ?liVn;uP z*koOot=<3=+=<+CL-se3EH#D_bLWap{4YyTGk~A|<*yGnU*`9`deuFjO$Sfgje)=`^V|HS6u@z>eQ*WsnF~3x zy+VIFFEM-EX+x^pz%k)4i2orm9Vds8L;~o#&pdv8bnTY;=1W?T`|^V)lU6$f00`jy ztK6rq!#^lL#~^zHd9*eJq-LkK+&2BRmOfU4->hF*QD&z$S5#foEX z!L6;N?it3Qln1}!$wFvVYX;Fh5VW5_#dm)YaU!d|k^d{q;WR2L1pwrzyKK#2XAIZu zXRJw5vwzr>-q%cTYDo9xNY8?Ci4X4wFTfy?l2oCo?IlMU<>NFf*Bsey0KgU0R#BVv zt$4I~xAUNi%&U;BFl+A_#VW#CWw*M48bDd{ui(WN-*{97Hw>3pys={{K_ME&NaZEq z!S}GVpjmkrBeDQti;L%BsTg{|sa$1cCUY*yl=&j{*6v=!xV;@FnRCqK!?bfxXpLyj841U};$t1xVqn=gPpETH4SEv;qm6nDt;5hN= zK=;=I5^mLh6iGrALZrtJkUFU}C+qf{Ge8hmT3a~QU54*%x-{DAFk`?g?y>z3gMJeK+Su$@X*Vv5Vo4B$Ka$lY+0TR@;Yj-aG;x zqIzLm!CMglHkljED?|!{#iLYwY~}vzs;lXhSq2&kstw=|Dxw<13HyjRgxcBn`IJYd z9l5w&_iiR;H{W2-@)Y9E5@wfLSHW4%W-BYJApTDBs~=4bcCBghvo$L&5{}Rd_d<|@ z=(B33K<$~_Y8&!$i>gpl(~ss$UrCl|!&dkd<7ac#!2z_GF^YHzZ3&!~IU{AjsD#yo zjbHL)ZRH|>(;+FF^)ga9y7zEATvBMlehwIp1g4=Lg7*UcV4EBdKAaoA-J#tk2D=zD z%o=%Gk6pFq@s*hg$`I9$EHQ));IeWp37i|=)(mo0yV|v-^+1Oq{{SPk!=?c3=~DObIBN^b_8H}Waj9&;f3{}) zn98RvNZIj_@kfE~7_CAA`y=J`yO(z&f~cg$9iCz;9^GvD zJbUMW(BWo^z|gtixNm2I&+~?-8)sb4B?q^xBSRpp66Co+W~S@_lox2Im@ocIO#hdc zB2BiDnJE!5$tzwy8Afz|Sr{o0L(2m4zqAzfzqIsuv|9&_*x@E*H%!M&*%t z_ihG`=RoFd&h0!Mk}`8VFi7snEcN;05K^(YM|O8^$o)p?0G(hMyh=)UVWE=Eo-MPf zV>(w<_pATi;8>I}{_bp`NjZ|sa`X}IQG#Ln>u$ssFz?u56e1EPJckbAjw*i9FuNxZ zyy+*vlJ&mprb-qrfaKIKTh*y=QLFr+f=s$HIbd&Lk~^seuV!9kn*^^GlpgcEpzfpo z@Fsq(>KBbBLu(npRyW1@nZ!*^PR~yWrF+d5G_>eS z)T1Ie#uYs}gG0+`d?r=RUHb)RNK00wU*BjP4|~P^B4z^^pAvTwZ5Prwhd>T&nnSd4 z7ojq#;T?tXExMj`5my{ku<#%+NJ@2E0j+JRoBQ*QXbl6YEFfAbB7%q3UgWJ}d-+}E zPq*-}`-}-uBYHFIMSqERaB}YKycS7W3+M@uvm!D~_eg7a85wBT(# zHBf$S3cISPKi}?@70(i}fFuw7uIxUx;uu|)WEG_Yec;xT5=P-RbeQ1!ZSjE=yzClF z2KHLxi|fypEHf{oCpv_w1MJi7kI>hO0m6gW9*fCDk?tLTFk?$_3K;1FxpssHM@bk6C)*^B5v^>{;ll zUpVFO=t_a?o3}HG=;xe*S(}358(rS*i3J7~@nhNKh_Sk(0^Ny^%E$OP*>nkAuNny; z>4sn!9#`#)z{X2SB9f=No{gp~hp!!QMCY+cGNH5*FA((`yM^K#qf%yEXc_d?S5o_E z3hY#J8pawOoesHzIq;>$820+_T2o<#cT%oM><@;06Z0PCpi^F@h5jn0w%cD1<42!o zhgiY+T)=`LUCergd-Y)>7spWZHlXP`aott0c>oeGBcmrex2DU`I=C{GIXTt$eUp0! ze0&c-&rik^KeqB%!z2 zydJ{VhI6VC=OMPzGC*leTsj+L*D$$?PPX;dzD-Q`bY zCz9Y=36=*-!qaHX=$til9$e)1RX>J)@`^J((VrsaK010&qh0cAaATRD|JD6sM9Ap+ z0v#IzS^8uAzg>LD=*oyj^ooxd$jdJys|7g12YRMol{Zmn+7y%Y<0Cm6ltcYm9< z5qSPw7wxOPrDj^}5}ZS08%4!ouH);a!bIOc;#6YLR-hnS@7NV(8X`6giQCC{OYua_ zU~csVM|$cj8$~Nyd4`RPwEFkP2YyC8iKf2x=cc3w+H?t?HtJ?}J^9Vw zajDo>jX&MPj>9yOM{Kf4UE4l3>6YD#Ji-y7Vd#az?0UNQ7NjL5*vzMaQFlwe{2xkJ zxi4_)kyaz!C~c;-SY`1@OoLav7J=Zt5!6MX9q3Qgj&Epf<J#!@j{ zr^gzU)Fo5VD)(Np z%sZQqPLy9y=LJqggM9tALED^$>U^5vMd&)|AaHxhW>R~C%^B`T_dW9^DMwSJ%)UXK z-BmHoe=`C3!d6I?7swFp|cZmq3TDEZ~z#)U*hF3_xl zo-*DgX>##9sgw6r=O}^Ya*3&ocwF>i&|C}x^jD#z8(2(Gm;?F}-T>onfVdQDCD(yM zJc`u?``X8$-@)`&tjZ0AC;Q6tOzEtVTDipth=!Ss@%&s-K8BdQi~} z$*Nf2V|p~16L0(k*h+X}R&A0R;{ghF0%_lU{VPNx)^t$2*i-LMUC4PWf$xe4MKK=7 z$BnI{lvLsQQMp5I{>#prOI%i)6lpm-Y{fBaki-9D0X)m0F&CRFKkJ@dI)h2^?v<@D znP(|`mY&D*fv=PJ)e7P;B8%>|c|C}tJZH;#u$)hNE>}SHi@NWyjLF^tN5s^3NnX7^ zTa`t}Q{K7L?|wG@hL0DnXxP55_r0{a=bqU;jDj{Q1;`A)b*AJ<&gXr~W+!#`#ypNr z*F$)dsWOk&=3!^r>MO=^KZ&R&%pxjW%coNj+apkV#TU4Ix?pK+%-=>D(+v5ujq6Vz zvp+LB9LyRX*7mbmBPAhP*aYhlRUhbS!p}zp={X6>oN?|A`yGWvrbpUw)Hqg=?UO~|FfB1A z&NhSl&bzw$bVtvzC0o4r=i7m7PB_W>=}jS47uuwaXMLI*x5qmG`~pqa&4>lr3wJj~ zyIwJZcwXS*>_hnfn2UG#z4ENvhXwDPV~HCkv`49Fhmz+6^@VCSk4>MpBjZ?Wh`4m~ z1G&>v1L0G4FiF^FgFeDvMw@_tC>RF)YhlsGcpew+E{ae3zyG1YLkz+!%*-Bn{&4DE z3Y)FBy1WV119(h;q863N`sb(i7FAq%oEe+Yv+sttUs2ES-CLSIwiqS(3!wag?Q)vV z1?j05^nKo>=~u6b8`uAo|BJ@)j}h$?kvY2JYuJuU%gXYVY%y@^^J=A`k?3C*!=rm) zs{ArL+hsJG&mGBPHq#9!t3AO@6h;n&Zz~jCKkTiSMQz7K-^DQ7i~NeHa%(?FbljO; zKYV9!Aa!&RESVfS;xhG%Y!y~)785qLvXO6i%qfaS zqWip9C?u#MSvOx}EsScvh+>heH|+Cy>HQxX8mYMg^4LX8#2`#D{!){ZE;rYDgZx6s z9rvx{{8eh>m5iM>g)4HuQR1UB;hpE3Yfy^Zp-zhoabuLwDh7jrjotk1sP&jBcC$ zHXiPT(iPS_{$=lJ{D1@bXLeQ7Zl)QqRxWPVDr`SX>xf>|96 z%biHutnmDk?EJK>%<4}GblY`O?>8!9yjwN~C0)}PVXmVSb!sA4*!X$?8J)YCYuEXzGQR z?61(MkNp;5F3i-jk+X8en%X7Hg6g*&my0{=A+Gn!y0s4Fd5R5+r?|72>%I#Pe$7~8 z@#m$>Vlc0=3OLjo;(9+!si{Yhy3DmUSsBAcBaE4Nlh2IGKJ0Q}_bqrgo3%+?k>l#; z*R#_f)+zp`TPlqG3M)gmrw+bX`D9r2;%m1-Se~RWqo0-dpO-#YaI5%JZR78)k=HWo zCvuX?)r;2_g)hJUvDadENnCwsBz;=6$MxIcivR97 zqkW$2?H?R+_5x+Nyizdu^v4ZDf<*E{W>imh!>C%%Lq{;s#~rCSMRzGahYs%a6e_Nv z8M8zL64AE{-%*v*>teBEaPhV#Z71%#`AA-cAK$y9x!L^;NlkhIA4LlyloIE}@AzwK zyKMo}jjkn1TCm7c`V}H(eZ%e!a={%yYeN5cX@OLU1sgH#Bzt5Vo7$a8OG&r z2W=h^HAyHx{y`kth|EXd^)c0>6Hu8hTkvhr7f6lx+^=D2yy1LA!)i!yDS981cskt6 zwmR?XR<)DDn?n8YmSPNTiS|0*n{98ppL@+n`qSs{DevvGo%Xm4QO>s!eqZq4R-9+X zbXQ^FZa`JO|M^C{(A}<`V(;xhE6Y|f?`)#*yDsR2=0u0k)1CL>?AZH)yJL4&yq@~t zRrDtLr}~U)*F~br>MunLCnPLdKfls_&b}>;4`)lRY>P!x{6Krh?mRV?0>0}TXh<(B${6&2%$5mSf@9kBynHoD^M~e&UD>OQiJ*#3GfmIFEzesmu zdSmjJ2OF3zG88K%!LsT%5--66kAj1b0omnXGCHYoBYjmNUG6y>F06albWKM^3YzAM zLOA_T!#?f#M=n1Kc3zj3Zt#(I?1yi%Edu%fP)^8Q@4C24b|N3hVdYGvLodl?_FrtX z+KF!c^62Y9^ayo+glGKLu?4>^ zvyf3glsq-BRP&^~BK-3NF#g+88Dh)){I`1&VM{SAxWU*jyz=Es&R-@TEy>*n)+Q=}>w4j6hk6Tb3dlPf8OM)5yd7paA_**}u%{1BF0#La$^j*VR-lM-H< zAQ3}ju6h!e8b3Y?dWBqZoX=SPsB;rpws-OG2=$I7ame=*EHD_y0545{3eICGzW(}K ziM#52b_(2d>LOBuN3-nB8nhiAB?zW%*7kr*Vnxlors=s&wmm!%#a>l^E_C%gDk2IG zcrG4BT5JHA;#hRllgsQeopgu&og9+(`-NS(xg<9uTjZJoy7)f-Dop??;+%7*MRv!p zMy@-vkg{)X>4;(_MjjYZ|1I5#eD2tD$q^k0xgd$^Q~;yuu64Xg8T#;-=UbYjml3%A zuC#PN(W%^V6UEywyEy&*yTsTSk6UcbST8%^cG)J~!0%ZN_!TXeWbO?;+tA$1cLMcQ z)da~-_Ol9Q2N68Ys=ax09%h(`lP#|ih3#q-D_?k?nzxZ(ycmA+`Xu@MTO0H6w(lv}WphpkSk2R%y@a+}w%=Dj=ra|FO z9KI?qO4^(~4$j1-H{mqQ^6LL3S1!gju(NqQ#7#-NWtwkPMn+@kHQZd5U5{ckwG%w_ z{Q;b3JbT&@_I{_~A4)faQwk33oe57t!I}R*6io;3j&BK0ij2{F-`yc8f~PXSn(@Cm zO6R=zswtn_f$^E0dNEH=LZiS_dXLhlie}B)Bd89y-2iLo1>Hx?t_u$_Qg4dnq|zU! zl39PgIU%{9rpAj_0bO2%bf}o0CbNP=5NR0BKNK5P5iUESF9!~K=Qk?`;uX!+V&Ja# zvNvD1$ZR)Q4Hy2ty8TPbJX`#|5W~I0x%9l=YW@yy?}f(*x=BFZwqu!fvmu*lLIV@{ zv+jO5{z~nkH@F8TV<|{n?^vUf5Zuor%GALH`oqQd_r{iU6Br^>o(j3A5zQYn9zXr?utt7`pgFS}tHP z;>eod$#{kfkk?y?A|f_(1)1AAx@yw0c|ZOlGm=>Vx5~CkR@ac8I!@uT!@0pHAkL^= zr9S%Art?Zq*bvCWkD1ZBVYcMgqE*q{TWYU&W6(68ZBJfQKvV+`a95 z$kg?1+}?_bcy%*t>AmP`GEVu+wU}Q?MnL3h!&V;CuV4Vv-`*L;^205&)prsqngQ2C z!ZWI_cH6PFe1dAl#V-C<+2Fl-%6TI(n?7AHQ>X2@k5R*(w-JO*~_p*_8r)rEdvt)(%1opc+d;mAL6X zuE-s5WJH{OFm}$_Hcs?#Z5r$#-`2HXE76m@kkjx}GI~qHYyjEFM&Zn9U*>WYk_&V& z>JLOh)@y;+zW-3hvH$cg1g0e8x|PoXRcavO{6^;WJ=aQWI> zl@Qxl*oxEN*lX!CLxH-dSLsR)NY>RQ%=Zi2yRzt~doHvkB!dm_!b*^pT_+n^Cq6dw zePq9<`0Is)$=AtPp_w0G>|w~arFoTzMn`-BWOiG9D6cB0=2 zb|L%sOU})ZA^RVS>}#RxpAVTs&+Q8&Kb>{+u0Si|#1hgc(+h|LdWDy-7#FD_`Lq@h z#LAH8ol9vAw8sLk>u6rqy57BnFO2ITqLLT#@U~z3?QBOl8p&y$_T4<^GBa<_9+T_e zMKPDFbl|;OKY()SC^^NnH!6pTS=}sb{Y%+DluM5% zq+2E7s&WkJJr>1nvSH0QNg8L>Eh&ZOY|qkiPTUCbwH#u9e0lYR?Kt^^@L!6w*Hwmi z4r_VKx1$#^yShXaixB>dQyUVunc7?)h+>Q~Q-(5AW&0t}{HyMk`PdRIVsi;b8h`TDOn2|f0oOrC$ zFEBlF#WT=0ppub>;GlO;_BKC0zVu!z^`9i8 zD}UyS+ZB^dF?k=Zdn@s9Y3G1QF9T@zD^8YJ3ah`qH>46UrOJc8ToLJu@=xrrlX70ch-_HhY%Lo>p(GxYhWuWSgV@DB(- zxz-lO9|CKujx?}_G3T{dN!1QADJ|1Y=_W#FrST;QxOvWg?YCAA2C(qvgf9lp&SZ7^jU^RI9&##^FcmXpC}1m${*k6P)UTgRc>tUmRR?1bMvNXV=e$bWNV+9C zWOf=EQu@s%O8d!LXfBS&8c1WzOqoKRp6){dML+CIfmEJ45$WW}!kkH1Z&4F87%d>a z{8n)JnjbMn-_TNXbBF(&Rpq2-{f%|JwgIsfTCe9+Jq>pTg?3mzP;0Ug2FY1{X(4$X z_SH>mInwo`TsMy#>8RkkBaH8C=74YEF^5ajjS&-*U2!;y<=1jljylOihO)#cQwH;1 zOzt`#o6ERW+9ovaI5}>fGKMHh)LOo@Y!OtK;a>qCM;HD*kPZ;k$;$(8mry1{iAX35 zB0qIeQ{zzKV_y$t+E;(`u2hXGjs`Nq+Q@!iVeo%d%TV5qdU_Ef(r;~92r;4}2ryzX z6lQg#Y}?Lo=TyVbCt>~CPg3rJlL`NN)`~3)W?3gHOc|=o{RU!TotZ{(hU<`s5oN{y zaK?!%iCZ4)T!TLrX98UZFor^gvdC)EfsMV(k85C~m+GuFVI%)g5arsV8Gj>Tf2NhT z8RjL%}d(D883%z*1Q^w|z9+c2rYR8X*&mYd5HOgdWqHod9!4+O- z9c--@h;1K}DiJ4xZbZy4&WC@HGqY`qWke#ls@u#>G#JT3nYHYS9knaWXo)q8b2S|S zy>?YdN0rq{H%SS%Q|3&WNK~goPRDdW1z5rRfe!;IoqlkFFQ_$azb}Zf%@^BAa1MCx z6~eRa&pJGH(u}3E{x&7<9_|GQj#I`QXvB$Emf9}t6n&DaV=Adja_rzwDq{+TCaOjM zz%Je355aO$Yn*c{r(A!F@Wy6#I~mw1z2~!XT5w7~e7&otoRY3G)J{hH<$xejTa_{5 zBBtO{0Mjur+-xEghZ?t#yC}&z7ZnCHw*>kZGmtDdvqA!?Cp^?MV#MSu1Nk*6?5&jc zca~#gh>6{ySDG22$Xf&+V}m=r?ui{-R$hab_kk=<6*%mfW%!MvIP;joEJ_)>{G#(r zIi`c(NI=3CWHJL%3hOvaFOzL!!lMSQR4~6`9V8GJI2b9T1AtX>jLUHYWCLh~Xlv?P zm9ne0Y;oC4-A)ho%GOZ@Qt2d5kp>aR1P4v`lv|jT`mfB8&M(|FM@499#iBT_CU7SB z5NhT0UFuK1i+Ae02EYYuV+5^6J$-0wEB^9TwJ$EG1s}bvuM&=#OtdPGrHMTMu(+21 zt+JiEG>~s1&)XcSW;c)(kCcS~4VrP9ccThDWGdj0nD|-V*VeIC-T`zV`QA6_Y5ksz z;c$^}yULUUbg#1PHH1w-zazp*@ty6I!s4UE8^6W8`t+P)jFX&vFI5^0gEQ%JUd5#t z2g~D|h0_mbF=p(jk$yecROsSub}LgMDkx0QdS8Rd0=|-4#f@tqitZza>@)TuO`J+T z$dfTz6+Wg=>&8HWi*_-Kie(M0ev`z%hFNF$bWt&5YwN>afT1{5P*=NWywAySJ1L$JcBw^{`n+U-#An5|U zd8?3OQxeh1WO2d&m{h(g-`!D`(aI~7JVtIEA!@Ib%XE>9cU+c?i(!gY2EG~mI-mn; zPa!1^-yE}7d{0VaX&1vR0Zee$l7Qi$S1D=qvv6ala^QOjQA^~6nR7RWPDWhdZ@xLu zkwEirWBO#%7B51OE*;r2axH;l!i@?4?q9$f1ynfA@V9!NW>}^iuYUja(g6^~0N;ha zdQ5}w_Zz<7TbRSsVdh62yAJ2LK(@$J4~%@-HQ^AZdZBOmQT8RPoGzupRMgMq2nDDy zr+S*e$cX!T+4f9JVW!Z~(2-k&(T)hZ`*&p!Is4Ogc4_O)%;l0uGxBH!i!GP0O96l)v0d$r%oTK=iW>cW(`SkYIV{J z84N;GoK;qK<-?mtKd6A=qg~=GD`xM$YubvQHnZBu1u?}!1P2lhpYUJWLwy@lR0gZL zI1zd3`I$gb2$i`8PII_6`gg2U5ZgZ3S(`yndRm-1*f<>7%nD+_ihzuK;=(p!{yZzK zMGA81mm-hZms32I|Ap-cxYBUR@RoWN!9W@-_z*#0#tP@pyP~sx4OrT{f{AG51)Ta8 zDE84U%wX+K$q;a9Gvv#0>VQ zb($|PezRL|f3OaFdl?wssRqNlV_9cZ+A*XOKx-cuTT@F{PiESPE03CRE{~s8@@2<^ zD|^s>vtEjD`S}a2u7*!c;wjEGQ`ly54QUWXmM)f_VR5BtNx}i~7V(|Li^@&HHxtgr90J5Xt^1nt zsYDhvJ8`+Ngdn0T(|5(}1ed9$!z#&;0YaKHjd8&QjX#lA9$J_u&D$Zg{qQ6F^=tVk zD-#?QOPTanCrml$Oi=9i5v^14Ygn!r_lz=LyoaBR%)R-*0LFMZzORcW_D~OQR(MPj zlE+OXM76@dC?P|VB0IS^Ta-zGlrB5{5cRe=d+Suk1Wfmw=@xiz-t1?5+t7aYpJA9+ z;@dgu*ev3Phm_f}%mQQcB&IcNGH{Z&zydg193PJ*0+`aTo~Ink&B~N9$}*~)S;;Er zziZvkV3|h}jh;xZjx)Q@{hWlCoJV=pQN{UpWD9fXj_1cFUTIS-i6R8fQa$oP*8qNz zxoeFU#PJdf)98`Jy{~e>?(Ge5bSmB<3|2vHqk2EI|toYyXGB z`keTfH2DSivi&>`{yXsw^ep#CeAyFL7L{#pC0+B}|4bT|d3(fS69!TXLLdCtP7?OM z+G(3BTZ%LQE-hzh2_xuRqPnAYRgH;PdLYbvz(8kq5mK?Hh!S&!F0VjEW_NtWw$&vv z6PdqeE!pD1#b`2w)ud;$D6y5I1n+6i)tI-)`P@CkC`&L~XLs4+Njz*x#%f6ghDks; zBj0E}yEF46!o04PLBVVs2JilWWMIH?s%9NLRIjD`IFAJMv$#~Wow+uf0=0O@Ad)o| z=GN2*rdn@ctf?x$U|Yi5gD4jq9BB*9ALO!fM=YK$uSVI8GMc8a<$0AquB~10Kmdnv zJ5j~Bz~x=}RL)wugdL?kkA5z-cp%Y0RMx93=6DIBf#}5rAiaE@gs}AzE$%WRh*yF| zM$Xb!&f0^;GR~6n{l-g{E%cuW)V!1zU>lq_H0b8KwaH^WKtDN%z&zP3`WaCnU|Wfs z`&F1!<+y+VI$vQYydg(mTd-_G)%t|;BYHye1`jZ=Kv_cNs5_Edp}%irJko^N+EGej z&(P{45-}*obdTv!K=tL&y?gtKbyHPhr0gP=d@#dSen1yqsnLV;6yL#OU%I?O-^mg) zN)z5muIvSd|4wrDL|5v9ey|->r(r$VAowcrX02^GozdEA5XLD18CB9yuO<2xwj&!6 zo3?`cwVFhJ>^`w9Em~H0R?c>wbo^7sqBC><%UBBz^bDbiZ37~}wMu$#R+_faeHjtm zz>#KV&PoUo=Mv`oLW)ce?!?_A<^cL3A`=QsxX%B>(YePn`M-a>5F5r04s*8I<}{}{ z=4=}_XHroVHgXP0M29hB7&hl)hKf=-C6(lSPIIV;GEu2ilB80fpYQLV`>*@HACLDR z_x--E*ZXxnU#*((&QNyl0Iuosd?x+2YDlL=fu^ckws`d5+SCC!jQCAasaxSsF^qCw z4zEyqHD(@Ji+7cL$pNWl0g>nL*T5& zOuDk>Upu7k^-SZ)t61Xoxy`{+Kg$A6I7k$@3nJb}ox-@)^usa;IJ7pJPx^%!SnR-# z_yrRDSwH%fu~%Ah1J#24Ozxm~6dCsfd%Z%P@5mDoaypSqhqSiT=&a}d%>K?d`aeXf zY6+2Ut`Y&H6gd&L*vD!p6WT*Q#+vuq^@27?m>61H4s{APdoM-?5yY?mlo6tPV2Vb$ z-#_}wAPT8@6}ZDj-8rBZP)V<;9~#M@4N#{bRL<;0i&EYAwK@eDkv{4s3>6u{ZRr-~ zr^R7&PS&jk3Ti2zj6FawwO%=5`#VRy6-`)B+Z1;3V53n^#zI$DJ1$5c)G<6s++aB8 z_IV7Z?eCO71U=OfFe&UZl(JFd*&4&z_{KemfiuCcKmb?EyqIKIw`wjWv!Je$w{J~9J99(VL0!cqt{~Lo1S#^2gAVgg z|JVRzuH?5=ZF#g%MXbv}QJ+1BHczFa&E-QIZVT~q53mvT>tO(`H=VxV0ix^)rNPXc3b8Ub;afd z`18;Zbw8)$@~TTpLaT%pbHv&UwwGc*A+DOy8m;OHCVFSm=N33F`O!q%7f=JNtFmCN zO$-GduA4#r02IaCw95Q;I5J`}?xC`1BmA;uV?i%;WtG514-F3eD+Hc*$Um{xF>m5^ zq~N})tL*9#+=+~H_GuH*3zT*FSOKR1Gzul7`V5R&9hEXj1pCG!jrb1u-`G>53=R0u z&Sd_MpIobk(@4;pL<>K;7QL$|bpJ@vQz)yqh3Z(MKG1o1DAXx3dfofAeJX&fcu1aW zD5!rB>IX6A4%F4$H9#g}O6*Z!We7u)BG@l$IKgr7q>nrw+&Ae>?K5q;WtH1aLN|fG z_nsBBxx6}eD?uv>LmZ=wJ{98T^T``@EZi^h8ZMFJiM+cdUUSc|Z{oLvK?e7t9l5^U zU!l*x^^)3YM;fbf>^wLg&Mu~*A##A!ukv!H+wXGUuDR@_p` z3!M!aa;J=t6OG)5t`9ykE;qKVP*qf|8nIiSVtt{j91cG+ny}-8S#!p@+P2zn`w)7A z2>yVf2Qm&+cY7DZ8%TW_hckrCTpiLF4r5qg+m4Po+7~1mb4*$;W}Fo_WxY(?4_yjw%I@FYP~n4dfG??^|TLYyP{8NX97=Hn;>dOsRA9z2!dsVJ?r8d_UasGA%~s}_DdW#dF;a?~Se zQu6#=5rRss@RKB*R!ORP1i+aS=9X?>CYlA_(hGKH%g_V$(m{99f=9pRY&7Pa_Oq0< zNIaeh?`PCr?`uc}<&8;<`R1oNt33#8^(bT-K)jWHDV#$69n{U8h{rTltMMbHHW5Y} zcQjgJE~j4I*a-0DhcKa>{ipyBUk)G_wt+E61<9Kn5AQ5c3wqOOx}=7!6~94&rXNE8b13#U6)az z$u-~M(_d0|+kCXyvC|`i{gH<^g%rq*mk94q;w_bl!yK@dN6n>Gtq_lc=Y!A#*^Vv2 zIl&Y|-k0atBSFU=<-FcFJ*rpuL?T>Hd)<=_r5>rzdK>f0-2U?LV_s>Fm8pG@L%p@f zL&RWN$v|u08RaJqzOQod$~RF<>yeXY8cYSfnT!>6b_(k!M1#bolGtn+9R&?E%o5}% z#IVmiq#j6i%}z(g(qbXNAia<41=RjfZ`Dqz4fPZ?cEH%&TD0fN{tX|jmt{_sm`t9c zLxzzSabv1I!{lOc=DYOWO!O*KULnr?B*#_!G?5zP8cOTg9P-fQSjh2yD>Xs4wLE{~ z`=Sax4BfEn5ubuo{md&O=shLocm*)<<&kJ$O-b9j)!aS&N1-M5GsAH|$){pSg^aYe zxWJ0cEvg&T$yYQ<)!QReD95)+-lZBxt zIIGH;K1`a{FAuV{JL+*Swv0V-$Xr?`31l=-z*eVg!)RV(k!0YacnVp3pdWcS*AmzQ zY>`B*ouqjh4(M8Lgtq`obLku2GGW)|cFa>Rla=%jQ9)wt4Hh#qaT!=hy_6(M0G=55 zRNd*61$CE)GfS1}jVd8Tswvf)&Z)JM6n|I=VA@mauQ{;i?$Vl0sdW}r+y+#@8Z+-r zZ=MpZ%yO~|E>mk$`|UB63%N@sYk7QwtzOog*6YCe1kil(hDF*7`lUP$l9~Mjk2#;$5 z{erdi-29?`3;36z{V7H6rBC~5^xT?)Yn-t}9vi6)NCZ*;{<63r zk*Nck(#)*yv}e26;a$RvjQvapI3^hoZHJsY;_YDb= z{@cf;zg1481cl^?rn_WG@*Y?Mj~QZyW_qQO!o~5<+(`Vk(I=+HHZGEwJ4|aE1tagH zHI^N2I0LVzeJ%A2*;4&#cXebj^CbSa@-O<8G75>>KqA;p8}yHAw9Y-ARqVGv$<6H6 z0VLB6?Msyd+_F=%MM|3F2Ub;>5ENH;LP-4Qm$J z0{d&f^N-xg1iuzyl}-U+G3KGP?85jmF>=RoeO!i9flhHA&~y(haGt-RxvZeg9X~Tn z%m2k5cok9P&Hi$$Vx&XTakEj8*Xz0elZ z&R1{*vv)pJk$RH7U+TO<=m^j24A-)-U*=gZ+X1#tCOexGP}_F3V9MhmEHTm*hc1V9hoz&eRC4s^ z>N6E3=U%a7VvwHpB1ngc)##zs_#G2h_7M|Ayl(m-$^e-naE1ul!8)}XxrmR9%=E++ zwTS~*Vzl;R&l0Orf6fMaj`x?1f9}dprKTtiY#vP|;}%C?VQrD-Wrnq|pcG1f7hub> z+;9kHcJh6QTCc!X(RX|nr}by`je6+U482}I3`25-0A!9G7gW=;_%?qvS}QYj8`iUT0^5MOll@y^iX(yy zAs)<;7jaWP@_YH1CKqCoOr*X`HU*_a{xbJ&eNG*=6qdnM6y#sCNb z3IxI)2fk&B9WX?2R0j}kW^&iafBw0c8GcqMVU>(=vgodWFhhCmHALLddFY?akYXG; zG$iYqBNcJ8SEu0+PP_HEeKm`$I8dIkQ}rdT0x^1zmwA~q znxJWNK)%xpX;(i2NmXNR*7wUTHiVXCX;LOb;J0?O@k$WJY7(?#b!-&f-%gzrx`%>X zB-YnT)s2MSU?0xBCv~4+Xh}}h}KW4Vio*14ljj_ggT6X=hH1gPFnoPF~HCtV}l>OO^TZG6LFX8LuT$nLeDZx z{;lSYW*8HUZoA_U^5|@LEk;x5Z6j99El!q6=w5zrkMV8G20E2jMFLe7c!B2{oGZm-k-^NKFR`1Hsx<_9D;~hRA&^3{VC-dV7}y!1-oK3uA)!-8>HJQk$SdAn2awW55ppcuH z;R~_!PmGHbOkWObgL6|zF9>!1nx_3ooALptf8-`wdr|^nt&~CB@NQW|dCI~~5KJs% zU>W1oJ;!73(^fDY>Lg}whVR_aJiTdEm|ZmXa!(m++rg}3v>B)ib{5-a8dxx96ww9R z1(~%E`{_Q3y(=&gL(`ITFe59jo}&d!=ERI@=6@S~wGo}?R)WsX<*nfsUbe~?t$w^K z7}?`>>VZr>s!B=JB`D%crWclUIT`vB1k3U|i@v)?3XN+VW{*haH?eNTh5oV3+a zPWRRU%(bBdtxefYV%+x0`vD0smnw;9eP_7OaIA~*ycRWD5ytB#J{1w#?5jOcYnjiX zUDeGI>7}fFO^aEJ9_nn`;Ly;|fJmdKHcm$^AG|Fd%e0E&;|$f}5JPiwUnzduCuZzx zUKw`H+tAbu_}Ku& z64on&PP%m^Fj+(GYtJhPzD#vmCd&7*8tLJ6%XW(uu~q7V7kHE;oT40P82){{Wv04jhEqF6O|W=PjvBan$Gr->phV@BQ7D zAusP|u6w4Kq#y3<74X+4lUX6dmmi>friZRvqDantAZxGV>v}MbOd$KWmiD>y@NT?>SuxdX|8wH2x^m^4Qs;E=WaV$kI+DB%)9nc7#-vB^29KEeFQ>w^ohg!=N6i3)} zz>k!3w9cuB5k}tSo;LQovD$c+&mxObnBBbiTy$7dp=6 zB;gNYwKy|Qs~c{o7N6flq4WxfD!BfE9dzui+8R@FpMnf*`P^q;o7+e-fHoA!0&RQT zR#s16?$jE{^gg||q_7MklI0`#_oN8$BhPLS{Ugz1afkn1@6h>| zOEZJcVb`ZO@N(m6y`sg|;*EINqG)^rBdq;uWCbfGzYC61pEv9WSNkC&@$ZqpTAFux z&GWRAf?*y<5T<%Sxu<-0bQ?ZqH&2u2G>AtT-lIWX+~gYQP8vj+N#8?zL@*il>TY(9 z9QS=*b3c9-j2U3f?1>dp<~ZdpC+%h!t2Xx>0NeRo@_YIP^8}JWiIAe;OY;3j;lKSxXkIN5c1-;;6gb?{ZGxBrt>nJV zy8ZQE%GJ4k)YV*mdPVtZu@{?K%K>LP${o7B=n>~C23V~j z*ZJWCQj>#^%G|WXk@o&jtkr=`E?>8>rxiIM(TGe+ITG;2Mp)pQ#`%fPDa($TIb3K) zP`M_5WVO^;?QdCL%`Ij>tIFByc!2L#ogj}}d(Kc`1L0+NCk^yVj<}*mE1_zpLQ;r0282sjj4Q6ZNRm#iyVPZ={o!fxIE7 zYdJB6(h>TEcf)zVU1Q0mt;WBlg$iPaJO2S!@K@!=l2NOdEKB9mA!@^E-toB7U8U>% zD^zBM{5#-$!COOup)gWZ0#&rBF*MMK46fBBKgp4LNP(%C|MD&KI1T*mVe?I*#&mTr zz^)bL&2%0u&u@XCq-?R@gU(|kUlz<21@LJHm3t$`m7Br{+|F^qv9!}6C+Hu2+wH4_ zYBINiOzeB5;`hucQBcd!`?av<>#KwaLTvDCaRD~lpvNpUEZ<5rm>KD%d@T)Qf0s{k zr&>rqOcFfU1)nP{RXr<(>UB_m0ghfvU%OxzU{%c;Z+h-H%^QnT|JJE!ZIHfme{2*in3c3D{f$I z?whD5D{u+1YI>nnV(-8U1NkH9^Tt9BB$?2<)m~$QYs~1|m)QnovX&@Yre13cKru`Q z+))X__Vx#(`%VAbCl9-sTs-K|lzAPs(#{NqB8PL7tmSu==W+5e=p85`1R$3vCS$5$ z2hWKuM@-Cp{?RvNHUWoe93k*#DyER=`=gdxbwTkdw$sr7&sO3!BeZA^wI)As(h687 zn53`S%)^WV-#EJAZxBG=DFP=y?I0$XJKlS-c3?kl)Zjv>xd1vICTH>h=f7CVN zti4-s_9U=~*n4@(W3i>7W%1>P2b01seZ~aa=08^@J|sgVPV((jkMxmrvPy*UK;NM_ zWGTU`*|Lk-uZ2-8O`QloL@0OWdqcy|BUyG!3NjZU7XhfAX?}{(OG@&X{3crby0azH zz6^&x)#|@an=zu|*J8fon!C7(f^v9cwU&T*TSD`cGZhH-meCe1 z0mU$?STgdSYG`bk!QcpwHLsFuKpdZMnb{_54j7DYSRP@PSY<&=Us}oLr#&_3kEONz z;%|$VrY5MaL61(AKzz;L5PwA`ea#9ly@EPGo$3{5Lo`*?rNkZvmso58vhfcv~>@h&0N1OHt7A>fP%yY^|{pyU|!4W&@J^oBEYoZ=d}ru{6znBOXo z{Y0o#T}0|2jmQQ$HMuYPF`CF$kCr|hQt--wo1ynr@EfR-#fW8%OKYR%%}c-1T~A1` zAReKO0J_2j;rpViS%ft zZyiN#MBt_BKEf7oB{Ql;e%o>!$5hcb7f0)O=UNhBhuC>mk~bkw;cBDbdu)=}wrr;$)<9o~gCe zwRfyup=!Q`fZ0Ar;5P6L^!zR6FiP3vG)0tDYS156dh7v-d zooj9*L%S?tZ)2it+9ox;vZo=4zBZWYMlT+m2QP8exw&<{COPB0d`(4gkQmjQqfSI% zex!}Pq6AU?2#nsc?0pu6O8R0DGT`1O`ADsgpG`#Ef=N*uV(Q@hTKRp0NYWa^1x6@%2PIeIsQtkOmuL7CRI)Ky#0mEA5nI#= z#xNzFci>3B`?hAEf1y}DO@h$#ToKXYp}hl-^C3!Kz?#;D05mb}=JLG}{ootd}AJ&qfWu(d0)-=(MIWjm^lD6TqD~Xi4#|`$MB|{UX3ICldkN;<%%|y5_b!@}4S4 z7Gy$9T)(N0s!{s=aDmKOR->G_QwHZC&N-;xAz9jhnc5GIxOwvDT<38_&Dzsy_`A;i zez(6Pb_`=)iLJA?vr3SOqJZt0yj7iXJLISv|0a&@6S#Q7YxGjj^LNXW_T9BQI!2hgfW84SgoB z$F(*y@W0j*=s$bcnwwW@3Iw689KYoGP$YuTM+oi^y{}6>{#2;LPiNP*S*0 zHT4QN@}3ajk14)2B+8Aa+a=WGvP(2LD9?=()GoB~u3$|29Y;fChfFk5ZG?AR*vAMf z2#@Fl!g&(|eu}&tSsP7Vvz$zw7$t#Xg(d91smUeW!;QAwTV(SdsInDe!W_8xUeq|? zO2X^*;{Wy`#g_y%%`fcn7wIP9<9R%u9j`V@WON$-xq!b(ID=XWIih~79v4_#EE4Nd z*iK&@qIcS^tJW&9J@n#CHf&N9tWgC7VQGQqSS7mTaWKP1us!c?GVa|YpijENY{M>ELgzoir)r)8&@im zyUX!P+^K{6adkjZTOjJypkj_?R9OB^L{r8Xr2%ntnV+8`U`r2mi__hC1|W~o z)Ok%~BW|h=GeoWya=oOd%MFzMrV!0OK=mF@Ri)v|29!Xq6*Pel`D?F*nn>H`p0mfm z7_$~gAFtURE^F?~5AN0UnQniQ70~JHg3UN`P4HNm!bypaP>R{wsLh6Z7~y`hGRfIw z11$=GXL@_%wd+;~;$7|V$3rH7Z|F7UsOX{5$6Sv2=Mj7H|MsnO68hMs;sy$YK#QQv zY2wH|Xdi4!r9T~A-5f1b{L?z|S|yeG zid*J22A{pDn(RPph-Tc>`I?FSgFm#P!7D;S;t3<~(c#Xe@VV?wLinDrEv<&wxYh4N zh|5Y3`NFI{lCh`RxmmW#tMaBZgc?QlQDt-23p@rqW?Bq7m0ki7LT)X%_frBBgZI@> z9S<%03jmajJioK8>f%b+vt7{OHjnqAbptK4A|Z+^y3q5oz$evy$Qt%td*M+L;K=JEC}K-NZX=+SO6rkP4Ch1f;xUMa(6w&DFUo5$x0*Y+gu zyS)WpQ(Wxl1xB+JL zQI+s>XHf__>n`qKrBCHij$UtFu;5{2{7}J~pAKlQnN<4C(H@Q6xJ#OPK!Lm?r?lzQ zU5CDP=R^zGb?o-0KYv{jIzxA z3kV zkBi{v=Z{nDO8SZ5`cHIn*wd0pI~@HtchRD!waC4I@(Y!b z=hFo4A05BMAJHu>t5DVt_6e>tBI<4+!!Z04PC88#0=WBH5#gxU2tUKexKE;1YX)*3p{Q(!^Q$?k)aQ|>ZCW1g9ayrMgr-7xOgnE*`2cpqH#1ujhnsfr zyWGDPh;A#9)X$K~SoM)9rmL^(=@Qf3V_ePH1|AS;ci>+gj^X}Af(HKSb5l>vag2vK z`^mz{Fe*uOGbn@4u7;0P8dbZ#)+!uoi^4s((| z8F5V*^8gjIB2DSIA9vyMoKJchgB`y2e>cYkTMM7r2TjPLo8xn1%5CUi%VW zWnhlxu;p~Ha(}ltA}JuXT6DJ5)y)K|0EiFBQr3bbH%4v*;i4b ziOC=_6ZKfsVYPRrKoFn;4X7R&hTB^Xsw=L%1!SBNc(|!=JXq@U0fT>9pr&$_Gn1?# zmS%qa@Am}gu1vfhhDdN0xV8)A#_7=G47ct3ltupJn#f9y8ZU`vjWiW(2c5&j5L3ir zu*EKYmA4N(uHh(r?}us~xdHVcqp$N>quBz#E8u70ZFGn9$>;7D8hC|eYF*jt;*)bN zet2jusu%}djXcVao;sK-VH)r5ryd@2kRw`7GifYWyd%MEtog7D6E5UEG#!UO14=k~ z_9cribg?#O4ca$;kndegV;Dt_A<*c;)u!irqZOczWl~JQAS=CKeMtDgbK;@Z!`WU( zVrF`A4fQSjHh|PR3j~YvSBiTRmY@~4o8Q!I0y*VG6WjlGJxA3YBh*_};Fe#Ki(`4N z({0%%!x+8vK4U8L6|0j@2@#ABK=?t(8wg*j`x@TKtmjLI`4k%{W-#?f7~I<4)r#vZ z;1^o3R?3cE=Db;ZDlo;H;^eJnb2~}dM-G-6pla9ro&x3;@1Q|rjAfSdbCA%`&~Heu zAk(l#oAN<4VG63F;AuI3P<;(*g0OL)n?jxp!_rBwqzzj=K9pJ^O+vUD$NX%#X4@vW z%03PTJ%UD7O>?ZKLQq!tB98oK9TwZkD>HpNz+uK{j14eDX}}X1=^yP)>M;xk^2Nop zlf9`2VNJ0xp=Wujg*(-KWJAi;`(^w`RmG&}JXX2JUOpvUEvOO_uoN>v4-G6PsRyk)fiv$?f=gfZLycGc z>n7X={wR|=<)tL=hlF9A$<{~rBztyUHmo+_mDpQ%!T93f7DG}6@87%3`;t`C(d7z^;+F?d+=c@mD4-J6(>NI*NhWwXV?CDG)t~E4HP5T8x&7?3 z3zNdF1$P<(*z;;SW#!{oB@xX+27_PHvk>Ih22(zyJj9TfDG^L9GqTNR@aU*ME!3S;v}!NF70Pw?Uh*dq zw}AKfiXl!Q%Zv$E{6gItSsE6-5;&~SsK>Olu1mWC$msN%tU}^~c5PacOLF@l_W}5M z)VfQ3sYl)!an>4ce-3fA-*s2wX{CWn{#7K>C~%P3n-tnQm@^UXAh2rs6ZEnmP}Oxw zoYr?vfbijM&N$ge;ZpunqvWZH2^zVX5n<|523u-9V#K8GDbdH$T#(A{839$tIP8X z8kmku>;`O@Zp;2fC+Mr&ak;rug+@lIStuun+NzWtv)8t&BsYVuDLWO!EqPxHCj|j3 zk>M_`j|ylSi8iAGlfuT+_>d!KgC?a=Y>j~q9};!}O6t25+n$;u>gwY3tmPDi>cQ+a z4Te{6kMc`gxBVVi0?Z^;0Mnw7@-7AB6cpbFcLJBGHqHbChzLM6IZ?&Vj56}QU-~Y( z<_}2Y#%UWG?|Uq_rM58qJGH4T}R3u26> z>L4oX1%_Okc;$veqz`s#;cw|?ZNI>o>we;yWc!sRQY zrS?!z1ofW~om7jUJ&-*cr0?Z{1qnXEQCWa|Qn`GLvC+X?MG1OGK(JbfFG|(_Rvk15 zFimbfjRa@0xGlwn_lg*rMkz8=drbn~Y2rrXi6v_H$ZrjUhWxR=VulJX>#pMLHZF%V zH(TSn9c@+~lVh1#&s}Hu+RYW9#Rp0!?Nim{EKsLHAnI#HMwwxbF3ulB^_86^n%GIk zlk2{B-Gw4@Vv=^8xD)p5`he`~aH1I8$Py$KL+2(cY@8y6Z)0}$wiQ^}yYBh{gB|rk zt>xR)kf*;`Dm#!BIMZ|01N?B!F2)$I+YlV?sh^-4Jq(i5qZV9xj&AW0C8M0;3TbKf z^e9uooov-~h_(FnyN>2OD#s)9uy0gGka~JV&6C4d)P>kcQsSX z>1@{Zb@_gIm6~VWqke_Iq$Vp4n`pjonYWZ>&At>r7{+o+l<-`eJSntGcsn;jscAHi z@G!=E$%lLpCkuCpmdQB00&S{UzzY3BYXf(dEfn(fa?=eQ@&sIWMF&m`IXD|_wHups zuA7qNrQZmBONq!-7>g}TRHc}jS*PWfvkE&gBZqUdbDiI6FRSN z&NA!q9vB*8ANOL1wMj7070r`RxYK(xy7!EjX}VCwTzm4{ag zNghP~{x@M#&l=%-dJ{v7$hc4eX3vK~Z#G8&hT~K6lmNKyENeO|f7+_4&~|A*On=_J zwJlZbLR7K!jxU2X1;s{Lv;*VM0s6*drz32kw#saC6` zq(Vr13OwszIG0D%Q`{rq0?U>^_ljKWYqfj4F_}Mh#i7RSpnWJI!ib)gBPScERS4)z zJ1Q_@K`MUB_VVaGxU}f{)_NdYK(gI*H*<=dr?MuMcBN3i9aE$O)GAr@?0C_fd$oj} z-m|%FMUEYW}_1B%NYY3|y2_nrsaa%2L6$_Jm1d_l_XmsZFyz43$xf)Jf zi_R21x*0lRm<>B?oB*$OD6lND=NRA!d!GJNwZ}cSP&~F($tOty4jhouj~zoE5VJ&{ z@GjRt1&;nqmuHZvuQL=(Q{_Xf1r8NlSaYL4AfA{=Ux*yFgHjG!rX<)y9R|6La3Uvgej zc+}Wk%_ig$S|z zj3EMw0Ei<1PXyZu5Wx|p@=z6!?g`;gH*w;w+A;mYUJdC^MSqT5BL`A%a?s(TQ{5AY z1F#4)*c&q7AVNx0I;3W_R3Qf_#xS{+5(ekx-v~3<`vnj+x6{EjbbFRB#EVPr(}rRO zY1-1{lBc3vYf%U-?ohiuXK%L`1|aVffj@=~2E>ZSe(xbrUhWg$LthK*6WqgJg9Cv8 zA+0PDqW_=Gk8@V9{@eGj;-B%}P5XZSx9{TJpMTB!g)V&k^XGN+mTHR~w7pu>tKTx> zR`;JTwZBhgm@lvB=B=?WyU2gM9w}krWNpIX}$T4=-%j5Q+-GB|6ZkI`t$Ff z!KNzf9KX?|*LKj=+jzq=*%6_9{`<}Ka;rS6`M0GXL)SX)5?|E}N)J$fM|B{AIGq~o zTif4tg0foAyt&_X{?o<3=VpFevuwrB@%^mLg+LJ_rFZFRvd%yOeXQtudr~S`w#z`hF04T>8~vA!_V&3&Zk&%(Qdf!3+2z}PyYS%YVcgva(l19 zh(EY*{PaW%P~;NmzRERpWLnj8n>yxQBfkx7v6tCHek$NbI3+y4tE=U#;1z8HIW_<0 zvVAiH^&*B}(#mFaHS5nku-mbVyn;zpsj!Ywf7a#vDLJK{)CpWj8KyUp;9u6HW0kw5 zx+k7SE}H&4T=+QYrEk-Qy+AWUI&J3X8NZX*FVf4OV+KRWQVvq(E)e_d{r~N&fxw(D zI=0rW(Ynq(EU9un<+un~sdsJ>GeEuZpSc#hQfB1YuR(B?3i56idUrDSn)S^}fvc6R zFiE97QVjbHS+S4!$yXQju9OKBx<~Q7-DYG%>b>Fm>lY-eY{}HcT`<9S`4W7^d*Q4o zCm-x#`IVo}`SoQ{W>U)Xk7HERmop=`d?kE9&KD#vEXCj^f5Cmr>I{ahSC(Fi$=rD~ z8Jm0{grj(A|NK;bp^Jj~na?x7%)fTOS)WW7Z2Tdb>SdLG)vA##JSDE7;d-Xrdz{>T zJ67@Et(1`d`M-cischRxl=VauWI_6G-I}aeZN}1Tm&hN9cOU4TbdLP^S~PrOMd);b z|0Utay_#8+!|dBd0>_1pzD-T6b5bpX+3fE>_MBst_@eiecKhw*vyPTV-Ou+$(NhKv zMZ7TbmNCHm&Qi*K)(%pcsatryTwLDROqcFMD=Xg!vMCM8etA)zqiN&6D|IDuxTFRk z^dYVJkNCZUq%PWC9K4>1_NTO@-xjINKir2Jk0MPZmG=h>ZC_$utp2ca*zO4V8Zu8D zmEDk~`+oIL@(xD{8&I&piiNkGIsB=5)2MB+z=Kyfe1QM4{~c?y1LB`8(gJ{}2W$|@ z`!77RHa}dcerGS;d0qDb8M&K1`$n5m>)!k%?=9X0u0Auv3$Pk)~zR^KT=PlEzYTq8*vU?-&C-qC|0yRiST+=v3cpzs}DbCWt6iS zK3E^S>S!g8Kbpro>-y0PVZ>^|Ae~i0$JGxFmmfGpJ~FV% zu3KVyav;*H#Fn$smD7uFqfbSCNT}P@-wb!eHhnIfXT2|J{GMARLrT5T2Y6(8JN3%- z{$94iv!QzlGBeem9Mx~mL~U65$7uK+I-Bog`|XfU5}AGBo}OR#_B`$Jn#eVBMB~Rt zuhW*{qDOtXWTxdkF=eRf9{62*2oj?Burh6Ynwx4Ov07x?@niHcjxhv1&aOB`|QOp$1WB0tMLRKE0ZhAnL9C z1K9NRnw5$1O?{d6L@&{k#F@ghkQ>5`rU`S$l?n^~#HsnfNy5;&mj)p zY7w)EK3i)OXVR-gzeKG5^gV3-X!aBQsb%KQ4Uszhgji}FMRAUWAibS@c<8rE&)MUZ zDS)A0{#{)sY>kiJtFu>*Pq@PF-Q-#ABAwn9qsI$Zm9G{RT^oM$%bIed1#3{DeNQdw zo$e2-OvjXscTMQyL^0vZqA?`@;KbaAn|$q|LTY>?p5TMMlrB6n0h9&8NF&MF+gaOBTG`xEzIa5v}ucLVO8 zY5$x@i|D_9rpon&;+#dL;%b@W|GIle0!zN-H+Y<3%z0Z2Xj|8b?Oy1NdbaO5Kw0jM ze=+U-&1rd9qe+!hFWUI!%060*YTpTM^A2;v(gJ9gEsWTh#3=Da&Rfr)M&K0Obye}89o{9ol!(Kat#z+L2f zNSSeAhVSrK^Jl^L{MFOH7PQmNGGngoA*z%p;COa8d6`1G8oyzX2^v8L42bsbjpbd1Be;IPnaYHE4#C$s6Bx1@`Vs^1TW-?zX(q=E6>7u`($&|t>eP%85PTR)RjW<8$XDVTWUQ%T`-lkQ9Bje z8p)$ZBjbm8_|+a|4w3xRZANaz+%Ut~Y)S4&lVagb1&V3qW7jj!=T`uizGvH*$*lM+ zp8Yh4{CxJo>cGMCCx)$ilXjoBxL~H;0r-6^hug@0pM+-`uf5*cm6*}@J^uFJK0HI^ zwS>rpXStrkK4VpIDM%=xhw$m@bcxC z7x#Bxtsh}MPHVlfwqrsA3FOdAoMl9@Q>QV zm_1V5zoUD?{Bx%ZOv&PlLwn8H!leiqk;d-lIaG0UW)Nlva8E*`^!lZ%GYRSsT+c3q z)L*&_N~OO2(f_#lZt&muyf;6OJZ&pmbQw>{0Nv}`z<%j_76`nr&@|7&3Vu+(^zC!U zX34ED_x#SC?FBz}{($a6T3&e}`^3Kw>_=fnbu63~dM$KK^{0Sycc&PK&iK(EwQ7(< zlstN4eBZfCm68Q-AAwfBb-Ywx@aX9N(xgKuXgtYI{gQmnq4VYON|Ddc7av+ZRu}6d zuzng%)P)6{_-|hiH#us>cB5!nZGF_!-FIoBs}zZC%UMC#pS}btU@e+$X1)d|jJcls zykchi>())94q(N2y=%uj{}SS1!op1vhjTAqo6K#699^Bd8>THVC30yVGMYFkVYn@} zTHE~Vw8sgdKrf2sBli|zxI^C(JpTPn-U*R7%a2?0i&qf1ww5kKz~kSDQ@bjEF6t?b zp)KUxm;cg?O2a(ge!>Cr=W`~$1;=Hq7;4m|4^?}F@n-*Xq*B%!Q;UzKEo z_UG(g>wBhJ5|i;pvb$6#A?D(F7iH7*d+FJME3T)-*mt%A4-R}>-@GPN;6Wp>G`vkuD~d0($$Y zAH;Gq{!C&StyuzCHCD&o5~89Q$AkaEWEQ~BkG4%82{cU$sonf(kzef_u)KmCS3SEu zEusA7)_iM5g8j5*v)<<9CmFlm;7UuSx{<`(;yxuS4*&69S)Z(O?=S8W;7{hs@T(T+ zvxN^FkG%S{Xa)1XKr5D!E1qNDwz{=?rt0n9ceC(+lv^ zku0_R7a`|mv-uMn56Ba>{;ag*m$n!{z8(av>VF|&UvC^QaPm*Qo=a>z5JPyFb%-|4 z&X;}{oa`0RZeFWu$@VC-f!vrzImj{xZ)46`!th_g)Vsjtve}*s$Za?s%dz<_lc5-q zLGpUwvd*tKZ#`|cAG`oxW2c?`ZzB;7u8$7{OKE%Ty!UQ^XB0AbVW0Bz1cw`6Em|Se z6YxYGM1Paj_m$ziZS9|jhJBn`%VbPjWSN_<5gEw}S$X)$>PAFvbq>Y$z))&-_2FvH<^N4m` z;WNpc`5?p%pJe5`$F>GPWyZ-qM6hG8!Mn%XW&MCdKlOmNEz3;wpE=oQmCDSVX>41B z@SVd_J>}55XYpXKXRa5hm|&mr#!P?-ivJ&Ym zmt+`at1=`T63|=3TPtS9CJE)5>{wc6KlJi$ye#mx%Rhm)hGwwCZLE9BAO_1}uXa%D zWfv~q!j4}*0yr*=vhk8n8PqWGnZ%Cxg9JOgZ2HAi?bJiIP3A)x+zApFii@)G79DV% z@w+k9@XyO;i_2}?6&Z&dkE!Qn&R!V7V`mN0aKs6>BfRA{xE`UGY|nAj=!nZ__&H`1 z{pSuAVeSJS^$s_QdX3ujztkBt)=lcbfPu9#$GEn>*oqJT}Z6G5F3I;V#)2g)0Zv0(N#%cW87leQk$>CSoox$+lY@VD7{U%WRW_ zp+2LB$m3UzAZ`tpsY2_!#^^@!-@tVcK@xRlaL;V8gQ-Cl%sM6|;&^D{~=v-!c>RBFog z80%<4gO=-6TJ!0bw>-{kuK0OJ@c?z()$uva2QaF5yb=`7?(I(hh&OYJy(m+umC? zcpW@tl32jUc3Eak;z7Xm2XaGvnZSqdF7f4$)$#TV;yi_%C_}RB&L7U#ZC_hwa#m$|@Gi;By+XNaHnxFToT9reNFE*+!`w2@)pIFDjm+%#~U-#d}0DWkq={!mFJ0jXKcOvvGNz#`FdTx zkC6APA%l3&#&hoglYnxYCj(#1^=}>7_*?y?=%UE*mJ_Tk00@N7{dSrB;rzHX-!Y&` zs2I#H#QU3iE?W^2FD+{A;;rE4>i5pRK8xwl5vp8U7uK@+pALa(#tHU0Ar@G(AhU;t&V5@8+VMM@b<3e*We%JijhS|ncm;&^xP1g?P?FWMBrJoy zSrIS?oFC{UBzTuk2B!OxEV>qzZqbV*l63=vsl}38bz&KX=2<&z_T-e2O`H#PhgVT~ zY_aNl)WXLCA**DZW=SQY)w68m>aTr~?SPH8SvqzLQ{EQY!rv`|%OJXP42GRU6GWUc z-a8)NEQQ8pIpG1n+j&>dY+fNFW@L7bF8Dq9Lfh4=lGxb&SkG3G8~Y*CsY9#!S%&7{ zKkDdSxZq^4i0o$7j7dGG5^>U9vN#A&x$=F>yaxr+81_w)>BB9Z!3Bk!WH)ICQQAs7 z!^@+9nZg&rni^6D`EA?~A=4&iol7pH$UaZ-q|s((b!7Q}iw4~ekL(T4z&E6?#HNT^ z?({G7KmKKP-2V4CgQ5-UafS9cC1=a{!!c~J zm&A)x*d($R852DD5&c7E+aswh-NwPJ7kSqBP&^=(IAX>AR=+JiLHvO71ZBKq`A44- zlc(^#g(b02BE= zD(4V#;>%hYon=eoO zd*p-chwT1DFVm6)e$k&HKI0E?Ag15xZ-(;^Wc|I`@Y`*++k6mxzt#-@0775Gg1@t` z*>Bb{XBOSy#=-vIO87D9y`Azr-{IRy53D)6P{l1ewfo5XY@>lj3^(HNk_euP-{GUW#p37e~183V|B0|XisWa^NJPt7Nlj0q_ z{o17XEQR&swh#72sz^f1>=sG3OgWrq7+Debfs`|s?ukno>qry(KZ8T;AK5>X{R#Xn zKX3Gv{k{IrKkA9~Exsd6k7TraA^pGJ_zzgU6UA8z^27H0A7|9rWt}bNSM-PMYGz?6B8GSYx|F_^q}M zZ*wfHXITVIB|o&g!zpk-WsRBePdw&$`U@n*RM?P$3csyHt5(_NbGJ2%Nh_YM% z0J&)OKkEk%hIl?7_kRO1#lDemIc{H8$ChEyIFEmCdi=AGi^KRm*=6dTApZbs`y}2o zn`sXGw*0mHxBZp%uwPgw)9Tf^BuBZCgZ z4>Q#MtJCRV%=z9X**y~J5d-xy+N??MUYaXJiwNIW(eg}i@q zi2m4m;m3@SN!0FH(#t%bKAEq$1Lp(#gnYFx4+I}ze#rbldi7?y^I_uf;CYK>l1L!% z4-A4Nk5+hPgtmBiU!aUg^~a&t?_R&aaJ~@?mrMukq4E>!ZulrkePsR<`4Yae-@GQn z4}#&s+hvY1=0|cloyeOk^7)vbR&7T!e7qYZgNZXN<8SaCKJ*@McFFb=u-Cy#+LNn~(s^LX1b9iME-j^&ZzmO&BYmP~NNS%)Fm9Xau2%Pb(-jz%N+ z8!Vo;%zeaiDTJlE>u-nKB$JtE4xA!-m^fg+-H>~OfgH#`go4RCoO;-XBi0(*FAgT5 z65*T-UC%eK8Q?#8hoaT(khX6}8#dc)JUAnpo+N6_vTksNTfHw12Xo7KLyrz*oI3d^ zdh+%$d-3(~COAy><1vToVf)i5BS%gX;CMYtICIf9b0jl`553rk=G$*}8#p!$i##kTKaC)7K|gb#AqL)vG}$JzMU-bNP@eI1v#IoM7={VJZE= zt?}W$?|)Fi$LBuHwto)!KPTxu5+G0L)?$#ex@gQyvy5|i-x%NIln`Wi+B%=DqAL3c&S;00-58DGi zrhSF#{fJ8&*!3inF~hkJuNRwaG18hG;eEal0?q}f)qyz+XAt07)#^SHBaQjQ*fLz6 zbR+IymLaAP^=CfZ$%%!Q6Em-dUpCn`p3>*Z#$jf%^xn=MeBs=VF!6Zwi(&2#ggHf_ z@)f72t04Q(JOgDPY?6MLpl{A9-+UslzTt`3-bK{2x9~K^<{o@1O zjG2&qw{N?47Ed#oXLp47=MFPu$QQJ~*MSA}*pG|uwnQzrgiZG#n8>k>Fug>NP9>9j zu;XF>0Niu^N?)6M^YEK5WW&Mlct_6%>m&fXL|GPllJxY-p=1U>1sf2wmxTL_mh5Jix$hh z8*R2(d6r(Rw@3KQ&lnd7c|@7W)S?Y?5UlOA^^_{gV7`Bkj8n zch?UL_Z%|GEGH#7oC^pbvdcK^N$+eL`+_!gmRV;5VU~36Pm3J)J#3kZEaMvyA4XYx zj_lc-&TYIpI2&vM#uwO2X&h7IwsA8l!JYMW3nZUX%(K9=fzg(teV0S>ACV7S1Rm_> zM3zJx%Oi&}dgIiTpDmZZq)PmK zjQg3E5_AjW!W+x>QLF8S!pMy9ho|hXlWBfihYO?pLgOE>3nz*i!O0Koe1(zj%Pg`8 zEVH>`7FolISRsVWyxVQJo50I*{n)Z;93_(GJg))zUe}~Y)DYx)iIN@&Pfy$Ntw*X@ z$?q}=(6EFcvMz5&8ntb!(_tB5dbZyJ`|#fmCkgo+A|v=8m+bTFtnvOoi}pCg40wI? z`xnGT_0l81M^1?A{{Vyk!~iG|0RRF50s;X90|5a60RR910RRypF+ovbae)w#p|Qcy z@ZliwF#p;B2mt{A0Y4CoX5sYB{{ZXf{{Sa*iJz$d0Ok7J-X(o2>NAMF#fHD~f8}#6 zgZ}`dar$xfZ|FlmUOue(mpK0b(#yZ7eGUCD=tc~4xvB0M`f6X$htP8j{Y*(+E%~ZC zF-o>(G+y~5{{UjmrDyp;Bn61?>#`7>#e`w?BXHl;hkr-Et^WYvaXF6RxVVSVjJW*{ zrAU_sjG1t+4rlsbmsP}(EfBpn>1L?1= zVpsk%a^k`+CHRK_0QZljqra`fBr1yU)NgtnwS3ohY+?ni|StdKu771CMO~u zvf@CZyGuWYB?b?gnqvtS6}&lp*4xjZlUzA zqc0y*UrLoV1(|@?{z-lyXpCWc`qp9eKK{4#VZWtz%o$QsSMe;@F^Xp}@{-QUa_SNd ztDgZE$&_B;*NTc2Y_UnEnq|Q|BfqV}57OU>hv?E?F6F`Z1}-Wt+FR$6*Njv&P7lOx z1=bqeDFGvXBO@ZGJan$Q9}u{cNbX^_UM0(?GUbzboJ+*MK9}?s{{ZkgoK7W@@fR?g zeI5k7T*DnrM)Un9q;8%=aJsKS%!n zVjd&ErqS2cX8!>3S^AM@GVfpbU!kA;4uA8n{V)WfxpvbueGmQa5gO_S-?RWYVZdC) z#No+hVKrz75~6cpF+CHNSSQGt#0)6eXk5H^aPkw9Ebs+E3hm>#$1wRWG?Xi%dq~0% zt<9}}*mkN2oy6f`B}4wGlz*&`-emc)ZDvRYbDHr18v;0si}`9Yt8hamXjp$US1|*b zPrL%+Fo>8EK6074?uH`sJ{)}NAJmX%G=G_a&^xjlVy|+GBKO3@oX4b_W}5zxcS2V8 zG{2)sT|g4G^bUT7%)h+3ad8Z@23)w^!aA21nSbyFnLy{XMI%A+8G*YN#j8U_7dM38 zS#eVNgWWXz%LuO8VAKln2&$&DE(Vm~n|$771}EGKg}mw{7TiIXJk+}@-r}L>s93b- zR!}$G5e1_168q@88NcnHz*=>0VwdOej zx~T0*r9+wLZ_+ckU0z_$?ROmA#TF^_!2V&XVn6xc*NE%r{T)k}oP9GZ{{R;lW9!U* zmr=}N{{V{mA6cPMs?l}EdeqMq0dkwZIv*i;DJI6n|6sW@-kJQtxN z21)O5$}3hi4*|K4h&yuwE3GxS$Tul~2MvtEosd*s97I!<6v65+I=ht%B1EOO{7REJ zik1V~x8S3$|)F;WZGvGaiRIjgZtTvA4Lr6gyz< znyTH)Fyqw6phZdz^~4b|O;o+}2ISYdODROzv6UD5hWJ3x*~BHVp_l&vrc^B+)jMLa zl<_YD)xzM0IfDZu8$g%HWopx;FhXXyeaC`}2ySk9PWcTyWIqs7GjL4(SZZnX@$|2& z0Em5EL;nC5IE(atyOs61$I{N`FX&2QR^~g*+N<0v8RW&v>wv(SdLhKk+!CO00ySgs zQg0u%9JD<~M+7L2)oBx`Q7aEQRVis-cpzI6$HW-9xP5Q`04Bbxh&E0oMvncw61=N{ zs+0t$-P|XTQwmI7A~k`>gg^sPg4NLQ_u_`cf?h@m@(jYJjMeF z64Sgw<1+g-pq{6x8JQTCmlx(N5;={RQ0JTx)uWf>%m5KYFmJTn8Xj--r!Zf{f_Z%pEpeSYT<7?Y<162DX!lEnzo#rhGYwid)eqbkF zBNSnAq6S?#g$g-EfGbVGTQpU+%h9=3L7_6{7AoD6#SmU|JfM{Fy$B1%@etZSFvTa? zFb)1AyEX9)Imft$#2H1F^M2+MQ!&+$h}P~74MGqDs|6`&bU3(_U2~YuifDo@wz!o5 zvDnncRYCZVa4B^Fv^&vgnjW}ym+CDN<-`q$FFhQ77`0ETDj zafZIH(JoeEGdxFAiOe4TqfsW4)Cei?7Yce+(E~tw4902w(;U+fim#XG+G+Jd?x2|! z*$}GNc?`WJs=xU{i>=(5xNgQ}VTIDa+J&^ol*BN*I)BW3OkfG}{{YCm&Y;-OIz9d( zsurnF-ck~apxxs1^ZAafAMf)mAy=mi0CUJ`*QbAYb*o6+AbW}sT~807i|SlSDcq!F zrmIJu67NsQW&rPe#d2_QDnZCr_>R{+cFag>RF}3#8Y*24tf5{YeHbE9aI|ir3lwIX z&-sW@ZnL?P!xEk>2rxKaNMg2>OQfdEVidC9?kjPXmJ@DefUlU1r*eb2QH_~dPFrOw zrc;sxp!u0H!74WqwgA}KF<)`wh#D6aD=#n^3ohUdkyXaj+uX#{Q5nk`u|8pN(ap?= z3+gZ41sCQ8RXzkn3UchZKnI9l4Se$|ex2vEFx(53t-~$O)=aZbHe;E4$x=sf#} zAYF5a#Tz+cK%-+xtVYD`{7O-mZsP1x>4X|VSqkoR2f5jAs+n%F%|#gjjY|`_(cCWi z^BloY+QBF-&9N?+xZ8Ejut1}b)W(B)t|j4cd5U3YbpTdsCJoL3s&O8-UgJe~?}#v6 z#u~yW!u1A_j~3lQkjoIkG4U-F*(?LeMj`+e`uD#X$M_kA3VS0Wb?#H6--vEdWNiHI z0dTnhj{gAUDanGDL3r7l_#h>vP=P%7my>m`h1b8_am9Lx6x7rTbW0?NS<>PX4tK~w z{&fX8?pyRH?l<+f>h4@pZTdT(GknjKb^v+AD$07tsk7X@3+n#>`aoyhp)x9a7&rLk ztQ1)YJP}6A6^un&%p)egSVdZ(yvx{@UobA|FGHW3Ii%Wc^ti=~FX+Fbn|PZr$3`HU ztZ8(nAJ^Ivbnd`uCe7h>aQj*nGF7aP-577jlPjiDCy2dFKDSGa9sLYo**U60vB2Q& z{{Z<=iE`xgGYw=u8G=Z3aB7$+wT4V$DQKdHDJc|7QnKaluTZoQBDThP^weHft+#&S z2rkQZLNrF(Z0EQzmP~e$aJD@m-9%kn5sbN*?g-ORySk`oO3bv$xEs#n88B9-BDa^Q zBLAuukZl9MTw80X_tboQX~ zL8V-Za9GQZGbp_ROWTj;J7UX_z8ci9agZDw7vD9~dBHR@`n zp2@fp!wyF9ML^bdtNUn<(#rGy0Eb^wd5wJ=pE8c%j(CI*y<=o+*D$|mhg>AkBPxU8 z)Y-dj23Tb=GQCH$0|PR?B8AuHSmc$uZXnw!S97pInTla%B9O6z&>-d7B6}TmoYD2U zafTJoIdE1<}{u5sDECVF8x7Ns1f(V`z!0 zj2HYrXp)O)UFF_9B{D$xg#wVxG5!5ku4`2nv<5|e_>@a0AzY_>ElrkmMW%7Ti9iCk zoXSvfH=Mck6tQaMR$FjE+Q%~YB&g!zsP4%~qnFDlxT=ZKjR7T`GkU3+;km zC29jp#HDRe1U{gSE-Pk)QLwX9JXPFS0wqks++VT@&VzARS40M8EjTzya6U{L5z8q9 zRHocZx)xQ~1mAPoX^D9Ep3?C0sDqgEjT5<#3v{C5XH2`l>^Pn@6EoNR+<_;!%+cItxvANV_S6Y-iIfV+TVML(ij^|Dw=G%sW zzr0d~!7WO24HszU2|)ZsaNRnG2C6e+;8H#oXkbAxt5N#C~R8nl!0|~ z2S403x$5FJVO;H*5C#Fmt~JG9pHYkc#7@<}{=rUw8Mw_ln6qCp+LyTpbR7Ebqqee^ zd_y5EvR#*qho5rB(mF#q$58W>&^I;X`s?%T?WHYP2^g^V=7^XlB1(;h*S~xD@db3Qr8v}T3K*Wn9*sb zEpsR?R;mk{Dqw`>(TQdRR%vDBxR?wC7U|Iz%H?$e!?{aa@g3-z0*K9k7|R$#HW(@a>=;E=P)Ck%8LrG zh`9uO&ZQ?NCAaey6x2mrHbw5ia7FRdxt8?6gk?sS{$PV;3M}R~TIrPDU%WuuG7V}_ zHGjn8i)IyhnKDdY`w;N%A*Sdz9S-l9SWi|@@BIuL4Of5lXU_&WlSL4!2=U` zTimLuc$8tG?3|IALt^4o3;CB-Wqs;Z^QgK*TkZvoQEbAvses#N*iIG`H8mYf{v%{d z{!Mo=&i<7vG1R%V zeA8t%kduj0iNX&dY){Tq0Mp#Hjy%qAja*u}WI2$+&$?p^Q-qd*^v2+=*>9Pxd=^?7 zc1wFr@e@U;yP6yMim(h#VpL-3@e8=KsO_}OwcJ2v;*flhO5C)U5&j%RU!{E=M}Jhz zaK^r6N`xFkOfN)bvI|K~D*)0rgzt6siIOKo)UZl^A_NryWtEh%izTR6V_))84wHyA zV|CQVFA?Ytdx^7H(-=~BZ{{7(DLGz#mTbx?EbFt5AH=DpF;KF#m_p<45DIfX$?hW= z%aZt;VfsK1_4g96Hfmv6$=W#l!>wzM0W}=%7{*A}D|PBpD$$By9Rp;j!9ZqZVB%!J z%+L9#Wdk%f@c~;2O(HHPOJu|%(?T_Cn%s56wphmEmlVM)6U11m%u`)J z(8km#svN?lEy1vRluF<^gMvGXz?6h-G-_XPZ#>Lda|h{aMsPG>l%jx3tPO0haka-t zUQwy#jrPtVfELEv!H-==6$FblFKM7(H7&M41^YkpY%oPtw>XqmTi=LhiDQXthb#d% z@=Gt6o*>4eP@BNiO%CPJo@W=UlqfTs%oVW$VQ0*?YMwib0>whD#CY9qq9hrvqtSta z+qQ8l@p9G+TrjLES1_X#VpWEHK|2SSU?BxlX_!(!2bgvR9M)<8+1pVSuNi}ubY3`s zNrv-ram`BfOB3(z3bS$0x8`I3W;i7r!4EQvgi2gOq=2A1bDy{7Wcn=-yg6x0hEvqq z8n}7X#Ipv64xu3}(5;N50*)37rM$dF;OCyEU{e`*mKKoo#lTEs9Kl5@>A7!lv{{9a zg&PONb#4up5Zuks*HIrR3NSR=%mYi5R=9_Wd*&9dq1m4TCz2u79%bUk5h+5*?ZFiN ztmEl_TaNyT6U0_8(543AhK3U`6C`2v?J2sBf;r3l#4H?mhp+7lwg8m0QI0;FfEmYE zf*A!pj0Rm(1hFrfcEnzMedjBmM9$?!6^ux?9^l#9K(8waqXrkp`!NQMN~A;FZ!PX* zD_P=TbV~|#=23WAeT@v^80QF6gk~B}@6)|H>N*+=QPi(hoREht-eLu}TY?H2Du|5; zE3-$5pT%khpm9*D7rTPp#X^C2hK?7BQ#7E=!n{}7RAiP_lx|qS_Y`UNh9k_nLmkzZ z<`;D2f%;UitdJv47>WuYXlu+Usjg*^tz0V?#BNm^$LyB48oJLh7S197yhSe0m=^6^WU7@;pvuV~DDlJVlyl2-EhAFQ)3?SQVVH3&AQ7Z^`OgBTe@f zR1xN0GEWhqeAWo5cW_7@a|*0npmD5`S`V0taZ;w@84NaWJV0MC5UeD47016rTaHoO ztLI>~aZ(oB$`ei-&Ss$Ld4Pfq;P`=8yk<0EIg3JQ>zI~atyLvoIuT(WwO%v zmTH0j0LY`J)??*(KN8)g<2*|hk1fL+7v>WiEEv?wKd@uvl@Ri8DQTS|Y2<|(qU0;V z5d@>$aC(Romm3dq#LFk*3LMj1a}bt*OFU1@@c5Q0v*+R}F`nh&4g^sVvKvm=cXs#3 zKX~#YEh!p>u(S!l6)a16EQGtlKwxnN1zg231D)pCfLil0vAd~JrZ`^_TSnbXD$TPQ zUoPNbc;+nMGbj0uRWU~91|loVxZ|9~rN&6DD=-f81589wM($lKYWEqO;4>BkHyWT< zn3L4ndw(JBh))L9s07Z9U+f?Q;anseh)i4$%JjFrfD zy1~n6dyEwZfU6s?AMC|NHa!*5nVsEWFa_E3kFzQasYNTcjYl)GSsQIH9v~N)>~WOm zQwlgO2D=P8Hx)T)W>qpsq{~$)VNqZJ#lYM~g1neK?r3!20#X81brE^gO@SD#?WyOt zzq~-kJG)VFx3!F#frbY(;s|q}a@B$)0v>J&l|02hjm#W3&FUbax~j}}f*vDWwOGBe z6d}(LH9vWs_<$>zR@x$8cPyhW!U}&;fH;89o?>Lzlv)=L8iGM=K%7Lub_k{I)7fKG zwltFzpzoNX-JQVAKJyO1a~e^yHWaL8nARirm(VEXsMJwVAaJ8I$hZz%F>ehJUKJka z%y=1wi>iv*W-3Q86*7yb5vEe17r2xInL{&-K)Do)X5gAb!H(LOXPAJUQISp{#s2`y zxr>};BzF>2w!Vdk?FCH5W#(x4WaI4p<(-Ju`HU!+pNT@wdbwh>rUXe;!{n8zed6M& z97gDDh^zY7nDDaPPh{-0d4kRr+uHvC*luF;biFVh>n$A{{-V6UFp4!TT|)sfZ}(9e zv978rZIh^*T`J6y&DPhKCr`{Q+W@rqP3{?R;KMhFm1Jsy-anYy-Q;#|z2;Fz1wmGA z>IHkd|{Dfl(sjW6p8JwcZfsQk)KWfU)y7 zYNLPy%(!kB#ygdxWMh@wqbHa)*)>4!cT4D_X?=tVhxp}d7Hc>g<8intGo5KpY z=a%Nr1Z>?F!Axkxtw7)LMa1KSo-Z-ZBL&P=ajvHX>%_`MT<2^}2Ly8GQRr^y%bS+& z09P6R0PJ?7a^?Gk917k8H5z7vcNwFg7ay=;n_$x4jKpd+RRC)S<7IxDZq`g4z!W70 z7SHqZ0AG7Ubum!&1rdfVqfy4*^MY7%X3Yl(Jqpl@tG-BavWg}g|a^hxZJ$?b4;Ws=2)YM1TmH6VeW3xhh#X{B%MUqlvmjIV083i;Hd}S3C1*aMY%DNsO;)9g zbe3Y^0aauD{^|@Zh-527m1?H}EMOI+00Ix6Skbn1KArS)oawQ8Aa5j4jatDy2s)qjmdoeAO)?#hX!C$aOza^ScWIbQzo~> z1@x4`*`_U{-p} z?2x`X{lV6ofA$DG7!^ileBjm4#rH zSR-ha(H*r4)Wtxqi1sF~fIeA8F=DVwKoPi13AQc0SAmsSe-oye5F5TVj9LsZNrE}(tvhm16xtg-Xi$N7r8*H zlof_B&SGbY%{5BRb0es zP>7;pp-}5r9mpwK!e0JmZKJf}T*`-{_=kX8&r6M)#dQLdZ%`>h4(n0Mu_<)u!3nj; zm?Z&=5JJqx!1L55D&FP98lW**S*$(70@{EgtTdaS#U0u zvm+Rn;gy(bR2hiFGXh>em;x~zgk}Jv%o<9ULkkunS^P^&OLqB%LSfa*ma^SuVFT`H zY-xr8RS;FG#13Ub*)(+OR#w!dq6jHf8%mZDOjMPKNG^r|g~k3N2QW$vMPOa6q7vYvio zn`b=B)kJ7YMPEWJpounkz%_0-D|s;nW`SivtQl#xv_YfhI2kvptlsJ=cmr7r#Z672 zGL+h}1G^Xr=FBZyTyr!TsnX?iOzE?LV#C5q1XZTh&|ypon&4@M?@@F+M7 zcl|QdtvOQhN3h|(rE=WHU8~yW0~J`6Wk7cbA-_}ZBh0pSv{WU)1aXsa1p@13!2PBh z>luyK2RjII+hgF~#qn7MVOsEb8haP@pcWrp~Mu;v+Fo@EUv z{w2C(h`G4d%X~@#5QE<_FVhqYXpK)d3Oq!{b2>Ve8EwFKre$6w+6XHgOAKJQH2`g6 zhXG5p=bai9|aw%(PdFEMAh7wm;gJV4*2)gA(lVXljgxYUaIF-Nl-%QRWT|HCmVjuBD+e!LW9`#4Tm`Aq2cdNfs|2Hj5fTDf#+hdF~GmqRUWbTz%kxvfA; z9mFmKzz#EW0N{f06N<7Mig+SC*SO7(OOC3=N;!)I&_s=a6v>vNw6grg05a~Qu|H8I z@G*f-W=gM^Wo~98++-h#XCWCiokS6!v+*4=mSHV}V!^$&8F!H}q`hH=MYNEGs*0S) z@Cw$gJVkY3Hf>Oj2uNH_;Rh@$Ox*xo^$!9P#CH)CIa-#B!zYcll*@Y8ve2%)v}J#Y zU=O;BXk?_-l>XUFwuTp6(rfbp#}9XF9k{$rO@4HmRlFa!a=wWF0Gh{%R}}&RQW3!t zu~k)N_*qMU1vq;k&;x>0(Nd^}NYv0+f>~~eoK04~T7ms27Oc*Ee&en{EC3Eyqbu6*}05a=$1$c= zV^LcauxTT*olFCD$%}zo7%`p7bEWN`rNO`qTr<#01<>;ssbOCeJQF-hfwdq$PrU2_ z03e`M)OEnVV?xuHH3J1Ns4BJZ7Rn_qUCU@SUwFfG-RHPj0|v1$t3!Ew!p8-|iB1w4 z${r${CzdLJ-*V`9Ato@+Wom zLYH-vWqre@Hx5A#syfVW%U1IhbbOY}dkMG-ux;L23->CNDiK{)BaNSJ!Szz*pujvT z`o{RZVzQzN5{+fM@$6N=q1x?kQdHU`F$mqqP$Wpfjbc|bH}tqdDa$S}%49bfK-_3* zH0jsgauJsn_{18KV(q2D z>#3!tp~+HmV*}=Js-m}sdW}O36xJiK;rv7vRk)N4Ke%`g?q5h?L{(f8)0vaka=XTN zFws>DBdMQwm#P_9_Z;*@4DK>rrg0qQrztSek<<#{Z&;at>vt~D-O_a}gBkA9HNQrG(nh3`MYS1a4ukFrRFNs#)bilp9I!!iJZ*tW%sD4wQYz1Qu6>6 zWOsr9ps7+P5lp;6a~hOgsGR1(WpEs^ZwMNs>~_!kp`Zi;rCihP3@`+#jj?zlS!-7s za}J_Ybq5f%4%vA?m;w8!p~w^hEh%qM{{XONDP3e;XZ_T?np#@ruG+86Yz~*Wpbs4V z%~Y`5vN3)&D6r<&zr1fVzPXpLdovcwiPUIuD79MS#HpH`iXF=vCz(ONF+f{8iKiK% zC4ow#RPh6qn8e&)v_9?tBg_d%8;QkgT-dkNt`&&O6|SRiH7cS4x`Ykl3YnC`wG^g~ zD&5AkXoWVXzj2njS(RNv+kRjGL`u3mLtWbVg|%m#&7N4;#G;I1A&OQiTEQ1EQvxov zEN$i>wNkBF@e5K0`L8nR=3%2KiM5t_g;#RL=H@~o@0iEz|AHt0;iP zO;fKBnG0{96Cku)M#9L}UFeGn?{x^%CINdzM~6{-L-7#M+lqo@r@X|A^{Ci4hY^L= zI*hrXR<&7KV5^GdgwNhlcM0ji`+-OlR)8q|N(JO~{Kfmh(Q9*wY5Yu;OmPqZtUOLU z+(&%DWaY%QMUD@eiYrboF&pkNb6UHK(Kv{-o6JW_gi@EL=ii};8epmSAqo%n%0+Zz z9%YG+o+82WU;uI%x!Aep4XFieI$>;NmtQB$qWCOV%%JA4b;}M#D=WmuR|`-+@N--C z%#F0xBJ6$Q90ld-V1+9;3aCB6QO~(dLrB#{D@$EUrV531fC|JH_AuTU)|;#1a^5D4 z#8FcVT+5jtUmV%z5CB|+S9Z8R67?MkaW8n8f3h!4%nkT$kIW=E2viS@lIwEi1!!93 ztr7i+kg;33?h0l#)?9_^j`p&kfl{*2AQ!*9w|~$rVGeLrd0@Cu0Xcw0Ql$hPrpPx0 zlnlW%+Dja(#SjY^XPDM#G)&-un5@X@M*cg8EmTz)rmyBUA}sQJ{6{jW*gn$#04paM zRyS?U#G6uLZdZK~+n%DN>BU7?n~AIE_Y0RT_CpJA%zT1wxPld1>SG3oF4cTWEWD)^ z5VqG1#xgaC?RCBR+zz%y zz9F~aHJ`M2wp$P?Y>m|!%n6&DTw94^u4S~ki>L)-dXFi@TsG*$Q&z>D;wJ_(#CKJb z++wv6EyMzrh^p##>49!>Fe~qH08PgY8uJoSG5VR=Cg8yuIcCIiz0^*SCMv|3AB1l1 z<%0!!i7tir73WVdAflg{Yg(tNbRT&|s?O%JT?xQbikNUUxmm11r#OMGbBHZ1x!k*JnWwzOS?Xl_Z2QcJ z!M763T$L2E>2Ik(S&G~_3*@C&;7ZY~aPC@_?mS1N1HwIlcHQ6m%vz!axGgz(mJ*DV zm2llkOdN9>jXfgtFYhTzbK-8zXRSfgnD^M+p;%Sj#RnGgEEz|;fXZEJB2w+kh+Dp} z1icpLrUw@dORZdUP|)!eY_xL>4c9k0XP8mOFA!xbeMX}+yddWD%op_JBkSwI(GCKAy$SU9*bmu# z6>PSi&dLu5>Z5LLERhizozC?(%^~9M{avsiXrFASo`qtTc5`x>M71uO7ah^7sGxh` z`m|&ENz+nA7*d0EJ4;ZBlb#?Y$@-q838Xvi4s4;tzreTy&Y{JQn*ylYEUKyq7A6oA zO?z(104Jm}kWm~uMKmyqE&V&OUTjZ0+WL*EO-Qfg?9{W0E_$+xas@No@jiAX@RzJY zEwUo3A{FlX5h`Guq96AwUO8In@lYvFn>(($^mNR zKzSjOsH;p3Pv6Aof*H} zx#CMxxTX}FMnkn(>xR;`RYJCFy+~y3$tsw|8Rn(}Ca-S!#C*kka5* zzQWkG%UEx}bVa^@Wm#Me=}>F&rvRH)C4{a{1e}t>PC@*Opvwv))Ps%Wb0hj9Y&+tU zwY#=LMt2hvp^OX=3iVccg)0t)06!6Ae;9~Buph#^yU56nDnFb&F8RezbQwrpsxnV@HG*d=CKY z%e!R*eGfw3XJZTEIi1(Wg_>yS6c?ZmkG1u`eykT$!VL46iqE(9rjbTw(DpVZ5KA<* z%xDiL;ImNHE>LI0i#8QK}RNgVCf}h66>Q`|`=tXrUfIbU~vn9ykA|s0(`iRv@ z&@*y8y9-+Rks`hvlVs*V8dVZb)-*ax&<(_IaJ%_SJ3Ns*H2F%1egs*VJ3+G}>ga?O z(%haO1E9xY69vP=Q$rqC9JLJHcjEgmY-b6hMTNI-)JBfItg1h$eSZ$e`(}f*c-Bn$ z@aK}JN$=$fv>=D{b`6?@TG<@g0x_21R2BU+n7tb%{L>EJOvVekD)@1pU8e6IA6}a( zI0{e)iRM+3&Ks7Bg9M=Ej~a$h|B}sg4>(9$XxSESthCN)4m|N;vMxHCO@O*!guq(E z?~Ht-98)xJe1KAN6A*@*XuqW>A|DwT&nfbL!!vIIbl_&J>8K_n5!J>(ng0L;4R&lY z!Zk`4`#s4-+(!xH1*-Ir>|zFo3Y9=7|7He%+!FJ$mOZ2|VCX@2yxex`JEY;9Rya^( z6C||On|6oI5k%aOJUTl4o^Xff*NE{SC6C2)y0hI7U7g}1>;`*ko1Jg3PQp=yJhCdE zurG@vp?Ga-npYH=+5eW5ugFV-dw2+={r2SU#i<&l;hsIQV55+T&(7j`jB-kKUPuPjO<_Z6!nANLoHi@K~*m;gUNVE>&?=`=K22 z9fNCD-9Xjrqy5XKz(|&k09_c^r6<$&8SE=rw+cERA zy!QXcLP8=@KCS=?J`Nm4X$rJ3J3l*@@L zbk|m{hIFkNFNOV&6W9^Iz%{Z`2<3h3n2jly`XgzZVn<*Mts z;{nUR3f|F80tHikkHt;$=N}1s=37L@K1#i#o!j10*yHQ9$6r`@Ocm6ksg&*Rv-vGq zQHhh(71A%`C6OH1aL9q++hc^C8=V?!7C#YyT_e8x#I+2AI7H8(nl;0?+eJs`yRCi* z{|CrxW{Ojr95p%4HcP73zI!jHm*OVhuWa-1g}frvdfU}((8twvf^Ik)(~YP^DQBe^ zr&;tQGWT@9XHdhn$O7>R@Wn_njnbaiCL&0*wN5b8!NHu9`uMC6^>T;(A30@p9*oKK z9oq1I=yL!$v@Cv*OJ-aM#JYgC8^7cyyGa?RbswrxRrJq!Cc543Z%2ig|6lQN+8M)^PH}U&^sOr;=m4fsD zQ^Y(kr9^gx`hFInc99f+R&tQK+?cuwyX_yVGU@dY#`>t|#MhYj{}Q1e510c=G8`tc zF3KH1{Q%W|+Ce_~1Fkk~6;^3P!GU^TGkk(>-GHR@r;r-vI!9#y^Sup91mDKCnk^(y ze{JM&tP3SHu%@1oXgQ-Y?rH`SnI;9ssmIs9`+oQ=OU@hLw}MEqk#)A0Y~o^ec&wf2_PjvmfEl3*w2FTlLtAV8@(P z(rA8&bvMN92DTO-EGOQgM3Xltx&Y8U8>-4u2$st_DYoWd_tgd^sG3jp$3s7(p;6Hf zG5HFyNBj@sx(NWQC<@O5TR|UJoBsfPmfgB(CU%+wSgDvPFQPM3^%;)4YJ*d@lZWp} zss4b;eqH96q*LzDTi9YA2~qwVjMk?hz{Fa|&;v1Gi1WtXm-$2XZ*Z0xoR;iFm8tce z_?zZ--d}LA6QqQnT|`SLXI$_aEKgwbSkPSZq_hYUP&c5qko+|T-m}crN!SgONP`Y@ zZ5=B-zIqxAaSp`YT}V7AX4TWc6S@1PB(Mew%4I3b}*P8R)5BWWNr#-|(IcZ@Ox`;h-h9VBH zEhi*&qD=P|G8tqS^Ex)Sjg6~3tfAgWfrX`kpXP=GBe-i#zF#Qg(SfGCYat8k$F0m# z8U|bH#i_i*v1;n%A$39n_-_~_viT~%mEZKSKSFlp#tL_W=+k{`m(oEy7PBUMt`@BI zIQ-m*Sz*@t7VE+!d|(W)FOia(^iCU2r>bJ`i<)oQF@A%SS8~axe5S{IGleNcDwe*~ z2w3X?C=-2x+{wG#tS_9e#{h<#$MRMG74mSjJf2`gRAdRP($~E)$I=RThsJXR(L839 zd3tD2d<^VgqOv-qqrc~&@=KA|ST&+TLCF!NJV`%jS+tWe)r5BWO6Coo2PqA@@S%$v zTi8q!>S~;ig{#j8M@k3GFLI$LvF=;VdKhvzZQt z*SPle6Pg)(nG(d#n9aVr^GE@?D4i&v0osTL=MoJxJ5zjkzdhHQtUQo)Q8aEnB@Ssn zJK*YCXx4u6&NeWI!fds|Luz!lOT(E6(18A6W7efi&2Wkx(l?iv$+^n662i}d$%lEg3hH8mw;X>USf zo^{oa;>=Jh5DMGHLJzfhQ2m7K>zk>Us{EXV1tjH3+vZCIz`YLG~f1r zV^G+k+HP4vpk88fE?&|l`W3fl&-{J&y9KqFY8l|_Ss~xSg<;_9X8FKqE@;3XxOjQ# zQ^A0f9BlsZTy4^Qy$tBkn!4OLr|?L7enZ0nK#OVe@_^}%YnUqwSkW<6MT7*QV#g-( zW*JdcTuiubN02qiHlB`(ZeEeG$?K9|{@nk<05XZGXEI)im6TRZ7+04aP9|J@`jWhl zUuykzOS1Lyy~k}uFs3a3cbsY%5K$Os1j9v>^^?tB64FMfqRw*aQUeNwdM6Hv_4E;H zypHN26p5f5iI6}jk7LN<_ctUf?NqaObz0Xz1LBCI?^FRLP_UVgahmqkbTm^W^dD|V z#_x6*PwO@1~n3Er0LHqF_$mw(re`)Ccn4? z0;zv0D0?W&7qI)IPy`hn?;j_6p!R4+NG|67W>RbIXq@p_k$q7(#{9l#qj$d5E)m+ttYj)StP8dB9Ie6*9bYs+V+5+QBBz?E6}C&KffgP0dR5KIV-onex|`jVSF2%g(#{JiN+ZC1&3$ zSBOIMQvw7zr-Ln?l^hEFLFw{$y3d|Zy5PLSIB@g^4M%e`WY~9c2;M>`hOWRc ztb=kscT)@nX)EazqPPlS$UZoA;cJtUIE3c2BQ@sdee>du(FBQMb=*VD&nHU>abT3P z9AN<%g2}Z3bQcOK-^Q|HLibrTp{yl!Yg#S~(NrBjgbHsA+Z25gDuP67@@Ai+4NK(t zg;5vchq?~$_&=Sdn{eXSxT9I}Y?M^jB+_h&5l;|ql_ep}_ruAbv$)w06)kRke11b0 z>5eRWT2K8&=)Q33N4PQN&mrCR*^GsL-J}>NFHEmC85NV6KCMD#6m9&R*D0!ePFm!s z!{1=Z-4*oAf)Emo7;a#9e}vhfqYtP%!sx(0kGGX-A8g3cxWQ1b>kgn_Qp-d{EP)Q9 z6ghCM3DH(oBJ|ZEJ7GZO6>;fKvmVCoy-9Rp+EudDosc89O{u$!6pKD3 z!-Dn@sm3uyf1*9;=FX!+<)*gFv#Gix*q3WJ;w;_X+R2THbM38o@VWT1z(t0y;6KZ* zKl31$#h05OBXavXtM5f3w4sBFFT(<-)HyMd9mUXx%)XO7cHI*6(UH zp#<+UBi@TL{S|TRlQkk%B;Ynbsmk}IG)u7xL|=G_tNGRp61*k}ud@KJ=CkmI=Uaiw z3AKGnmRI?9&Ix{BZgK5hfr#u0=SxYanm~$oy{KZPHXEH}g;U%SAI;NuN%U3~jpCSU zw^>)6I1{>t(;Q~y_YV+zE*_{f=Yqjde1)J{rCnx{xEi7?D$=rP&!;Z^@#IHUxZ!6_ z;@Al!FIiszwD{1Y%0q9g>~ktD;kwmK_OO$JyWheLbX&;n&aW67N7=;?( zX)0KQ+QUa^BYUsunAA@7d7-cUTgof1{5p8UPqeAZAGD9co*-A9&T`D3pCklEkRkzF zwPAzv3}G6>!@rIE11hch4i)6%42{20ZdMeiuPv`rmA;y-O6UWVBqHYH(mYgy4!N4? z@J3Z}*Ek!3mVJCx!cXdAJS8^g1XX6qo>`0LK!f>r%3Sd-%9q9O9B`__Pr zXN?rfVFE=4_FWgP@#H(;cS5RLfcPOUb8LD$@<{&);^{-Ow|4l<6II?$eKeD2JkE~E z&Pa&=md_(i*9ckH+cDZ8r|d20`^qaAxkK=duQ7?bgXg_zq-ZRzV2y+~>LSd$=@$Um zara>KE#1-6Wg@%GNRN&YD1}h?iUf^8C>;=^b8#l6qLy4w`@k!c7|)WzGQQISHYdkL z#YeS{`zt_BqTO5BWk9{B8hCiRP37K;u?K;8C)f8Z{7!4FG$I|!bsM>AS!rVmLn7b@ zz4iE)^i~tKiaSJ(zxv5<7Y<_5(UsHG=uc5B_^yt%&O5e!d$hwJ&AXv&-t%XEF3vLh&g+wyn_1u}j-eSMzDs=0+VJfcor5S} zr%l2_$77TI8Xyq(1X+d1q_G+=8$M(XwtIrGe-8$)Xad_+^EwXHM!amLx%DudLb1g$ zM6Oo)Lq+?P9!?9265pu&4_^}W)WqSkHb8mzZ^WxH%BXVSoonZ=^V|Ff!-hbRZ%0Sbnxk^mXjaMJi5(twBM2duLttLrp?4=w4&Visn5`^Ah|_HvgcV?Z#DjjKElPD1iY&Jab;B*)gsa-(}@LNT>QUCP>N1i%!NC?Z4ZT zqMz4#aWykZd#XoL4|Dy2r+;96%fn`-?J}O@k7X2)>R5E^ayXgFOq8>#<;j!ZKsVc$ zQq|8G(7bmaEf7D4HhE&o9+zOe3lWaU{JWF*neuO`yqWQwR;Sz27NM=DMIzD>g2`_u zs;;r{1G#=ZGlDzDKM|+NGBl`MI6YAGnF?X@u9{?x*|nMNNWpYXzYj?4br@j^2!VQf zbuVquR-D8ZRlVUl@x9rTgtPI{M+nmIb+I<)39#AAYQw0a)Z_+iOU;^>mZIYG9Pl)^FYg|H*xL8*ciMMWeA@1zLY6Yd;az&OX+4p4h>z(t?ZJ6c~|gGl9()EDRq8 zLasK9WGxLHHogyAN357L3w{ZP*m-fUNV{7UdioVo2ge~$^?~wc(xW=AKYX+S-)j-8 zp?SJ=Iu;N^ZzemUNz};CXt4ra^|lL}s-JUYYRjkUzUh|`DzArUPo?W0Zd@bNB?cD! zxCr~wKYou~ROZ7QU~(_ZNMYF48;o=nk7A7qH89tVd2$HeBoWj#$XD)_IHH2U3^rF| zSG=)SWGDO^57p;M-WOjgp+9?cNlJln9Xww~Mub4^YcR#uDD|@>ar(oEu;)dw?WSy z*n1>taP}HgtuiZ^Y1+&)u!q(EFQv=q@xn>M=UNJfenpTrSy~$PH{GF4&E zSJB0lpFfIJ!tTpk@*N2YAHOgZ?zjMly*~!<6wK2WrCam4ouK{uIK-%QB|?OfE-Xph z*NR`*57^)@lP|}wi}?z z&VR)MPY|;9_em3&)=AAvDK#y^n>i)J!S}e}3RgJw_UONY%+zU5j%L-;(YvhKV}pjZ zyIu|1KB9pKw4ehFb~*o%sOjv&CseP^>MM{9_P*Pf0`UP=DzjXuOC&ZO-S~M({Kq=E z!d>m%_i?AsGbfB`txz7iFn$%vQgU$xx7mLH@2RgJRP74e=$=Ipz(y!BP^e7qha>k^PkwXU?HJfh_VPMFmheI zsm}#Kry^DtphKK(7M>BQ$Li~@ZPL?NKemKjlyRN1z4L75KcsmYgLZQ}$Xsi$E?vlb zUH|!YZ;(ynI65(42I3@tAZ+WdhovhD#MVuaMRLPn<~J>^1ITmm)}%=e*e?VMr7p!8 z+X}ZxOJ}?KpEeCOIXQlx9}PY?Ol6bu`c4}W98~$FE&OZJ!i4cs1U!Dpe^hPGf4{c3 z(WB2;_RA+Mjeqi7wd4d&id!dBlr_gATG=fecZmr3tpDT9ngc&D5A$^gjwRalZe68< zwfbH522N#}<+p}IoYpi+SZ?;l=pDq5j@FU-jA~JcI*oL6x)2>cMOq150L)W1hj8EXxf0 zW57Pk$8)mK^SF4Bkt4XbC+PI0OFfves@z3GlwM8EqY!uL3z>l{+%-IDcJHLtBF^E1jhGzQ{ znN~uvjYzkpW?QYWIY)?G(wTR-R;WKGm9)~ky|qPh&?@zbRr#e>_5fUY#P}lTK5}%p zQwvd7`P`I(SR^#m#V8^7`Z5zs$7mZh6wLN$HNbVvC=0G}nXrM0AYh!*M9d429d z>Fs@xvBHXvQcskC7V{>V$FY6pVn~#^SiIqt)`%>dB!C@FBRUc4NtSh-GSxi8CwU{O z_w2u7Bps%bToy!7RNeOPqw?)zuR3z@Be7>vOurVjR#q820V+5%;4jNALItK>u^aNv zQ$dw)>7F{ENK7v=e^Xh9x^hyD^_HgtFK2VK*|&MH^8Ab2WFE<)d~yY6_O&(2(zS?7 zh>_pa@LWyg)y;%-C0*y$zgf|lp)>*sQ4GD@I20RRL~95lQ-O5{LaXU(wTrroOLf77 z9HzjS(l{}3mIYr`o~oV4lg83M)A0*(dEYnCi<2nmdhpBJoP~rGz!x$%9lw~|efanv zjnM_KZhIHB+dDq}%*9H&*mzrIa!}bZl~t4IC4AT_vx$(Dy$E4?$03ORc#4p7PT(bm zJO7#?T627UJCux^>%hEs=O@|!@2NtyEJ6Lz#mQxrY&PAv!SFJ~(AqSP*rWFJiz@XM z(LsMpnsxU1(~hm$#J+AHcZzdyiIp+q&EZdX-5L=Q!DnJAJ8HsPb2yrlLf+uK}I ze=bZ-5M9JuBLtq-eIwpNNRe7oD@k6%N{%?>=x8lIz{%Gz9-+6n3wZfZ4{fHD>ThrQ zn(AT<*1I2rE@%bsZQbW%1L$)rQkgCFQao^EPkn|w!>mlzFkky z?EvkflOwZL;>s8S!Bc+m2S8o8zJT39UqJkE3 zQYfxuGaltmaJTc-ZkGMQ%c80ZvrLpvevpHy&W-oBWK<4S^+C*b9WpcZx=r6~t$HP# z@BKA1aN2WPWnST3sH!DzrwzW2?8@UpY^}dyv|wUDI=A-TsmgmY!51m*L*PeMD* zs{MZeRfR-z-i$KiE^Gs#D@f!MghPHY&{pP1;BWAOO5)%AyuvGXMNuIFOY);F74~#T zbV0)ktb?wh0d_FGg2b|rSfX`WkE0Rx?X^7RV2=43c^}rq?^mP&)A#U&i9+bz^=P2Y z`>f$qg&Fl99)u{0o{rRq+a!XEn#8XCImZHt>eh>5{8o=_E>~gu0ZCW$aFr-lY{20=~CDAo|=w5S(Mprftcb_8lY;5ySDET_ekFc1^ zW%}@u0GFw?HcxLbzd37&n$Ddj3mJLqF4jOaeWvh|F|Qy+yesnX#n5p9!YOWebT~Y= zL@_RIP=n`Nev#*)oRx#OFfF`ZF!LEqfKLo=_YUSIIyka(Z&-)MJ0ozVhUjrba7~21cfB z5B61U7ZB|z0W`xGTkCvfTEhWx#6)Iq4IwcfvpKEDYkd?*pbS(*gIc~Npw z`C-QE)lRw84M^A=&bN!}OjY@Y+UE_ZtnDVmGcayG_9QcjmSJY+VOD9QoK-;S(|HlQ zAdA5(X^^~6D?fKI?WV|SH27? zh_R{|uhcMKrmlFZT;;6(5=rF{iJ~%5$mFe%7>QLx*OQDG|9wKinqTdcZH*$Lb|sCh z1XCgc-Vo^nafUT)O@OC?ha!h~6GstqvrkGc^?jV%b;lyx^E%AZBW&mQFW)2Km}>$l zt!~FmU`PLBxe30Lw3Q?MDwlk(>W{$*(|`(5*!$@+yUyyk{{YJ=b?Ns(KcNh|gdxMd zONsff+`1AUky#KW6w%H;&h*(}K!9nte8UA%$~nl6sQTy|k|t>`0}oq&6UOJx|LWQw zJyw)^{FzW?Ou%#ntYFl#eRG3fwxiokrcwJnfQnA2XH7}`-ZhS~T#T1v)w(Km?PIh| z!E;@F4I(fPe}P@z*1_}bl?qw zL;|I<;aVU68!Se?pUtx(d`?-hl5!nTD7y#PamTV`Dbv&FYuga2^yaCOSw7aAU=ooB zT;#OeAeagc+_1x|K&!5%-d1bAQ4J&aOU@PdcCV;CcM{tKmPDXgogp@)15tB!T*}Pu z_AdT236?NJdj0NOeVRrrizt<`;yd9sqMW!>v2GeTRz2nfJ&o4+do!OJBiO&Dr0@gIY-jWv7Z9icwrk}FsPrsG7H?V%fb$=%H7FOB6q(hAlpuZA%MhL^)Y>X!ICz#qw5jzFI z&)JHA(P%PtVOl5I*?RmT0a4fGYN|R(td(Z)_7qeuwGFAQ|06_J&-@o+v+3haU$dtrbvx7T$p+qzOlV;m`X~}pRo-Sk_d_{ zv$|s~+|V(7EKucoiZ<$T*0M5-+2c&zu)gJy{~Wl>QwSfiDKb*Ky!>sSr0urUUHIee zyJ4PYpZ#vijG~UAl({uuIF8d4^Ma%hh^h^@h*R z)`0cZ?TcjNH||$Neq?P@LC3FbjE*9PT|yzsTuOW0cLnQp4&A(o@YlHZ}E+t!yms#?9fx%HOGUCxj4J zTnmntD#{rvY<*~L3I5oNc3EmJZ12p8gA}ZU*bKAdjw{bdvR!qA)iB!!0p4YAL`;pG zv=zIST`>{SGo)Rt=U`>7%&^%=>1qgx{iG<)D;}Ga4=d29M?MV%#5Gs?xPwMi&e*I7 zd(vgD(j_YY5L_u<&iS5d2#tzqUNV5{&)`SkGL$9f!qDllo%8T9Ph>@_J4N5o`vbcC zj*Y40%v)~G_oAw+vci8L&YRxSR4!}n_ogYb@{N~LW!r+>j~UbYPasi9O%wh#X+l#U@v z=PkWvEr{wGzmR(EVFUHM%828mMEALVj;}~Ko+ju>l0C{*nA|p3Up7avNU42WY|qc# z_*3ZIne95sm}OA4^}R5p#SO8+^4qZPl}fhZAo!kM!5@ed_|c@6a^q*q-*ZNtjvpI* z)kp#wB9m15fQup4B@j(U`9{?+*;DJ7?N`YW4bIYz^q_Gqz-x8mNLJZg3P^lE>6oe{ z=Rhm`x+Z?!XVkdh?{7mAO|@}T+kXJbve}NmI0>wsUaE@nXY!52LEXad#$@_4O*GQ^ zi6nGAM&>O{Q*Ms*i7JY3jeJD&AHY+&=#m7NH8}N=?Ap8T6%7iJ0zTL$QXB6mPP6p7 zoh7Vno}CW`EboCLLjwI*>7=c*bBSKO&P^_FC~_iH-9DOrw|<*d2gtKC@nlEvXli^$ z#h%^9#Z9Xf#Z4%+3>x$FX@)uyvPE(XHVy%eBG>Sovn}&gbdg?}NF)2vwrl9dpbi+b zSd;x)efnc!Snw?gD{gbH(Z05RvV~H*LKe~cOUoUfptO&2B!0V^`<%O&mFIY18Dv_X z9p#yN4cEZG41mMh_B8WO^Ie@zQZ?iepq@R3C`GO-FO7%Ghdp?0e>J;8nhVV{EU>*_ zQr4m93JVJIXfTzTwg%fj%=w>~MEM*Cz<=0Xt)SBuRy(-(){-X!Zsb247`d-jt#oc& zmFpX(SQ@_m+t{p0_-e;)(Kp_ElkC{UYVk3X@Rx?dR6Np~uQEF5xYwc|lWDg1Acr2D)J4|^}?re-Rq)2x@ro$JO$K!s3Kr|6N zH-bT;K-XFrvmgfW{#t{(RN=t;e{QcLzYc1`~CyJqUR_@ zzzzMdfsJ(-4>S2B+Zq0YBUQ=O^^k*uzC{_5fx57eTs+hU+Pg7U$U2c^y_xa`IH{uC zZXpRY1P9AL7y94Mjf=O$-IybZ;S5g@LF{;GX5Otg5rv=1t%J%wMKFZfq?9rDmA$5J zB=-D%6i!@n$y6}!Nfz+w##tDI2tf}s(w#Cu&wxFIY&+He04)-&>DrDx=g-77>?zl$ z1rftX@dR>}%ldYWg1n@H(E|U*5l7PKme&PZ`PYW3hRb&9T}Os6Kk$tf>jfpoe%J+P zittAT;ab1BwmrCNwp}3JEzClK?(HN)M(__stFptzE%i`Mlu1JM0Ea4)1{nnvF{x-5 z%$G~OKjrkVL=ar{Qs8`~1f&~C_W507lRgry~ zY&5Re{M2-VnPI-=l8fADK0)0w&e4%$8(_1+=`8Y7g{AISwl+O6NQA9SR%nmHCTQ3j zNNTk;q1y}2NSm&p%b*C@=7byzAUluOgzwpudsL>AwFJ}ym7b9pU3w@^&^zEcnl2Nbc(KNrPSzoHSe8G}BvCte0gVF#b=L?}@z0dS&ytd%%kd_AjDEY<;LgHbKB0;n~f=kk;jKBWz*j@0G ztzy|dZ4g8OCg<$xF!YK7n57OzgQ|Sm`FEY{`$+2{x-C25tuAjkR@-nEbl;LJ zSk=;x8R&Pl6yp%o5z0twiNwM1$p;J!#?UPGYmuYMxjlvAR4jMic@H`l_E+H@(Ze)0j3VaM?i`Kz?V!dK>aE5p) zXO)il?u6hc^hx5p@3yRYOl}-dA5~w8G&yUncCh)Nny>|+Tf3RFxNyNcsA5`?Ht(}> zMWdf6o-Oa*4GzEh{01Lyf!>sQ>05*G9MuJTI*htb&UD}6QPXuQB}wao5Cj!m%(Knr zT-q>VwB_!IG);Z1egEyxRPy?Or_FAm*C?1+h7N_I$jKxzS)!|2cm~>iajx z>p<$c-c>cZz|8**%LY?uUC>XTGZh!mYCbLx*8YKCF>%01Rmna=n=;2-mPsWaC^b_Q zvb>;0o?mF(eEo!KaXv}AB6RejL{+5rE7=QQOY=R1|eX0f6 z&k_w1a+e?E_4Kn?yz6R7pPocrc<_pIwwNhFqe-~9#XV1xy757m+OXLw0vh=<#dZ%X z(GBmfQsVGp6^jRj2_&{oJYIHj$=VO^r8~t~ua&1z&$6qIPO{qfjm6!P;yZ1ylm#~R zCYHaC%d6%q9)a4@VQV*!u)5TJV^g_e+g^n)8meG|%K(~=SYo8B#cF(Q2lb0}N^g4s z%KocIjuKvU*>RWLb4yZ>nxPX&==X_nLxP1>ROxb)+d-0)O-FSnJq#i-rCc)Yi=3bj zfZ5=)RXw;q6X84@b?L!l{MoI^2^oxL?t#9$_Vb=)UGF%lE%0w*+sh|5sg0fq?|g6M z@k^{S1>W0Et33vZZ850B$3XKMGFEF%GIlpKlaF-rnZ?ZiydDZz87FuFAPlu#bd%{~ zFU+H3^HIOe1jbg&j#PMHBo z`8GZ00DS{SER~Iuoe`jv1Q&a^`&U$L-DH?zO91uPs^_c^yB#wXda~rdY5WK1Q1MLH zQ3nVwtyd^mu5;*ZhP=Xx$vrGykBdz-dAPaOV)dxd26!manCmCoE2hjN=rjPa&y+_B zK!b%e<3_zY@kEw>a}*+1riIGfbkIyN`_KL_dc>C=5i@4kd|B0~q5gVx$aH0>!3X~C zswmlPgDRAE_yj>rzLy{nj0>J5YBEO?japp(1CUvU*#WnF9CM(11aVp>cmDf(Viubj zU6!wR9j!|dk{n@T$N_~|PNYl7;`STA1H0`sdUy7fn@l1h>Mk7RxBh$?OueXxR&n>h zNww=yeQYFe8CxMcy3Qr@Q#=f$u7NhFm*NLT$jKo#3tdjwH2=l701D(PmVt3Qd*Ey)M>tfE?%!=mqxQKJZXdi z<6E`9Gg>-KZB5j%kbRG=UGPK{j=D#$(~po&kC8( zC5X9>3a75!J)2BMlrbAIS5RjnpS+l?_tKB0}oM`2vAgDK^Z%uH8P_@PFFaE z*E|oFVu`V004+{-)3Xg^?{z(Xi}M z1J_aJ(8KNr2mNjpozMSD&;q^{2!7n38Xh<5FHf3yL;*CFh*7{dA0_prK`Zoxb+K%s zC_2H%o8~@_4+G?bCP*$)$kU;7yB;Dw!^8OpX^=LKIO$v%oMy|<`!`j(ZgL+A@?|D$ z6&20STiDQPe;|a0aDaZtYs)KOXG=DJxpTNaTbADsA52arD9{8hR=K%C0-gAOjtEDG z^x*1Pd$RJ~o_w5@&F(rW`q_1c^$)!@`_w-3!q884`t3cEm%2goV#HWwMbUZX%v8j# z?H$_>>OwU}n8Yye`EPu>G@u}EqCAWKye4cs$O{exC3sHSn}%5wx7G_4E8Le5TIz8V ze{b}SETa8t&Ft?F)po7eQv7_y?Bx+v@^-#G_F(9Ct!;_}V{liDPO8UtjkSr1S4ocl z+i)}X);)kzS$zQ9C_D_3>Y<{BKkW=CG4pm!2ZQ6T;lG7H>MrGcvUR<4`V_rtsHM|w zl>DV&^I;N@p4<3>l=&Y({P3FUH>xc{1w*C0uqWBG%m-%L7XTvHho|`m?=es8qbC$1 z!JWHrx&xXCrC0$CX$d}dP(|a!*Q+TlKlqr1>-p`Nz-ccJ@V=sf-=WQBDgi*JFUfES z0~zoOWtElT(Dcprbd_<&)y&RFrg}cF(*(7xOh>J6<;|qFECnZwqE;)u(-An%LyWNM z;+w-?+3;#OVvEg)c9U&(r&$vY62w-7LTv5(cvZ{izqkQhHCcZOl^pn;=XZ>!syv?+Sd2oO6{&dCRXR$-1voG6STs8i8HA zW`I<*^8{P^Qosk5H zvvBq8Wwqpyvvx+|?t24*=`?PyjT3?ycRo-y`OCAGd;p~ipcLtQj>_jz03OvIukz%_ zhCud&v_G}RKGPo8kD-+V?On`nOVmr5hF%tQj6D8}Z?K9=l?0lE8g#eFTAfnm4rl-1 z=$LHs^L}(iE;h63HhN|06495NqRDSmY&L$t6H?&8cNixxVa531P%iSduK36Z^|&L-Muv& zHHTa$8O_TtE0i{RF^PkdSJx&fR$@}ZogEpTW}fN|C=xZ4OmRnht=mU_eda&@;4AC})i?F&DU)Y#~@q(CLX79Tk4 z9r~q5-<=37IcFsjmBU$<&PNQ+Ku0v?TLO1#yh3cFR1o^6G7R_6NbeF1T8Cwsk7eii zN_{FLKMY~#fy3fjj(lO$A^{3YQKU9Iv*`^eEzs?g8Wvw!s2akeak8iG@#vmnOg6)w zDQviqBH!I%@L4M zoUStoFa2mLjGz3JKO$s7hw>}xw5pXNXlKiuc6dKNW1 zk2t9Fve}IZg8-uMN8rIJi%5GB*uw&ekb~ScAtn1GVXeU0IC7b=h$aoqGZu>$n8=`u zVbCGeIw-(ZLy>?Edwtg=m~6j}h2I9XN1~t#s<9H8p3i@hLYGCfy;fz%3gA{hp`%e0 zo9>>vxGA=Ci#L2R;zJ!mo`H#7w`8OtHzQ>Ee!d+H3MdkoQIt>2QVjvbPOWL>i}JbO zFMybayK7C-0{eVXoQOrnn#2?e;1OCPF-ptqgl6Qi1b$c%GEQ9; zrC~v}-K{OC6zYx|6mZG+x1tHUSE9?=I(|$1(N;sqfOSwq!JUhWv}ffmo*t=m1)q7l zU5YwpOKOOdZF`mM$%G=i@$g0J`AnoLs{>n|dw_jhYyNvBqr`@YAZCvadl?Oloh0fB z$p}tZ;33P4n7&ErVo^)s*D;0v(<=nNJLaBYUA=-3<0fv7eR=`GfTH~~3#0z#2<%bi zs>)UE?8{<)!Hw8NAul|kc8vA`%t*_p^~VBWm)A8_RpZT=(mgrNwc(90zHONfn{q%` zj5+>mT!(>}y2{HcriUU66js@pI_abr4c%nhD43_={#FpUkcX#Ux&+57Z!dKD8p*j& zeQw0zXGh(X{V+eNgbYY3H&7Us{~upW2%l7&)nt9rOUB{Rxj)H%=R_Fw2 zmn!kuZZZ0YDP zCLxz8mBHC{BFH70S+9P=M54E~Lkt?|iKZSTTI)VC0%lY_{tW48V0~_~7{cuORWIL! z5B@z%^|_qfq{q(!ba}0vX{B3*2xeDy3FLfav;LZ-E!hm5+2cqy5E8m^Jx&U9|i z7M72_<*}M~IXkcY6>&rRFr&o@Qq7~A|9YmU8=Tz&m38SC{|n;qUl^@udJ{e$JkSS& zvW)Smy&#KNi>xEAgS6?b#|29xl9k2H&;@U>X){?Cbo4KqHi)Lp7{#jN+M%-gGdW0smx0BQj*inTgqG)PZCr85`GGRY zC<=VlgvkOp;3fl`jg109GE!HfulDwsg@qi{Kg`cn7!FaJQ6=}mtlcCGx z7!%Kkuz+5S2M0gCpdlwh#d++i3#n2VU!rp{%9R>64LhBddCBwgnn*7;hK9*^gYHKZtl>VY;vGX1L}B zFUgOp@K&wUj?gB%ggTRYntS+bt}P!YB-oc05RUCZHf8!dN3sc1I&S6d%qId4C1zd| zSKXTd*6@B1aw8#}G>`>!^-?jD_~pTOQ*sWygO=lVNsNiTtOScfkreq_9fbJI@t&wi zgd%fK-D#@e@YkF0_X}z1{_j3V%eGF=)VgK=&I}l9=q&39=#B=K$-ccJLARYsty`84 z0G4i{;hmN>%|t|Rc@tS{YnqZkJ{7lrANT@{2+T0eUigKgE_Z<$*vWwfbi+)U8lfgo zH|j&>1l+%NVKX~`2Pb6Gxf}i=OWRtC_eE92uJhA<<518v<~qM zNGfg@f5bu6z~l%CllO{VNpe)v#T_5#a;eiE{{U<;aA8&cr zWJ?WU5~{{4GLG)EQh>o%648XbOiLiVzz9ouTGtmqN9 zsM)+g;bq>Trm!yaF2DoKxzfGWK?JLvX7wrY?Uz`rc2sl{soZ3sYFlju%+AILWwivf z@P@jV*~AnrR@cl_#u%g6neskmjU0Bx45t`PL8Za%F9waW!_;v3AyIb77}RoKUTfk4 zmWxk-H<#@VzZpP16~D~yJy>!me$tE+xI^H8Od_mMjbVOZIDUaQ%viH5rvS~hVBo%Y zH!!NmAT%l*Sr&;<7!R74V|4n3l;^2J#-BY!?f8agvRw_!IlTCa1%n}Et(XYzYzxRn zU8~$pqG0>YD$e7OMr^O{6Dx7KLZhVfsLT|~uf%9yj^{G-`-s2X1r%RUvkHpAl|xiV z7^Y;k_?3qk?l+OQ>HyRO``i#lQe~=h@d#2{%#|=PNJke;d2RWMvZ+O_4S~lQhP+vc zGu!wjvLI{O`OSyK3DP=Tv`Uo9^ZuebEm`;f094N5tavXjIGYy*T(F%u2w8wkrg2^_ z0@+wI#K|Av@8J03Ei+PY6u4)lEz< z!VPUyWz9!ms?|V87j^sn#g$f+HmQgZF}swurcMY_*6&Ozn?B$I?)`3I71qWfC?mz* zC0lnxsPuvH2Z=t>B{1wT%i*U7a^Y2P23XP^Gc~YH2p(o!D_bQam5Ex_5!I2qw^3Ub z2b$b#Xw(>TTqc3|ltk3G%XyhY9bSGTvQFxtd2{Xn1RoO9)vL%mSOREQUe9k478Tw+ z#?=eJu(+w99Whw>fi^mq<6}uvelfW~jDEWrWm-1H-O|C#w;qP#9?z0NL z&@R6sC{k;gou!=o#Y&V{nR382 zALcc3EF0cGeMCbGd!Y*;cuVbN0k~$mY?<8Eq%of{wU9bss%oE5S!JN$6apz=BWjW5 z`enTRp@IfQ&e)fVbJRmP+%_)!Ooo$d9rBi1vVk zMS~vY;^bBu$+w6gc14WB>P6D(EY-j;p}qS50BSm=yJGl>#X5i(Ri)xBOLXFziUnUa z)Eo3sbnz*o&e_Nz?g}a#tOAn9d4)ol9lMH!M7&J`9Mt5SbQLXi1O27(n4pS);ZD+N6{v|rvhSpe$j`I~QR@a$Y zg%!Y&Ay?T?a1lz%5Z|a&V;}wf#cZJmFv6(}S@81>#_ha>!v{9qx_EvXejza6FJWl# z%a@8;h~SSLOPBB&ZHuoF$-YTbTwb0Tm8#-cm>a#tvvpWbVM~Jer_8G83$~y_Ta1t{ znXSSMa-R{{Q^D?8y>kJK8k9{f!COoB;wnnLd10`!opUQ-w3L}+aREz?K4OZ{_TmIs zSXLt)tJ(yVHqFD}2Q?JwUN2DC1^q^bZ2sWDConX#E0PceS*jwCsI9XB1;;RNF#wD* z;3A7$_H`8MiDndhY6Mn((@Sm_q2Zi`XDB+Q>_Yxp3ki@_a7vgQMZ`_O?geTs%M7yy zD5Wx%V%1?L>@ecD_NHLCP!BD)2m)Vlnv&IFBqT7Ya^mr?H}3wXf^{xx>!KOXy`c4} zYz!v};_%}-rB?BWY}=WGQzS{yXsk$SFnJ;d_)qx zuA&y3>Y|jTV6IS?(yY|6Wn`$Cv+XpBzT;VVgLpG6EpFxem5%cT_!uo0^A;+}VBU~I z!e)h*RlaTE{KV)uWM23s@*ux#HBWk+HpLCpFjjQ#KY8jag8VS~)y&Cj;h9BW#LM)j z5s2ScnDTU2+Y>PrYOje;x>JZ(n3s)?ArhR9B`(aSi?qbpS7OYh5+;GQU*$2ZSic?4 z1HbArl-mx;d`hT%3v0$ouQM}86P&~zQDVZFe((vQqAkt7Kr;~T=9a+DE-GThOpHDc z*i2iq`k!ll&_|)pWtmx6C4n-mtzvGixrHuYw8X4mBxui4tIi;+9^`b605*4f zmKCV;h`F0B%^EpFL5XS<i!dp)B?vne8#9S6vW*(`CxXOnfDgLFMz6mTv2+= z@*scqW?E3rVGTIFuo`mRJ;wku6`Riz)KMDs0;@H831!;0xF`j7xaP|=QN*QKQ_Mx( zRc0}4g;n^7qGtEzS}Vq}D1|9snQRnL-NujkGqBI`D2a06fmC}hRJ2bHcLE%++Rq|E0nvB)m~%O)mIhF$ZG1EqxUKjTiuB(8mqrV<`;#TxrflQXs`+@+7se>3`Ck6?U z+|(-qk1cpS>JR~P);r_nn}z3@$mYDo0{0ZP)t)0ocYTcAqOJ<_cFYLo$k?p^01@cC zVl1vb6C-xY0l&y6O zt6ll#V5srpb4ogxXm3#AS8g-7O7U}uYU$lT2NH#c$t%Alv-3Gfi#kUrv^nk1^A;Nm z)LzMEkBR+#;kOyw*0qeq46#+>Z3U{K`F9;a&{>P71W4rHdz5X3`w(n3ajA8=Q1O~8 zyaxQt1e?XYgEbiTredE=#&H*AWDP<#W>G*?1G-h>?uAw>Jo6Ql*tXrwVE!UfR(ZZ7 zYc1Ab7n0Twa7Ed*uB9~!G{JTUIXuC>6U0WU>FH-moi~o4Y@zYFmV#d*FPVXeDYuP5 z`P{b(H8n*FtV3YrY2M+gQO!gZZuypluNaj9k>EIj6m8cLDS2~I(?-ndDrE^^arS{u z*Aeip9WQ3D0tn@p8#@-sS3&)I?3+ne!INu36fb@=9oj>@H>;!MNJy zQ04(D7lRLBpbfEVP*KpZRsGOtG@)XYWH3GqADD_plN=A2_yDxNSN)H|gACh1n;7I7 z%zFpOhufZ0)YMwJ2?`{q+dSEvLA?9&AmSzXE$TUAV=TkwLLc+7r_ z+(MT8*D+fm>|a^wwMOv9rYmN1KgDDcDv7EDmGe=r-^EGlz^{{Y0Y zc#c zQ2+{+i)CsA1;KDSRIr##&m;oYQ8=JxqA+}l^m&38CpjKp#ATT+F77r`zvQ*xS82>c zKjkt}M|D!$b8@3deKEy{xlToc7lXHOQl%auZCaGW;#F<|wWH=fwyV2Qk5Z*<75gA; zox;V8z^73(g$kuW_vo=*y{{S%rJ>&BLxF%okF`7=>9j>3xiw*D;|N3?wer7=S~2P2OH*dZetTLlUj5Y-%k+(n4WYxR%1dFcK74+@Z8OyC>Y%!A1&d1aKj4!Jh z%ZCK0T6{|JP}kA7D5#V*=C$&5?ISa4!steqv*pSUz+Sud&OEYZf|DBV>>64$ZCuD>6dh9cC) z=urv|`j(G&?6+UUO1uNEBc)YwqVN)sg=5~ifb!fRT?vDj`L@6Qz(B<-jlb-~wpjHR zM7qH)6foB$Zm-Qp9)?{5KNf!bh%L7;Xbe7M0-f#(&0^*u<_#7ATjmu)v(%_rywoF$ zm&5K{PyzFA`{o!?sMX^4`Invm1F$jtLnfv|9cA?`$;u*&A=`psy_3rWCz}3#)mVyh znvURN15vcFFbEwVsHnhODb2L>>VNedh*@9UYpC02KhyzcmywNN<0r(j;HP&Rk(ax^ zVuW6K;st?J3L{!q@WH1i^A(I#bDQH+b&}?8+l{RrC6=r&m;j(x7kP;&^F+38f##!s zEdo6b?p%Xy3B&-#j^Lm`e&1)Nzf7j$6;t~j|NfSP`ttSoI1QLR#{=>R>R|>h}twvSltBC4%0Fv1R3*lI0 zzO*rByDgZ@J9%`Dy_K8*&jH>NdEHM&kQ}Zuz_fTSx15vtO zt1_O;+Q$iXYUl1?j>##n4{;VDjeRfiF3yUd5xkHfoh*<_tg@@QWtDCslRqq4SyA%G zOD-Bm#GotZaZn{WF$JeyKF}(Hjbi1|pc-WbZ)_U?w{sDxEY}gx<0a_gHCOz?5mYNs z>ImZwPk4$J5iGATs@5Q3VCv%6h@r1ETNRIGS+FFGrhxHu)H;}?ihI)P{s&zzr-BQkKP=O5w#9yB8Z z!>PxaxWFB~!faaZGt^r7#JxJJEz6@7q3Tv#hQR*-f36!w`VMg&8PGhyaq@oYaYzgA z%&!+Y+(mfNWf#P)0kw4vmoM7}JAu~ig;3JULbrDi{h)Z(pW`re9_msvqeBy6jqRBL zJ1bsbh^ovsYSbuzTwOfND@A-%EYp01S`62BQKg(BVL;X1E+UHA!NjUJek$M%X{}q# zK%&#ja?HAeYl16KMfsG}juuOI4P9s7#LOtw zI)W4fX4!Q~W$`dCF69x7jI}b-n`H}K6?%cRVdhjVhWok5QbJmCRKa#xETY|&9Vk(l z((V`|{{T{hl6gm#(+RWGEkOY2h6P;?#I~9YuHYzfC?Uk4$qKe1)F@!$VU)cyn*cjy zfikr|-RwJ=g2gWYPVQnJsa%KNQQ5qUQp;5X02O3YW>;n6F|a}|Dp=C*{KuiDEem?o z`DYgdCBYBBFoboUM*jdZiy3PAORBu@7X&#HsGFmQ?J3x=52*Z=)67!d1W+==#6QhS z5C}RU-^4>c?=fzbh6m31C^D2N@=!e+^2Gp927;;IYzvsK?94y_H5{PJsG{#@ycm58 z_=;_LS~#03n%%*!bFq!4{6N3ga*(U_6s%Pj8n44?%O+{~zO?A(R!Bv(rn<>|nfwJ;hnSf<)@lvuSp-bQT<@f>GImf&t2&><2 zDiY32yp0sYxZS&3VbeaP%cqG-B$V@|on=lwNZl+3+A52EROE9IxuPS&SxaiN+#(T0 z0+#fh4x{>K4duvnU4@mM^-DSNw=FtVaCi@^>sE-cc>J=H(Q=?khwS znZiA~eLzMukC27RzmhisJ8|Lv%+Hrpys-c`DO*srdN&4_d4Q2{!kN5 zOPcOJtXK;!HbaZxMhN5Xe?nDVW$G=D3w^u(@VLr8u5MTZb{{2dEZs z3@5}x)1sxDP-i-eNQ!eF&)NR~c$cIFVZ`Eu=H<>put%(=FHi-img-xQb6z2A3=8Dfn%tGqQt6amdP~@mc;$mgrQl=M&QQxUp z?hm1HrLnnyA$7j>(=n=8W&~japHPMTk@_OPh>R@lvQ&dq=jKrj6}57lexb94%30=D zXjaK*!>NFnnh8e)3CATL#AVA-w|O4AwxJsljOH43bjph;7Q!tl{6tG>gH<`(isB7A zN&|qwN_i0v78QaB^mAO#1kAx1)G!Vhz~jbcySuqjy$#LHo)z&6Lj?Uqu&WnS8CMNe zRT@0SV+7c3U3h>MtK8)>=3ZE5#MrFenMH8;bfN4$K z9ba=eZhm7_v4$&TsVi*FH)x~aV*c`BD#FVw{37`8vNfepqvSxM?#LG zfi|Bo|14YzI^_b+=VG#q+^X@d|K|%ph>rvc#Eck!{ zII2_(6@9_0j=pA0(!fc6e9Y<_x^WpOFL#+;MK-I#!~oFk6NsTzZReQi*4r#oEGd5j zGdU`c)YaSfE3P8WxSV+|UmFM#<^7aU!`7(1_&?cN;3{sDs3$ z#eD=Bs8|(0kbk(C489J0^{5$T!5z6fsG?-I+jlp#QKDewzAK^P~k@QI1k*S z1Y`&I{{6}_(YBuvVIxf`1_Ei$#xms~RYF%c+%}AyjJ*r(EMaf&1n&>#TolDCrZ5Uy z69`wydy1+ud(5|Hd6Xf^<|7EzTvZqGJr%`q0l-$+IW1CucTBA4IN2F>K+Fzkg$I@*bzAMv?g7<3L&9H3ZIdJ<$P&85diMpR z?zI$*qm#Jld?+q7ETErgh=$xwZHvD3I97!)#*Xy(jVLCSb+X{|5|wG66FqF=TG>#( zMHR^urG^Y`26K!aU^&#-xpxR97Z<6IY)QId2tvg4kv5pZ9XgOHkAbY<5u^3fY*W*Ku3~qd1;I+runFjJoO| zS5d-+nG~=!eZzNHd0+;a7QH@ZGmzZh)OAaiftNXskYkvGPueGVmnU#m@!Z%{E0`E+ z*ecwD{_MHNI3=xa%HN4k1_jahxabSgjmIk6rwkvMM}fd780xqUkVG4E>RohYh6*cu z%R`Xw&UWxWcv&wOsLF;&a7r$c=5z(E?r^X-a6o$Ci~wP=P8oF=4K*27%$4&AE5F2` zPAgLqwi4hrT?>{$4XNaZ#1$yZ9snb5>Nq;W@C2ygLpf9#nQN>}(ok}Fh~P7IEZQ%u zT*@lASQ;m+wk(o=6zhBBd^B@_WJHDFk6#6^PS6uOO?wF+*J{<9k{ zLf9&@n;v4;Qc(3Osw{VlfUq}I5KILMlqD!P=2(Ub=3rNHkCb&wVJT5_AbVP)(6H%_ zd1J4cUd}7i9xIt)8?`ijiD*O5pDgZp!xJN76TH6Vrm2Hrj#eC{qp3nQdYOg5ODbA7 z<^o-Z?nF}A;FQ=XMC?Q;tO{=lBTC$JnaSPE=eRZESmY`qvGX_P zE9Cf>+6?-gFtONtl@g&AThy@_Ji=KHS^offju#TVo>_XbQOA3jeqgUNsW2Tt#YJ3h zP-loD#mvfEu^eG(!MFex+_j<^p|0iRrHZ&#AeQE$*Oi2=f(sZ5^zM}Yp&CCZtpQJ+ z#mXlk=K;#_MgV&}4tOrG54c4Ut{5nZYZB({t|RKVmqTxhjqe=J;7XuLrme+;9dlG`*_@U9Hx?F>rXz#x@3(9&7u6E8*mgRKw(-;$pmm2`s&0 z^AlQH>6o!X5mK;Qx7UzmQN?UBK^2`;Kvv706DV>ea8OG*ocU8;`o3zxyc-CTe zeX{psUS^anolC16kVKsZWt5|B5#FAqkOJGb6sw|9>bE@sTyqRodLflg4B{v&2ksOW zJsXBZG07QWlda4{B5qfDnc5sap}v$z8b(v|s zkg{@dFr^uKOUtQXC*mZx;y(pKgwe^UmZ!uPjZx2;nM`*L(aU5gL!jbiOzvyV`pi!N z#J78SgFzNp4_C|-!ZoLND$MTs+zyJ&rJ(zb^rgf{Mz;$Fv2oJsqiYCRrtn!~`w(hrxz+PdbxP}z~ zEeyW+{6QQ8j;aRLm&kV?Q3fsqN}M@`*yV=ot-{zP)^epg?Kc_)n;d>+7aY?9gaaU6 zpbE=;)DG@blJYX`U9+gq7twl;gO+nKw6*sF2Gn_tuIem}_C<8nFLBE@x*&l=c+3%_ zUCPB*)Iku#R}euQ<~eRUt|Jz=GwCi1mR!rLo`Z8ibbqlaYYV`!=ohM%4u7Q2Ys$M; zDJdwRmJC#=;}J$pO2~yozyr)c7kml3GreXY(R9S&mBT#`ZXg@4dV#&`j?c&u)cM_y z)TPZB1_Lw8NZ(SPsqShz>_sCnN1GTikzH~*lsOJP$D{#7fphajW`(w^mAJyRtBF9) zYcj;QYX&)%u;S^$LTMCc-4lqwEQTx$u7V`#9I_$}CDcv<90WCsLTCnQn2ZQU$tgA+ zO=z?}ceQZ?sOD53Yl_J}U=(eMk(~Y`%GwEZbGVolX6uL?v>Ra4Wntz8tqWfSqE(hl zus5gy(7CW~v0m>Kw|``VO@fxFH3ph*xR?VFDV#(ys<)U$r=~F@Z&9hU z5p68bC{Bu=5!`ufioX%4>R?=>;s)-YnaWrlcOA+H`MOaC zDR_u%A)VC8U+y;xa>9o!489_&yj;%((J&G{)~Zqco|wq-Eh_##(W6niy~0qPVpys~ z$QTBU$2mL1>-;12D~i}ha%rqb0m;EoUPmNmm=21K3JHrKR#Vw4_exWAS>F?RHK>g+p6QHbTJ2Jmvl%5N{skO@ZNOl`(WY#@$KWuz>W~ z{7Rrb=FGu^+LwlZpkoZ<_Y?3acvT<7E3mGjf?X9dX_y>Cx~ZE4 zB(>CP5OyXbe9+1zoK~ftIl9acG9#$|Zf` zmmzQm2bp@+LljC3*OsPWvpFBn9BKfK?LXbcA*X4@`-6x~Cp()!EGg<)V4;|>!-LtN znG5Y0hT;fz> ztNVpt%mVwZE_}qyOvkIo6N(u57CwmYX}%%`O?7c?9A-ODlv`bnCL7dI4?I)@1%DGZ z3^DB-;>Wks6QMLWG;6EsHgd5CZdXBr}W${SKp5GW%dtg%Yg<~2k4hN|woOKUC7 z-EZ7#ZvOGL)?d^Nuq_epD6v+<)K6pyrFe)Li@V0+;)!0L1gf4Pb^Dj}1;D%9#bz{m zj%Jqx{?kx5|2zfn9@ZGMJa8TERob~OMfccE&sg@2Uygzwg6pF;U0q8(TIl&moZLm}$5SSa1^& zE;mZusc)LI2A|0jfmmt7BR;;-imEo70lS(-K#4(LVC+C3d=j9?_YB@eMI`rE zr$jItF*cYR9oASCa!hrIkyi0|gh+=c20!er1azVXjbP8XE#$bwx;`@$6UjBMes?g} z2BNq(`IjA?VqJkxFH*;y(H)%Y7RwxufYMs9^GmoI(Vfz0DI)9n1}7U=MMQk6TtGFgZ5$D)scle$oJOV<=ZKqg>}oD*{OdB2qxy-l zn%rtuy&{EH!k8}Ac$U?p3WgRtmqA6yxGJvU75YIIS-n{=P7U~jWmdS9sL}bG6teV+ zmg@B{pkCu;HsPqsfnv*L#d^dHTT}auT{?r5IGJ(zWxIE&NMV$DnKS#9wzVycVra&3 z4Pl7eTbJFk<>d^p&jABMs`<84ZH+F;{6!)aE0zA(lMc*k`;D-alE+z^FYzCY2zD+| zurON)P(WLWPKn;7cTqhKBG90Lre5QoV^gTO#cNc?q)d7GKvJBL2T?Le!H$=fIr9(| z6|0*oSYtjy*if}PbIfUe8;zq?@f!uUvo8bsT+Pun3(y|pqf|f@!K01FgVW|ry&i-vBY z_yh-OntWnqr2_~cOm@nQwqnyu-f9|Z)og0V4|vyC16v!kfyyYtzS)&`VqpOLo?@$Q zfvJOZuTiVB?9^siS}x(V3h@+7G(@E}7`MxXg-1K?D~Lown&UE;gFm>bZgDM0Vc@tV z=yQl@ej13?uNRSKnp(7#4C7&$N(5!a~`2afKbeV`bP6zcLdPt8Gp|*@(+p* z`R}H^kSieb!r6^QHmOl6hCKk*POj2R{k5DEQEv&I9#@io?AnP<>paTP>8#{@~k zSehkDR;p61l&)r5sDcZ2M7>7fjZ{T5%&Xi-X=7Yg|%{xp@ z*u+~c>gsfQ=m}u0?48lhgW+Q>(;w-0l+}H(lL4ppa z_-9}0EoKF%6GmV*%MWlWWxA9NK=qlqQj|(o3Bbxbnrazq=m!3S!eaps2o9h?xm7Ln zFv|w*XF5BE(c2dQ!_)%2t1W4oC8uh%TPo2zJ7w!I$yt?DIO++u|X^d{4ah=t4y^DzTf;vD;&vC2PlaWV?)e8kRpiA=800ae2`87!LI z8I#wkg-aFPPJZzWpAyWb1qse-XHDI*s)1|^31_$nenrgi)V5=YZ6Gl`P@o_n8AurS5h+m! zsDz{ng#jqJ)|6UADiQ|~2nY&NWP^Y z=GfoNR2lVO2 z6m&+2aRHFc@isxRZC7#1&R_#wB4x`lwrXrdCEnvL7^q6aCU*o3_=VbqMkNhO5nVt$ wKpILcj-V)js1>P1Lda?XP~+)J)HMLPN~z2RY67P)Dhz!OpoHO^!co-!*$upTsQ>@~ literal 0 HcmV?d00001 diff --git a/apps/docs/blog/2021-08-26-welcome/index.md b/apps/docs/blog/2021-08-26-welcome/index.md new file mode 100644 index 0000000..349ea07 --- /dev/null +++ b/apps/docs/blog/2021-08-26-welcome/index.md @@ -0,0 +1,29 @@ +--- +slug: welcome +title: Welcome +authors: [slorber, yangshun] +tags: [facebook, hello, docusaurus] +--- + +[Docusaurus blogging features](https://docusaurus.io/docs/blog) are powered by the [blog plugin](https://docusaurus.io/docs/api/plugins/@docusaurus/plugin-content-blog). + +Here are a few tips you might find useful. + + + +Simply add Markdown files (or folders) to the `blog` directory. + +Regular blog authors can be added to `authors.yml`. + +The blog post date can be extracted from filenames, such as: + +- `2019-05-30-welcome.md` +- `2019-05-30-welcome/index.md` + +A blog post folder can be convenient to co-locate blog post images: + +![Docusaurus Plushie](./docusaurus-plushie-banner.jpeg) + +The blog supports tags as well! + +**And if you don't want a blog**: just delete this directory, and use `blog: false` in your Docusaurus config. diff --git a/apps/docs/blog/authors.yml b/apps/docs/blog/authors.yml new file mode 100644 index 0000000..0fd3987 --- /dev/null +++ b/apps/docs/blog/authors.yml @@ -0,0 +1,25 @@ +yangshun: + name: Yangshun Tay + title: Ex-Meta Staff Engineer, Co-founder GreatFrontEnd + url: https://linkedin.com/in/yangshun + image_url: https://github.com/yangshun.png + page: true + socials: + x: yangshunz + linkedin: yangshun + github: yangshun + newsletter: https://www.greatfrontend.com + +slorber: + name: Sรฉbastien Lorber + title: Docusaurus maintainer + url: https://sebastienlorber.com + image_url: https://github.com/slorber.png + page: + # customize the url of the author page at /blog/authors/ + permalink: '/all-sebastien-lorber-articles' + socials: + x: sebastienlorber + linkedin: sebastienlorber + github: slorber + newsletter: https://thisweekinreact.com diff --git a/apps/docs/blog/tags.yml b/apps/docs/blog/tags.yml new file mode 100644 index 0000000..bfaa778 --- /dev/null +++ b/apps/docs/blog/tags.yml @@ -0,0 +1,19 @@ +facebook: + label: Facebook + permalink: /facebook + description: Facebook tag description + +hello: + label: Hello + permalink: /hello + description: Hello tag description + +docusaurus: + label: Docusaurus + permalink: /docusaurus + description: Docusaurus tag description + +hola: + label: Hola + permalink: /hola + description: Hola tag description diff --git a/apps/docs/docs/intro.md b/apps/docs/docs/intro.md new file mode 100644 index 0000000..88f9571 --- /dev/null +++ b/apps/docs/docs/intro.md @@ -0,0 +1,47 @@ +--- +sidebar_position: 1 +--- + +# Tutorial Intro + +Let's discover **Docusaurus in less than 5 minutes**. + +## Getting Started + +Get started by **creating a new site**. + +Or **try Docusaurus immediately** with **[docusaurus.new](https://docusaurus.new)**. + +### What you'll need + +- [Node.js](https://nodejs.org/en/download/) version 20.0 or above: + - When installing Node.js, you are recommended to check all checkboxes related to dependencies. + +## Generate a new site + +Generate a new Docusaurus site using the **classic template**. + +The classic template will automatically be added to your project after you run the command: + +```bash +npm init docusaurus@latest my-website classic +``` + +You can type this command into Command Prompt, Powershell, Terminal, or any other integrated terminal of your code editor. + +The command also installs all necessary dependencies you need to run Docusaurus. + +## Start your site + +Run the development server: + +```bash +cd my-website +npm run start +``` + +The `cd` command changes the directory you're working with. In order to work with your newly created Docusaurus site, you'll need to navigate the terminal there. + +The `npm run start` command builds your website locally and serves it through a development server, ready for you to view at http://localhost:3000/. + +Open `docs/intro.md` (this page) and edit some lines: the site **reloads automatically** and displays your changes. diff --git a/apps/docs/docs/tutorial-basics/_category_.json b/apps/docs/docs/tutorial-basics/_category_.json new file mode 100644 index 0000000..2e6db55 --- /dev/null +++ b/apps/docs/docs/tutorial-basics/_category_.json @@ -0,0 +1,8 @@ +{ + "label": "Tutorial - Basics", + "position": 2, + "link": { + "type": "generated-index", + "description": "5 minutes to learn the most important Docusaurus concepts." + } +} diff --git a/apps/docs/docs/tutorial-basics/congratulations.md b/apps/docs/docs/tutorial-basics/congratulations.md new file mode 100644 index 0000000..04771a0 --- /dev/null +++ b/apps/docs/docs/tutorial-basics/congratulations.md @@ -0,0 +1,23 @@ +--- +sidebar_position: 6 +--- + +# Congratulations! + +You have just learned the **basics of Docusaurus** and made some changes to the **initial template**. + +Docusaurus has **much more to offer**! + +Have **5 more minutes**? Take a look at **[versioning](../tutorial-extras/manage-docs-versions.md)** and **[i18n](../tutorial-extras/translate-your-site.md)**. + +Anything **unclear** or **buggy** in this tutorial? [Please report it!](https://github.com/facebook/docusaurus/discussions/4610) + +## What's next? + +- Read the [official documentation](https://docusaurus.io/) +- Modify your site configuration with [`docusaurus.config.js`](https://docusaurus.io/docs/api/docusaurus-config) +- Add navbar and footer items with [`themeConfig`](https://docusaurus.io/docs/api/themes/configuration) +- Add a custom [Design and Layout](https://docusaurus.io/docs/styling-layout) +- Add a [search bar](https://docusaurus.io/docs/search) +- Find inspirations in the [Docusaurus showcase](https://docusaurus.io/showcase) +- Get involved in the [Docusaurus Community](https://docusaurus.io/community/support) diff --git a/apps/docs/docs/tutorial-basics/create-a-blog-post.md b/apps/docs/docs/tutorial-basics/create-a-blog-post.md new file mode 100644 index 0000000..550ae17 --- /dev/null +++ b/apps/docs/docs/tutorial-basics/create-a-blog-post.md @@ -0,0 +1,34 @@ +--- +sidebar_position: 3 +--- + +# Create a Blog Post + +Docusaurus creates a **page for each blog post**, but also a **blog index page**, a **tag system**, an **RSS** feed... + +## Create your first Post + +Create a file at `blog/2021-02-28-greetings.md`: + +```md title="blog/2021-02-28-greetings.md" +--- +slug: greetings +title: Greetings! +authors: + - name: Joel Marcey + title: Co-creator of Docusaurus 1 + url: https://github.com/JoelMarcey + image_url: https://github.com/JoelMarcey.png + - name: Sรฉbastien Lorber + title: Docusaurus maintainer + url: https://sebastienlorber.com + image_url: https://github.com/slorber.png +tags: [greetings] +--- + +Congratulations, you have made your first post! + +Feel free to play around and edit this post as much as you like. +``` + +A new blog post is now available at [http://localhost:3000/blog/greetings](http://localhost:3000/blog/greetings). diff --git a/apps/docs/docs/tutorial-basics/create-a-document.md b/apps/docs/docs/tutorial-basics/create-a-document.md new file mode 100644 index 0000000..c22fe29 --- /dev/null +++ b/apps/docs/docs/tutorial-basics/create-a-document.md @@ -0,0 +1,57 @@ +--- +sidebar_position: 2 +--- + +# Create a Document + +Documents are **groups of pages** connected through: + +- a **sidebar** +- **previous/next navigation** +- **versioning** + +## Create your first Doc + +Create a Markdown file at `docs/hello.md`: + +```md title="docs/hello.md" +# Hello + +This is my **first Docusaurus document**! +``` + +A new document is now available at [http://localhost:3000/docs/hello](http://localhost:3000/docs/hello). + +## Configure the Sidebar + +Docusaurus automatically **creates a sidebar** from the `docs` folder. + +Add metadata to customize the sidebar label and position: + +```md title="docs/hello.md" {1-4} +--- +sidebar_label: 'Hi!' +sidebar_position: 3 +--- + +# Hello + +This is my **first Docusaurus document**! +``` + +It is also possible to create your sidebar explicitly in `sidebars.js`: + +```js title="sidebars.js" +export default { + tutorialSidebar: [ + 'intro', + // highlight-next-line + 'hello', + { + type: 'category', + label: 'Tutorial', + items: ['tutorial-basics/create-a-document'], + }, + ], +}; +``` diff --git a/apps/docs/docs/tutorial-basics/create-a-page.md b/apps/docs/docs/tutorial-basics/create-a-page.md new file mode 100644 index 0000000..20e2ac3 --- /dev/null +++ b/apps/docs/docs/tutorial-basics/create-a-page.md @@ -0,0 +1,43 @@ +--- +sidebar_position: 1 +--- + +# Create a Page + +Add **Markdown or React** files to `src/pages` to create a **standalone page**: + +- `src/pages/index.js` โ†’ `localhost:3000/` +- `src/pages/foo.md` โ†’ `localhost:3000/foo` +- `src/pages/foo/bar.js` โ†’ `localhost:3000/foo/bar` + +## Create your first React Page + +Create a file at `src/pages/my-react-page.js`: + +```jsx title="src/pages/my-react-page.js" +import React from 'react'; +import Layout from '@theme/Layout'; + +export default function MyReactPage() { + return ( + +

My React page

+

This is a React page

+
+ ); +} +``` + +A new page is now available at [http://localhost:3000/my-react-page](http://localhost:3000/my-react-page). + +## Create your first Markdown Page + +Create a file at `src/pages/my-markdown-page.md`: + +```mdx title="src/pages/my-markdown-page.md" +# My Markdown page + +This is a Markdown page +``` + +A new page is now available at [http://localhost:3000/my-markdown-page](http://localhost:3000/my-markdown-page). diff --git a/apps/docs/docs/tutorial-basics/deploy-your-site.md b/apps/docs/docs/tutorial-basics/deploy-your-site.md new file mode 100644 index 0000000..1c50ee0 --- /dev/null +++ b/apps/docs/docs/tutorial-basics/deploy-your-site.md @@ -0,0 +1,31 @@ +--- +sidebar_position: 5 +--- + +# Deploy your site + +Docusaurus is a **static-site-generator** (also called **[Jamstack](https://jamstack.org/)**). + +It builds your site as simple **static HTML, JavaScript and CSS files**. + +## Build your site + +Build your site **for production**: + +```bash +npm run build +``` + +The static files are generated in the `build` folder. + +## Deploy your site + +Test your production build locally: + +```bash +npm run serve +``` + +The `build` folder is now served at [http://localhost:3000/](http://localhost:3000/). + +You can now deploy the `build` folder **almost anywhere** easily, **for free** or very small cost (read the **[Deployment Guide](https://docusaurus.io/docs/deployment)**). diff --git a/apps/docs/docs/tutorial-basics/markdown-features.mdx b/apps/docs/docs/tutorial-basics/markdown-features.mdx new file mode 100644 index 0000000..35e0082 --- /dev/null +++ b/apps/docs/docs/tutorial-basics/markdown-features.mdx @@ -0,0 +1,152 @@ +--- +sidebar_position: 4 +--- + +# Markdown Features + +Docusaurus supports **[Markdown](https://daringfireball.net/projects/markdown/syntax)** and a few **additional features**. + +## Front Matter + +Markdown documents have metadata at the top called [Front Matter](https://jekyllrb.com/docs/front-matter/): + +```text title="my-doc.md" +// highlight-start +--- +id: my-doc-id +title: My document title +description: My document description +slug: /my-custom-url +--- +// highlight-end + +## Markdown heading + +Markdown text with [links](./hello.md) +``` + +## Links + +Regular Markdown links are supported, using url paths or relative file paths. + +```md +Let's see how to [Create a page](/create-a-page). +``` + +```md +Let's see how to [Create a page](./create-a-page.md). +``` + +**Result:** Let's see how to [Create a page](./create-a-page.md). + +## Images + +Regular Markdown images are supported. + +You can use absolute paths to reference images in the static directory (`static/img/docusaurus.png`): + +```md +![Docusaurus logo](/img/docusaurus.png) +``` + +![Docusaurus logo](/img/docusaurus.png) + +You can reference images relative to the current file as well. This is particularly useful to colocate images close to the Markdown files using them: + +```md +![Docusaurus logo](./img/docusaurus.png) +``` + +## Code Blocks + +Markdown code blocks are supported with Syntax highlighting. + +````md +```jsx title="src/components/HelloDocusaurus.js" +function HelloDocusaurus() { + return

Hello, Docusaurus!

; +} +``` +```` + +```jsx title="src/components/HelloDocusaurus.js" +function HelloDocusaurus() { + return

Hello, Docusaurus!

; +} +``` + +## Admonitions + +Docusaurus has a special syntax to create admonitions and callouts: + +```md +:::tip My tip + +Use this awesome feature option + +::: + +:::danger Take care + +This action is dangerous + +::: +``` + +:::tip My tip + +Use this awesome feature option + +::: + +:::danger Take care + +This action is dangerous + +::: + +## MDX and React Components + +[MDX](https://mdxjs.com/) can make your documentation more **interactive** and allows using any **React components inside Markdown**: + +```jsx +export const Highlight = ({children, color}) => ( + { + alert(`You clicked the color ${color} with label ${children}`) + }}> + {children} + +); + +This is Docusaurus green ! + +This is Facebook blue ! +``` + +export const Highlight = ({children, color}) => ( + { + alert(`You clicked the color ${color} with label ${children}`); + }}> + {children} + +); + +This is Docusaurus green ! + +This is Facebook blue ! diff --git a/apps/docs/docs/tutorial-extras/_category_.json b/apps/docs/docs/tutorial-extras/_category_.json new file mode 100644 index 0000000..a8ffcc1 --- /dev/null +++ b/apps/docs/docs/tutorial-extras/_category_.json @@ -0,0 +1,7 @@ +{ + "label": "Tutorial - Extras", + "position": 3, + "link": { + "type": "generated-index" + } +} diff --git a/apps/docs/docs/tutorial-extras/img/docsVersionDropdown.png b/apps/docs/docs/tutorial-extras/img/docsVersionDropdown.png new file mode 100644 index 0000000000000000000000000000000000000000..97e4164618b5f8beda34cfa699720aba0ad2e342 GIT binary patch literal 25427 zcmXte1yoes_ckHYAgy#tNK1DKBBcTn3PU5^T}n!qfaD-4ozfv4LwDEEJq$50_3{4x z>pN@insx5o``P<>PR`sD{a#y*n1Gf50|SFt{jJJJ3=B;7$BQ2i`|(aulU?)U*ArVs zEkz8BxRInHAp)8nI>5=Qj|{SgKRHpY8Ry*F2n1^VBGL?Y2BGzx`!tfBuaC=?of zbp?T3T_F&N$J!O-3J!-uAdp9^hx>=e$CsB7C=`18SZ;0}9^jW37uVO<=jZ2lcXu$@ zJsO3CUO~?u%jxN3Xeb0~W^VNu>-zc%jYJ_3NaW)Og*rVsy}P|ZAyHRQ=>7dY5`lPt zBOb#d9uO!r^6>ERF~*}E?CuV73AuO-adQoSc(}f~eKdXqKq64r*Ec7}r}qyJ7w4C& zYnwMWH~06jqoX6}6$F7oAQAA>v$K`84HOb_2fMqxfLvZ)Jm!ypKhlC99vsjyFhih^ zw5~26sa{^4o}S)ZUq8CfFD$QZY~RD-k7(-~+Y5^;Xe9d4YHDVFW_Dp}dhY!E;t~Sc z-`_twJHLiPPmYftdEeaJot~XuLN5Ok;SP3xcYk(%{;1g9?cL4o&HBdH!NCE4sP5eS z5)5{?w7d>Sz@gXBqvPX;d)V3e*~!Vt`NbpN`QF~%>G8?k?d{p=+05MH^2++^>gL7y z`OWR^!qO_h+;V4U=ltx9H&l0NdF}M{WO-%d{NfymLh?uGFRreeSy+L=;K`|3Bnl0M zUM>D-bGEXv<>loyv#@k=dAYW}1%W`P<`!PiGcK&G-`-w7>aw=6xwN*)z{qlNbg;3t z^O)Pi!#xywEfk@@yuK+QDEwCaUH{;SoPy%*&Fy2_>@T??kjrXND+-B>Ysz{4{Q2bO zytdB!)SqeR7Z*b#V`wz;Q9sbwBsm#*a%;Z0xa6Pm3dtYF3Ne7}oV>>#H$FLyfFpTc z@fjI^X>4kV`VsTHpy&bqaD992>*x36$&m_u8MOgAKnr zix1C^4Kv*>^8IV-8_jZkZSn%yscddBFqkpaRTTAnS5A$!9KdgBseck^JSIQS`wRWHIZ&85f`i++% z68t8XiOy$@M67#u+Xi6bxpuq+`HWa<2?N@OcnUhX?Fa0ucuMgFJFc-@1+=(NlQ>>F zRDxG-|GOh}P`zp=#(X0xY7b!pCjittaWhLjHXBB#-Po`?sO81ZebXXp;sg3B6U;yT z7ltQRr)1+s9JQ^V!592xtqynFYr$yy)8J4=_Fovpb*N%#EBk3~TNxng@wp@YN7Lqp zrjUU+o-9X*B{;#FfWF+8xsS-jI`K=*Kw`Xfb@RSO_U)QsNHa<|mWk9yQ?OwtR*_xq zmD=jg&|q#_bdPo=j-*xO@t@Lx#ApL+J`iqWlGkq6;4fv@4RCK_O9tc(xtrrh=-c5R z69GA#i8S&gK?|;>DM8&0G0qF?C*`-kOcVP3)1oi%f47pC4CS=HBdpf`E)$Hno3D*LM*Mxsl@|fX(Xf%aXWP!}X9^S#Vk`h=79=r%L^l^YWXw_fRl+4teQ3x9_*k%}TKmP12k&)U zMNC;?1$T%`tp^#EZUUbydm4SOs@A)}3PP>tiL3j_W06pb3vSHu)DJU-0m)ledRGV0 zJ|rcZ1U@_hCyPE6_-wiimvjR3t);y*Qdi`BKX*PP29RBAsD8W-^u0fLrRq zwCLWC=t#&Nb(JimFikS-+jq}=-klKJuPf|#4pY8f?a%e6U2$1>GPfs~QJLAlns4;O zgz6*qdCCdKNu92Gtjo^ob%T4S7Qi-4NMGg1!+m0yH08I3TITyT6-g}m=2u_lckZ^e zq;^$v+pjrNbh#BOPdii=sJ1bq8F?sZTJcTI5o-P0V#bJPYY`?awnv-41^CJh$BpLP z@aNtrc;&0^lO>O1M4Is=8YA9!yo9_AI^mA7`Aw!579-QByLL>P$1D=@r}QPn38D;% zpBWvkXSRS?b^4Pq$yjf%7Lcq#0#b>rLc!^-G|4-BD83fHp~~6CQ_U~u{@(n0go&P^ zDHT6>h=0KJ)xPF^Wh5@tUEbM@gb&7vU*9YcX;|;ESv3bj^6HmWbTMt;Zj&y(k;?)$ z!J2pIQeCULGqRb5%F}d?EV$v(x+Zqs7+Bj<=5FIW5H^? z1(+h@*b0z+BK^~jWy5DgMK&%&%93L?Zf|KQ%UaTMX@IwfuOw_Jnn?~71naulqtvrM zCrF)bGcGsZVHx6K%gUR%o`btyOIb@);w*? z0002^Q&|A-)1GGX(5lYp#|Rrzxbtv$Z=Yht;8I!nB~-^7QUe4_dcuTfjZzN&*WCjy z{r9Sr^dv=I%5Td#cFz>iZ_RSAK?IMTz<%#W)!YSnmft3Nlq~(I`{`Uk-Wm83Cik$W zA>ZEh#UqV*jtmtV`p(`VsJb>H>??z9lR#V(`9^UEGvTix4$!-_w1?L1)oZ^W!E0k* zCB7_q(G~1Q3x6mPdH1`hse+Jq;+?Cw?F&D*LQhHFoFJdd@$J@~sOg%)cymn7a4znI zCjvkBKBOSb2*i~|Qom$yT*r{rc!0nX+M`4zPT|h~`eXtS!4FPTH0(?%$=fr9Tr*nb z(TR6>{L$7k2WHlqIT4J->W-mYgM)ac(R(z56AY2Kiex&W>I$p+&x#bMNS&|p@eWOy zGD7es5=6U#uG^J26B@SERc=i`I+l4_*`E_OxW=&=4|rH=p;$GB!%As!i|~ypyq`M{ zX5L!TI*|QR-pt7Y$irT5b=w9KcWKG5oX;$>v|GNckJ5XfdZ#KHirMyigcqZ9UvabrO{ z8rDp1z0Fr%{{|@&ZFm^_46S#?HL)}=bp45eUvA1gf(mODfe+cGcF$6-ZaI;NvMu;v zcbHrkC+lE z7RwO#m?)*hw^|}s-z?wPDEMJ2%Ne3)j0Dnt?e(@i?bf<+s^BM?g^S5YKU~rg%aeTl zJf0#GyUY|~Y;9SV_?#uV9<{xsFjl^YeW{@1$61GkUgc9Xv6cL@uB^M?d@o7H zHKV^XV(Q|Q%Geas3dw$Jn&atPqxYB>>Ii<#Zv+@N8GYs#vrxfbS_%zJ#18<+55b3yBCV#A}|5J8EAtdUd zn{=~8r&YaM_GB^l@6D_xfSvmbrbJP^&RZ{np(I^~Osf9d>=xz;@EnY?(Egg`%_&Vt zJA2@>$gsV@XFKh@>0z#d4B>B{^W%bCgT;)f6R|f%yK=!bN2w`BOC_5VHz(Q+!7ID^ zl#oQ>nDe2!w&7tLJ8#8wzN%$7@_>{Hh2xdID<0$kb*>G$17$S3grFXLJQ>4!n!>-B zn>~N~Ri%vU@ccS?y8BTR)1#fe2q zlqzp;&z9I1lrZ*4NJn00*0|iPY)Z0d$3NTJ9HNQ+?JI;37?VSbqMkdoqyCsG=yp1B z-3WO8>t^=Fj^?PT?(-0dZ8y_FL2Z9`D!m-7Dgr7r>V~Rm8RQ@w>_PrbFo$N_#jGzx zKC&6u^^M`8cdv1&AJ-O}jSqCR94J?FnYw!JN3(k7cejfuS`7-j*t4GNaKH@|kkrB_uY?<%tF27r;kVj(nzxph1JsFr z#*%R0;+(NAevpx|F8|sz9}SI%^z@E#+KR{}h1fyNXo6z$e*+nNx|qKR4DoCl0?&Q@ zs8_MHOw&gA$VQz4yIo@Zg{!M@m9v_4{_V!x@I>5ZaG$rcOvUm9O0DW9tR>#oyg@l8O!7%+a(wcN zU}SdcI3?TjNeNXmMJ!GUx@tFbszrKU5?ewMLA zJ)^SSUMDXb)yO8<*A&?2bBN&NEk{+9q~*w%k^+OUs)b@Fs#!)#9E-|}*u zWAn}H61Uy!41$}d1d44D;guxTx^kD367XWM%5Dea)6$5&n;))D;D^r~G=m$CqS7L! zmLX|kejC<`PU-rS#;n2Y0*4;&?(ROps&9eVSDoY%G@-4kyG5AX|Fu&1M5Gm0(-Z6v%1@fS9$`LGCB zlH8i;1e!(dUd#1c@G(-^QedB)$yJ~Yke{h3 z$#|*Md8c7)??v!utM3QJT7mN@DE%_r@BYhvf))3qME|n>shVP(03fO0{Iye<3)wv9 zoYDZ$wDak&n*QW`-s6KKDk5X1OQ_ramOCv4gjh1}jy%9GX!s!hq`NW)&%o9y+YrmT z+u!YGVhHBA*{|c;^}Xg)elpF+dMcpHNALqheHQIX<8J#~;Ah^+Dw~L#CynKWfTWCu zCEbY3ybkQ225nUxd$i6(3SN^?}z{r>!_8$YiwX~LE`rzuT=q!8;h{UbMWDGL@VpWm; zZtr3$23sHj`&Co0No!R|5#Vt7{9}j|TwplkHdT=aUeQ*;9XQ2uW1WUTbA%kHwMR|UUq0xTEetKps9KmNYAS5aY+L31z8w-k=r7r5hSK=6A!^nU z8C>n~S?X}?D5`5c5&2wA0cxo;KgFAi4N2T%LF4fWoMQ=CTo>=1mjvBvW;|iPUB>xW z?K5>~6VIpJYo28I)EFl&7dAhqrB6A-(e-)leVf;X*$GA~eVokc6j+rvRq{{fZth{*dW0`N_!2w6Ll9fV z{aJuKFd-zavy0~QH9hD;H%Q(_Zn7nY>AkaeKuL7Q@G02wArkDPH53Qg5JGaH{_ehi z35yHf_=pB1wY&Ak3EZ-^Ml}MxJh6d_Z}jDN7RTDy68ton&H$4=>#b4w904+;t6CcZ zMtV{hLGR06a?g$sZA#7RlKPF4Bqk=}`#oc=#~O;oUX7hbb^NY3f2Nin?(&;E?zVkm zN}OTyV%mP6T5(MT-syZn(K?c9sk)z$K0AQvvk9#%4%)evu)aOXbB;x-*G5ljx|A;$ zZmCV}y(IS$SYPVS%g#3~I9lE#erA)7BgOkZC}~2)7B_BBStEVtr1+0nv{(A%zhmjT zsE;^zwY5(ZCyf%wwr*SJyK_?Gv_p!Oc-8$W?a03T_8q zb=XB6)**gF9AoG(=dN9-4yO7)FI}g2!0UFua`5ASTp*W2K#(fpZHPv2}6 zuI3YRPb*T9uhpKUc zPNT}NbGpABC}F~2UYA?vuN z*c2)mWKvZn<+PL%-Oq3lAhrw_j}+<$Tfvgoo)dRh((_MP7Iz=PwI|1>aObW5-b8qW zI@O0@c{EbVHN5a6k}i4y2?Jh~=Jd-MZnv)h^T1;2CAllrl%EHm`1{XUiW<7g+6{XS z&hVyh5*+TiVaO)+4PE3HcnsJajGx>gwo1EcWg^*Rn0l!#MVM%(Ywui_UjM8Dgspk@ z4`gne14lZ*`698%UOOx^(v_~kQiYj`WkY>(f5KDC5I{-Wi!KoINK)H^9m|SUliD=d zE;N>?`0x*{61(==UBrN}mpsdhOZ2N~I>oQ1avz|nvyfQQW_R6VAnn;IzqlxDB)0_Zw_Csf#5sdmb4LBwIyBk zv$NL*@acUJc4`FtA^-PzoHR zKXm{;9xP9kWW6MEPYuCeDqX@UiY(8GShF|L{-)R4_acdmp+&W~4nBxde z;pI70##wwE$hfIrpx@VQ`Yc>|xSP$S8~WoVKTg5Z*KMWE)Yp>$m>ZoNQ(u!z-#`mL z1jJZHKZ}Tc5Ap^(*KIg6ol~wx)s~So91kdWaF2c{?F58%EDiT9uV&xYWvS{aFS{hE zg--eu{(>bL!0h)=md^{aR(APus_Mr}+}|%Rb(>B&dHn3fw9>d3rkDH6x0-@)^Dkwj zjb75;-8>7gmW&$y_4x~rPX!&!>l3d<-kfo+g{PIl%s;UQ)Y+u z4&z}r;Sd{hco!{2a3}F*4CAcydj7`#V0_iRg%G&NxtQpm=(5VbGfiRW^NoBJ1rPE# zzYktZRk7>`{fdU((V`a+T{&n=cnr4LaS!S|hDOtXWb>_e-LwH+@FmdGw>6+B9J6~} zcBaNb(<-c6&|ghc-%o3xG(Op-q&pXd1CfV zgPNdKX~vGy-LS;4Q=161sLAoMaXGG7weBcT%KmWHZ${+6bC6yehCjqK36LdH>fR!{ z>Xe}eUaWsRp8U1&?E`K@0*oHDY-p{^+u0T&$b)J}|G6C(lSRuN&WgUd(rH=0h9hUz zj|U@1UmNWdbn)SLk^KR_nRxbB`hNKP>?@ocdEL;;1l||Q0{~Zx5N5FT_ z8{|xM9~@McIdv|?#WPK>1b&f`?=bvMO>?(;W^}|VZ|%*&C_rsnS5&E~%`>$1I#;~* zn=Wx?omuI3X^Q4D$;n_~HEv`6`Rwl7C)iTwB5O~BB+$PgQTGE~V(6h;78q+*a8tK* zi)1P_7BY;9ea2|o@l#u>z4b#X%;a|nTq^l*V({7P;k z=t-%I--DL{uv#dVtaWg|q`lNci7#N7sC(@vBesWbHEY@Gb4`DozcU20N<=vl;-%s5 z!WzFm74mydG1Hjwdk!c_6!|q+Noz5>DrCZ!jSQ+Yjti$3pBqeRl}Wv|eimpd!GOY~ zDw@@tGZHFbmVLNc^ilgjPQ1os7*AOkb2*LRb{O-+C97i_n z2I@>^O)#WwMhxr4s;^U&se%2V#g)$UMXcXHU)C<7ih`meC7t?9h6U9|gRL%vjBW=4 zyJ(KaCRlNg`fO6a(x7h==WMvQG|_Skr4D&0<8t`N`#*Y0lJn{f4xjR5Q%h*qiJ!9l z{{3xuZ%nm38N+XqLO_y}X{{=Z1sg+iy?Wk0(xmzIV8KVwj}M}&csjjc2tOdzyInRf zj&mB~+`^C>=hnyxW|Ah^U8Pcl0}jx|K^QWjuTpX%S?_Y({asp@tk2!qmNiJscA|3v`}jyo*ALZ(Rr*ar91T`}p~N<62j4RJ|PDBQI3t8Cdh) z?R$X25f31}sp@&0jG5+in zs$WmohuauhuK4uZ1iNJsy2T@EuDDT=`&$LT=jKS^o}44OK5cA$zAzZq&gS)a(=xC7 zC(q}(#ncl6@1^p;YG?lVnJ)t^7Ky53%ZtMKP6FKlx|zSaeDQD~}Xbf@cZU>-AI+P+4hN52dWFDA$qg=0!5}U9qLoblC z?2V$GDKb=Lv@me&d%DST)ouSOrEAoGtLxcGg1~Kmzbq?}YUf=NjR9D?F9<}N_ZiNa zZhdC>2_z-iy!(9g9{n11i3|~!hxmAYX6z9olmC=&YcsiKI;&XK#&iSd&6&{u1@Hd^ z&}sU>_G+y}Gi-8`-k*Exr{a$>MNGj_u%u$;s_fOjknwYR-qt1G|mi}nQ%CB|0Vp`=0tc2y(3 zJ}XmzSQQ~(SfJW-|mT1TaDmxNCml#nWVyhIvX z5(>8xARd*joOU-U;Dfj+E+nUJC25bpe>!0L^f@BXZEW73UVfjT$=FTfw8u@h@$hDQ zVua*ub@?Dlc%%H2Kt+bYLb>$(@roZ+vrM&so0RO(eTY12?=Hk4*qI39-0yU@%aQU) zh(=Pxi6yISqhKQ$i^SEeyiioo-1GNY25sM+qoj*Y3&qp^8_)87sMwbecGG~;>|9TP zREo(Axioj6Z+vp*b2~Yp&YghcPwB1H+J6C`1#2tPkLCkZ%eJSah9>34C6}Wx52PW# z^-a1fn~bY&PC$SE9!mvprG5JAMZ8#PQ1utYB%g4fm*YwmC=|j!Ynky<|7ZL;!BWr3 zFawY3dr};&T$Ip3YmV+)De<*8`l~v0VwiNIPNf3|&X$o&6@|n6LRM@CjYQR1 zWBH=K@#i3!;27}0=N!39tP9ZWSn8M>14nC%WHmBMuFJAk%Lb z3uC1S9h$5}_+BVizP47z7mQl9&0QY+JB+^dI{s zw`OaYK6by8i7`3&)Phx%c((j7B1YUWiF2MMqu4sv*rJ!i;BLj(fq}XbxPz*4fPY?O z@*Ky#cmpT^|NpZ9uUqz`68dgR9jtzXj=}e&QRIn}pQRT9PLxt|PUrc*i*0b!XrG!5 zn0}>27K&TEtQcrzD<@JD6Z~^YE+@bp^w7O54P0!hf0Y2>E)Q-^2GDnxCg+6##J=z7 z@ngMS&`rDgl6d+JcSuka%Z?(3I;F~=S0|1#j5>jeKEQlh=sBqfv!hBN|;yTWLomu=my`^LYikzJ(>0epsIY)kU18UXtB-3pcSlnHT_D|^@nAOvSZ&U8G z2j{}BU*x=`J<)n1d{C?*L9G7(UY zOa>7`PWnsf0_A36hyo=b^S{8-brz>TuX+X?u5rOaa-i+Qwt#GO{msTqNOcGW+e>Es zB9jlrN(d>)QU5{6)p@F-7=X4^mJ_o0PmD`XJxKX3yEPtUxGs`3c=nmm=R})T1N{pn z-4`5~hgSH{OLb&X7JJ{Kc!m~cw^Px|bf;E_^&_m2-RyF$>hpwb^&OK2x<&5mZY$DQ zM*Ba9X2yg~f2CrRi%7#Gmj8ToW&RX3woB;vaQS~RStNrN_ip=L(D5O`5ARa1*tbl$ zz*z9~cch#eZ(SfXecVU8>@a)YoW^a+0f3~j0Y?^-$NJeZx)){fSvT?~Oz zr|rs5)}M)5nL!oe|LIs_Tje3%Izv_8s~up;gZHa$tJ2apK4+*%@ezaqN}(Z)Knf?w z50}vMb<0<55q_7mTNOQDi&W|)caK!E^KS2+JE#Q+@^xmQv>inXC5o`mvE&$TOke$B zV8GSwhlTR2rzJ#_;)bk${WP%Ih)i=EYN8{o&z8%2I_q?VymrtR;v$zLkjrg{wpYbS zvAcy#5)@jAvZp4FuHHU2=>%7yAaF;Pr;R4Fs{JD~J3=fZ1&XUJg-%A~!KmHC3n)>YIEi}NEb z%--g1St?_*DOh+gnZHtmEkxs@isI}eRrc0wU8l;2b@mCiAM#Nn997Q+LV*)|qbtKQkb_f0o-p5pdd)@GMF*DshM3Aa+3F#`qRIwJ0hm)o|YEL#OaBEakx*CoYj z!aPt=uH3>5{Lo)X0vnhRQ)s3fJD8{|J(JOpEw+)Rk z`bt&Qmfn=@fB#v0H(jRr&%qMgqOh#^u@wR@511#rdFm|rRDW^uR0I;SFNFONvL|T< zNgTUA$F0a)aQgw8fuB6MGPB@qT?~BCYk5+Jsf=?}Mb;HKNTkLenT0K8t8|H}D?|hE zSgX!{rJBv{`q@9kgrWLKN$Lc=(eX|?lLDj zTIgDs2{@)$i(H$~)t&t0ljddg!CF6;h;#+vfsiOq1m6z-@3HjZf9Cwjssl8*? z-Zk;h*SQd?Jne_EnSeuFHFb<4o#^De>LcvXXN-SWl?t8{*wYg3myaD#!ASmyRX(M* zGTP9W!pDwsi#ZmX__)rLPoItw3NlJ2we~Weclgdr7?3%+JE=SOCt;iGP}}vJ5Q|LG zVyV6tvP?5JtW=tF&6vZPw&HPWnzz1x|7JWQiR85>W`0|GOLyooBAJSsXr;fTClQ*2 zaK)sev-vb*PP9gBV5`_Qo%^@(nz4=7wneRMzW!+lzgV`U{S>?Un=WkYC)GrP*^Co~ z39gtoderj4l0kRRPB`Ahk_XC*5YRAEO&?q0Mzru!IeuE^lBSp;^j8_6-!y50K|n_p zGMdRWFh-Fi>Ry&?gYb(4RdA{FOqob;0q^4FiX*<}mB;zWot5?G&X7RqtC)_A4|jTu z$#`}>b~R$z#yqsMjRktG(!I2WS~hnaPgt1B%D#`8tL9}l{0BaIb*@{Pzt#{=K}Oe* zDAsQ#vX=-a{P_Eyl10+;FIVppTs>K45GY321_I8QO(l>aZ1$65njm1IL>Tmd^bv>K zqvaOE2UgLp-Yu%rF$JfIMhMuRr(^h3Hp`{LBoH54u5@YGjy6Wg?Q*O?XEIX6kMCO~ z<_kZcb1u98AU{a8r7g=xIgs_PH3)hJ5I+6utGV-%RP@*Qi)z02$Wuo9%2dn$3FhdS z;i52o@P_mdzh~c5s^ah~8Ps7Wp+76`e#%y5agtQuPd3{4@zh;+PJ;Ul(o51qE_WV^ zg+~a_eJ|*Xi=4jabrA&e^&&@I6=VSbgQoPeA2W5wnF#LY-O>}Ljj#`MCRMaV%vO{76cz-Og(S_6~uR>qnR(*x+nLISCR#;o3%W_6?D!w;_CpEp6{@(I+A~0_7 zs}lPdr=NoC&$L2h;r!KHMBq)8eU7#yV&?{?? z=4x^BMDRXs3k2G`S|TGIzZ0Hg;o-%T^9GFBO*20Lb>W?krt$`*_Y)pIqLTXjE~di< ziI$JBW{M?JgMOp7XK0RqD!` zyjnzWp^?d+&R3;V!S}YBsE3^$ov%4ipg*$x>0&cLpey(^IE*D!A^->G&P+M7+J2(; zwd>Ep{Zo-~HYh#S%R%s38W8{Ca=WoD??Y3{$m(9%xV*`*LEmoP1$uIW>TgrB$+onv z_ndvbMOIqVFhw~TrM%u2A6A4v!m5V5;SK21dr|_++u|ReV)&#sK6$=&(H*ZZXM7U< z=e@Z}9GCKoq)cAQ9euu8+|}amPkIa3BNZHT6d18a1P&$d5_02Ht2I0xoGDxi-;5;j0tI=XFRNl62_x%#|RTOCW zg*`>@ux)y<;|r##9cIl^Q&4#~Z3CkHHz`X=;xCJy_@caXbk+{w{=u4_bgn+6>EKRa z8dA{~?4*L&vu;0?5LGS{cbn;+@q!-7usGB$?e_1K0#gE|Ot9ixD#X(4>uu)f#}~A3 z3@nGY`HD_hpAqWw8U%*?yVSuzvJm;5G+nq@Cd+=}W!n*06lvdQCuXal{9Xs<5I5oC zcw%nh=Wg?~Ugk@T1@^y}Np7w%vxB-A9tdKDt{<)FX^ubm$7SZacAr-%L-a1JwG)#C1c0gU_I^Cd_qciW@*(2ezbRpD6!<$ zQ+C*RGs|w;)ZO`^revsDl);H7f(3E%K@i2Y%eE!3cq&}mnmjtQ*Z=hEWe2W_A^XH?Nys^bJZp5h>K5an>5p6yjNY zREWvikLx;$(K_`V*R=<8<|J@62`31~=7iCV$p6c%Lg1YAc$h-uj ziA#pcUoF0HIj*$$+!IpLE!H*6%e?c8aHZ~W{8>f@QlFmqcJUBtER_3}jheE>hx}mv zf%%k^5;hsmrzrQC;sDn(d(nBjd1K!gR*&*-DQ4;zv;)vaatjg36nGZ?Rq_l;c6lQA zQhH0eWpKygvHd1%l_?G78|(|eJ53Tsg#N4Hvjo0QDebJQL;DKH#&_8b>p%_AdE^@3 zLP(ASqIYgP6n3POQ=*_HPw&ScHtu&nQK-?0+ z8>8|df?xb$oR$yQ8MoZfbQyr0elR$(MT?`-AAlb&Ga4F{{$^zoyi|S#Y2?CZrv_8g zaK5GIo1kiS5{V~y@0UpiT9TI|Vx*t!eaK9kRthIgdFvr#q?-1&t(a;pT=yrB*xZmb zYw8R5P*fjZoZoV$hSYocS7&0+G_-lb)kFC+Q>p$|lmq`}9KRe3H$HuG_y|Xz*Ykic zBp$CVTqZL0olc9!_rqG86IPu{8Iq!Y?GKoMknsM|jFN<nmkWW$R)0;=-v0xAm_otSVoWlb^RlPVJ7p1U|d^4=E>-zP*-Rmrv6} ze|&GPS7f_&uWb1R`Q&)TSwU~0v1a<`-)o6LgtM9rGA0LiJ@Ue`$XcxSFf)nQC^6NuI4*n18HDDl~3>VPbX+k7zOT>bP zjw?xBP7GAvQDt>BQx!=@sw8)=gBtaH=3ce`T>Xns6feL{J+BW8)Q#=W-7NmHaV*F~ z>UmFhh7MkTGy+xsl^XpR;qG_do8Awha7b-nS4*taqw15O=A{`zjy!fUT4*O~Px9G* z&%KU#?o;#N;>89$=?gplzj3XFNdj^3RMIHRL=~;oyK7Quk=^>0g#CAZ(QGGeUGLU* zWPaROHN4T{eRhQdB8Y!9jcDKvnUVfi)uLU;QxRVsz{0S7@3sEf+Q?Ls|HWY4W83@} zlSXj&#g|UeKk!d^F8}ntYOtDT?R^m4cwFr4JG~o|z8Zm1yM5aW({Yy@f~BU11L!v#Td7eeD4W$>lcjaG!42YE?~f3MI=4r% zoOf_vBji`oQ?lj_PxRf%pt#H=+;A1r#K4^1?Htf{euOeDW4^2m#LA%gz+PfcvYKB@ z{l5(10Q&Plb>;K9_`Jn-xRvcD^qdB-b$9yeMaHX`lv9~f(0}6fFn#1NHFDl)U4XX~ zltY}5+&}s?L_h~eET8)X6I%nfweCW?o!6vD{DiG}w?pr%+YfFCFf-a6yId6Ra|pe; zDl_g&Cv!gUMl0Z_t9nh5KE)coN>{ zg&1(j`%gkFBL`Uj=dI12!|rM*w?!U{waw}fJ_H(zB}-9=p|eJ;sfV<_S)YhAe7eDS z{-N^pB#iLATr#NLu{RO!>S;pwW=9=;trCin9igtoOlB&izD{7ASKh z(CzzkugUVut^bL;3>2f~%R9WEhM%m4uk8P(3g_CM>~SJy%}G!J2{hm1T1XXM;$Nx< zvJ>kKg7*&8803!xLR5KkS8}@!TpVFYhM@Q4tv7{NMwN?-8Ku8G-eOxwZUgt(3=6ku z31x;jRmhmiv^Xlb2w?7W5OlqdT#XaE5q-_MGSi%fF7Ds>Ic$5Otyo1~V#Yyo$>HZh zPZe}g8O%F1w+%SQX;*l^WxmvUQ&N5%JYQ;hfA9Y5s8Xx?TASV~=_EpR32`iLB7uC4Lj=X$lBnh3I zAtk%flc?{lm>QjJhL6FP*IzJugn z5FL63L);PtTf0G#iPK0T&aY7OESEL@kG;N>SRc>->6$NM z2j0(*rwMhfDRh0gf$lx8dvfpYx#D2>k7XT8!~5PqGifS5zl^X|?z;dW>t6;)d<#^U zqpau3c!`tBk%yTSPM>VZLXi$PMqeV1LgvwnFtkPxPgjRfvVg7ax0Xr^R;&%IPtWN` zA5SCheRx72%iHFEbeJaExY1ElK+?^&?iS>TAUdMBcMr@A%n{(^2RH+ud)j7?B;I^^ z7rkfli|k(%_b%e@w{>p57WU-$O{YdI+TV+mby<|-#*lt?XmB#+(b(wfKEBm`AY(B} zAZnYZD|DDnpBb>>Q7ZEq95BDq z&uh}x=%dYlNY1S?M_&pI&)5JYVBPFYqUc-8!Vem&)86BebiW?QAtFDVy}0NH26r_( zC_^CO?cMW|=e_!Nd;`}}wIe#2rjbs;ifve-VvB7)GI_S+Nsq$S5JY$8#w^grTZsOb zUyoAYclwpn;7>Ci@(v@DI(;8$4<&tHXlW*;hWslB|D-5>6-zKX+2bVjkSQ8?!9MgK zl=N~I!}?@~Kx<^NrI^q0srRS28Q~9lflYBLXVmE~H-TOQPE~(*4@#$PheP8^EAU}f zm+WSP;g*ei&p2L;l@4F7HzwvVyZLh&&an%n~F2LIKZGsoGGdXNS^^gkCKD8wC{ zOn978*5SMH1Cf!Pil1ixa+!!Ro4xRSy)@zYLPs7Fyinlr`RnQAu(hV9V3Uz}C;^ z-~Y9jxm+%8+u;v_3xQt^9}E{~dg`y&k_IL-boMLUMr9GA>}o>^!B)g*B8rgz=En8c zEK9pm`|y*X?2q_#wSx_BP5}w*8X6!2tqcCUtG(2FdmF>*`x6R~l!xbak@?Q#VXxG=k(YY-43Z+D2$B08B6(u7e=DG~ z*%5MY)s?k;<$!wd{Mz})9SNS2BBclkhNAYGR=Yc9eI@Gtv!DgL3xps?>l1#V*6K|I z@g6biLi{Ynk8TBO%+c=d^WA~VrcEsG)?TmrPdXwVR*O*orI~)IESKLQEv<$euHRV0 zUPn>T+x>w-@sS`pGlN?9>_rh7SfhqmoWUbl!t=cqsYqT!VHZ?eccRCm5S-9?!v&=- z+Jeh%?!&){ecKh#*;pOrlRLHF|528F&6}$#V0U~vK(#a_$BEQ`{zWkUKYenVJE9>7;rk|eSgj=7Uhnz3xm0Qy^^Hui9 zY7}x$DkL_sWncCgDbupk5VZMn-;o*FQ1Mt z2U`xQCp(2}Bg4`+`iC%H9Tf4sY*L~$W{*be^*Y%4MZV8(`SR)b@`qbsSWL5$uZ%GF zjM=n+$!a%_F=CE3MuW3+McnFQ1MtXU-E6p(YrX)pV>Dqtp-+cnY_W zd6t8G6`!Bvka-in3^?bveED>Ixf3Gl)fQG*Y`aenBlz0qAXALrc|ep17;{X9@R-8v zbs8||w|x0@eEHTEGPjTjRUj%~kJ_aIh4Cph9?uqYMFN32jbQ<|1u4J2l3al~zvauP z$SrpD^VHWJ3&Q$?NSEJQ}*?%ctYZ@oc|`spkf7Fia_oS2yFCcrly1 z1B*s!8Iz$^^q*A|3`=7QzC4t=pD)K`zthg^Ep3E}5G|MBU&RLp#o|IPI}ghR$q+u@ zJc5{|sde-oO!?>VTH%FCKcI-(x=FE!a+1wn)^OP3S z(e#KhTllu^uAeWD&p01Gr5^Y5;c%fFa$K72}j&d--OdYuktp4cwI{afY9wWwjpF#aIES^M$8mK{XJxHGf9|=N=EJAbe+>37@0iVs&W_;h*kQQ?1r-@eW+XFHl4c>?#k=+r=%NW>Ns-Y9A@!k)T?e6*WHg!^ zZ*0Y^BoAG^SUXT#3*y5Xg0uru4D^-_w7Ja<7f}O-7K+riTwU5)p$~=j{lfnLnTbiJ ztqb?QEjgM@GJobA=9_=M^Pe-{{NpBw-~L>F?&eA9|5hLVo9&$cPoK+Qju$*3*X&2z2QXa0Jn?Fjrh&=BsW6$h6(K|%>!6&+!pvWwM{YSE z-2liDar?!20&>3lzSo(znGVlddBXUF`MD5V%%BUKj&q%DB? z?(HOR|MMsL%d7R%4K@2w_Mb<|Q^^Uhgn&XATZ;2|AYPH?##y0*@^LUOfpalPq!6JvF303@uKISoQlV}P z;dN)hq%Sw?ryFYaqwE5Y!yq-CZt6$H z#2>jt`9vS*VVD%krkk(_CHEw{n=AF@X8p8Te_pef?agkSTuDb&SHOk(^L9eyq9lor z*!d1Y5E7ImLI=ua!rZa?6dV^A1}7KA)>ih>xDY`v_jyH+B!yE9gV&ovv`fV)MfWhzOU)&HxmiDL)}Pnx zy8SCjpR-l1*1x;@QGd?Z+JU#FR!L$ZLW}^hTu4yAh@yn@#CC>hw6)NkH2692`O@_X zew2#*_2<$AS*3p3tUs^W8yf!5EHv``gq`TK@^r`*qK;7+j`0vpxpx(Yp5vD$g-eM9 zH6}_iz+3_=Lp3!9T4*(@5+yFCWwqN^Fip$M%(wVx5R#GzQ$J5ljbNE2WqEdanY@g$ zu#n9z9G3g#<^B8jjTQHY4oh$-iHqcKEKeMcz4u4{La%=)7%a6{daG(5?Aa&#PYOXf zh(*(6@=2C8MOG9gPWF`SH10itp@(GrL@D{qK-xH#q@m^9#<5jU(+%Vb85aHSqaLE@AhvVfD_AhL| zf45ltDTva)W|!2{Sm z86>a_1xtQO>^f??ee3bw!=voDab>}uYT0#Y%du9`e(>NYhh83JWevavq&4tvcmd#d z;_(p^-~jm#SBQ@2sfOHC z02lPvx8w_uh2!BT_A)%xW$S;~Ki&T6n&S|1S*MR69`L{Ipy8nczO7)95$-tB%3$2U zd*s~dA7J10>>uCu04Os918r@$0P*WMeK>5jMAh@O1%{n}WWo%C-6V9DbE_=dA^3$v z;=&0(5DPo+ljeOMpEF#a$)zYN0HaVf+J~XyG=CjMy90W5)~h{-pd0i8zCK%x`Yd`n zK(4#{!m{D+`j_%&8Bbr$ID<6}(a6Gy{ft2J7Iu7JKjROc7Z9o;&2Z2{K}W6dJXyxG zWPkS|TMhC-R;OdAAK!qUvB@Mux{Nz{)tT7JFeV`qmK^`4#L|A!aY(Z zaXnwzl^OErpkBLubZKJRdfmO5Co{G%2x?@Qb{mG|qB!qc9iQ|^#ydJrbay9CA>?1f zae%Nz^5qyO>Zb!3wO9aiYuC~eZ@1sF542&fQ0zr}DnZvt-Ej2^*wM>@Xpn4X&Ax6x zj^3q_y~U4m$C*7o)K3-1wcLetu|!?CmVkU);Bh*Pg)FRWKEN|l}@@xnE+VKi1y@|grKE@d29@hVW94nddvm$4qF@#)iA38?`kMa(2 zYwTE)C8**5;vjk5s9+S_|0@ts!2e0iPma&S#*51^=serm*Vs>^+9ku}GMrO_zSE2N zLeCi)PjsKS-2Lz4)Ht~L7z+a;>_RyPM?`hUC>Rl?t)a7BdVJ2?r|sk+=H#KEGo(#& zZW*p_5X@n?UdWo5=92Q)dx8-r=HGd__BDaOFbg${6W zaB?IT;lI3HZAe>L8kYUhKZR}xNvu)P^hf_V7!U?*tOKbv=?^6{11&C*FmiFa+Qv+@ z7TuBr{1{sGj^3^$5iF%wRu?7}XP1$wRwqA7M_Ee?L)mJ}^v?7{7=|v>|Al>?_axO0 z`)^@RYQE07_w+vJxzGE)=bpS5m=6p#whwX|*Bx~(JGp+^cBp%CA>X@EzGo?k?$@gM@@XA3JdtC;1BMaq#z94|#pA zSblq+=4^r@uwC3NLk-o3i=cwX==$aF$juKEYOkB@LO z7Ru4DiFqxeK}|GB3gE`WD&pP4-20>QyG~EoQ+-|lFE5`t>DzEHBLy#Z9w@1G%48NW z4Fp{9R${JLU#Kz(+d1sDLs(*P8P~=FjiqaTe}ntR0cRE0Paiud(=7|WF6K9%o~&*` zcr_OfXP{w#T_ye($O-!CJ-WlTZ*J}r_{;R(FYiO2PYLk^_T*9^r?R}9cp$nmk)TxE zLLpP%2;{HliSvXw)n`_ot#Y&k@&p^-=P1m7357@`u3-dd{0QX(?jMi&NMt_owo5|3 z*FRbQ1L`B1uw2QBL9`9cGBndP3JQ)x?&0xgGBwP|*TSTH%uha9w%}Mi_NO)kopsCt z;=F-KhpRpVuFnPrE0P2CaLM~C`vWxqiCa z)@^h2N`CV)-;8g%d}i8HJw2X*q-RD2bs6@z0&|KP{-tbg?pOHJ^6z~N!Rd3wLBO$S z^XlB?I}nt%ipoO$T_Fqr@6Ha(vz?t+i7f@Wz?Im3dH=a+dqg1Lo>xfI-hD;v=LtDD zJ1>w&G!Wb}*b)8+tQFA+`M&-sX8b=H*wGowqLyfuX_U}X1aW3DnI#R-NCv%*Pj!=2C7QHA3)eS_FkwD{$YQAhj%#G^mTu*B-j@lfSkj3 z^poc>p?)_aRqt;;}`z4RAb{PNh?NI+sq*GA2=eIP*7E%lh$h$p-J6 zTv%Li*t$ErJGuTGKHrT7KVTg6w+F^JnMHgnlc8X!Y1rF>9YegHyH#;ht;kU+hIMes8y?Bjt{=Q~0N`J=28lA*{@BFxf?_V00KyGLc zZ!t8Y6OU8Fump1KRzYqU7>Rplr7P*iDnO2RteG&496k42uW71pli)@!mDYiGPEYHz zvss;xd*U^jxlu4~T5g*v6i4L3x!SVMHrp{-e}03%PyuZbbs`2@8wA5c6|oD!%H)ON zCa>2XeDX&?-hZL5qGBvYp@(xG@WX>|a8^aDBtJL&%tK{7aX5v}+zO&DBQ4|A>6bG(`TZ# z#t%;m-+#Mn7y>yUeB1c`r%>W+0;pyQN~bEcll z0dO;&0@kxSo^;(a2ZABC$8ooW$?$@v^dd}$sMr?UB)@sI%E<_*!OaUnH>boQzc3I= zChIHVk~evWKeit(Nmd4vNlu>M0^GN@#H<4M9;G?N{~!BNH))$pu}_A84zGYu^bDV0mm14lT~SlmoA^kU z@1T)|%^uvM@w{{OEZPX<+`iEGr-zhaLeBjQTEF##Q7qsqij4$vZMHe8|-k-8PCs6~sXt@<3^0X#ifJ zYmAfRN$PmA!`syV!4tdP4wiQ$JNkIFA5EYwXd7@ti=auhPDut>XRFK8MPGDqE!Rot zOZ7#ldYDe*h{U9xj6|jkl15M9Z)=MwqKDoV1-v>57)+cRO6SNW92t%_ZKebcv*00+ zh{Ar$c=+b=t|9Dvw_bboV3YM`PQFz24}X2U{pq{gt9n?#t!=0TWWvl*ogvb1``_9| z|2e!*?|%R6`=4`JAP%T!iMFo)0<>GRt-rK#D&;&Syo-d}DBJLr`-F##e(Lg)-+Y}rKBaBHumqDMK=C9B_F zbjmb!IpS1`Fy!t_OJe}Be}msy8?CC9{M~t5XJ==f4P zs|jyy6^trzzoPUe!!NF=Q8+RB7aW)HNzUF>+RWv|JxHUZ;3TB!nc-c^)Ct%BSx?@I zC>MIn3WN9hf46=q+e~h^egS%Cv(3$|&0n#Hg&*X`TF?3?Dpd&cCR-X><=ZmswITz)b-g- zsQHweYoeX&QRlMC-_2D;2Rj!&bSyaXBI%OZ;`2$l?=xI=YWu~J>N!LSaX=2^PR_?Y zO6O0|tG!Yf2EzVVIY`oqq>_V`lNlTz;ewUr2KTbx-AMfU)^1L@B(UeDw;(`zj{5M*?krKO|L&2$Sxi)o#+n zncgm~q*C7@`JV5o_kG^C-n>B|3azO3xLkTX&ia-=$o}21SrCi^<^Wntv@SlM$an>| zsxUEcwian+o^b&tE-nx)J^2$<6;@yh;lnd1EW~VYpZq9n|C6^5U-7CH(@X#7XPTLJ zKi@#X$DiK)B%UQazkWRZDxH+?1vv4(uNrsXACLb#o=jh-0d(WE0gBtrrgil9ojoDK z_m)K9vlLl^4G+uu@ggYx$C95n-TZyT_}C6>yz@4jDbEVmnMmZJ5MywiiSwA^Fu%eQ zWFXG-nKDs_J%8z5*AExwS^6KJ9_KAl*}wZSP#@v z4OsJ))wG(nW!uS4AR6$|o6zL@H#G{q^A5Y_P^u?qMx{r5_@EDnVfSSytzg{ky{~EmH3< zISG2j=?e(ZWr7#Mfn|ZYNne@+1LX0zKLi~0!wK_OHn}Rk>r9v7^$>oWr#54tv1AZ-) zPmP)NvCQ*~NGm>gNhhl73+p!(|lwi6D8DHy?kYV`#y z9(4PM4}qQU18+e6RX9}m*R8G9?XB%apuhNr(K7be4KX`82S9; zP1um;k%fPd+aT(Nf@RqS<9$^802Vc2r7hmE1p3(l5n zFN3N47|aLpO=z)8Zz6H2Y@90&ubB^pOwc@K=IgVpe}2B}e%f=3s3;yM=%W7I)%V}@ z?_OC^bCIH2q)~@h_f;g(&wRW;jn7uC0`eCkB(843&A$kU1W=Vh6fSUp0m0IeD1VGb z*`Hzm16P5V@9nGx&H}@YH?LRaVKp$tDK?L6!6%?$+nhQKC(+=6FASA ztfDNRJ5IEOxf#;nQS*Skp3ey70>pQPL|>Qn=U{ucG)W~i?BC7$>2OXh!k_rsEoXbh zNzvXC>8}s_csvuNkM7B9Alf>ME=h|h8wBoDC*IqJMT<$o*}S9y#1W72hhyx&%XmR< zhTJVfKr9)}2V*$i=@bgs|Hb~}&hY5t@CcRiaQ>xf%0ky1#k8m&pZ7qekgLQm2sKi# zn`0q3%8hX8;S#7^irtCd}uAhI4M}>Md9A9L0MApc=UB@7ro?1Tm%E- z`q;l4pz}jSL=vX$qicb^YdI_X`>p8Sqn)#l2%o|1?C^=Y_K|S89RHys=WdWywjn2P z$juTI`#+3#q`FshJiC;Z426ZTa zH4`AX7TeU6Wo1UVPp@_v+stDzHbY}r8ev;%wY8W0YRjQpkAvwRkNDXqe;i9&0_d*W z{@sxkFg+Y@5AdPDbt&61nZH~))@PP=!`{!ShA-6$Lx_V0#p%#reg`w<}`0l9$Q+4@@8d9r^X0tj&>w3wavvd2eQAFk%q+^7nQ zN7UQ?<>SNov)Ygel`Dx4G>7}J)(i3u5QF>-*sFz1VaKs~&l8Gr{tY;;+;e#0OL1;f z6G3SzMeR~AXP5#DvL4{6yT|%y&wP(p(d3-&clBM}exJ3|cl&$i?lXru;607vKlY17 z6};!}Z22laDw~K1TPqPtEoY_DTH;I2`^y-=`}x(!x1axR|8m##L0{ay>GB>i;Q-jI z&u5mFHU%O6S}>TZv-U7WII&B7V>85i`F!Iq_Z$jN#OP4-=2vC{#)VF_z7~}AMNEjX zXb~6AmCh16e;f{DQj)zpJvn~xX@BoraiD(p9X~(fvysSvGzqH%JV(@AF}%WYIQ=hv z{L}vBu09kS1WK2`c-wC_U&3OKcm3m&U045; z{@&kyEBbpwzCRv~jKCP;5@i}6v*dh6N5aLH$}9Iv8~^40)- literal 0 HcmV?d00001 diff --git a/apps/docs/docs/tutorial-extras/img/localeDropdown.png b/apps/docs/docs/tutorial-extras/img/localeDropdown.png new file mode 100644 index 0000000000000000000000000000000000000000..e257edc1f932985396bf59584c7ccfaddf955779 GIT binary patch literal 27841 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 JrC|B>e*nH7H{}2T literal 0 HcmV?d00001 diff --git a/apps/docs/docs/tutorial-extras/manage-docs-versions.md b/apps/docs/docs/tutorial-extras/manage-docs-versions.md new file mode 100644 index 0000000..ccda0b9 --- /dev/null +++ b/apps/docs/docs/tutorial-extras/manage-docs-versions.md @@ -0,0 +1,55 @@ +--- +sidebar_position: 1 +--- + +# Manage Docs Versions + +Docusaurus can manage multiple versions of your docs. + +## Create a docs version + +Release a version 1.0 of your project: + +```bash +npm run docusaurus docs:version 1.0 +``` + +The `docs` folder is copied into `versioned_docs/version-1.0` and `versions.json` is created. + +Your docs now have 2 versions: + +- `1.0` at `http://localhost:3000/docs/` for the version 1.0 docs +- `current` at `http://localhost:3000/docs/next/` for the **upcoming, unreleased docs** + +## Add a Version Dropdown + +To navigate seamlessly across versions, add a version dropdown. + +Modify the `docusaurus.config.js` file: + +```js title="docusaurus.config.js" +export default { + themeConfig: { + navbar: { + items: [ + // highlight-start + { + type: 'docsVersionDropdown', + }, + // highlight-end + ], + }, + }, +}; +``` + +The docs version dropdown appears in your navbar: + +![Docs Version Dropdown](./img/docsVersionDropdown.png) + +## Update an existing version + +It is possible to edit versioned docs in their respective folder: + +- `versioned_docs/version-1.0/hello.md` updates `http://localhost:3000/docs/hello` +- `docs/hello.md` updates `http://localhost:3000/docs/next/hello` diff --git a/apps/docs/docs/tutorial-extras/translate-your-site.md b/apps/docs/docs/tutorial-extras/translate-your-site.md new file mode 100644 index 0000000..b5a644a --- /dev/null +++ b/apps/docs/docs/tutorial-extras/translate-your-site.md @@ -0,0 +1,88 @@ +--- +sidebar_position: 2 +--- + +# Translate your site + +Let's translate `docs/intro.md` to French. + +## Configure i18n + +Modify `docusaurus.config.js` to add support for the `fr` locale: + +```js title="docusaurus.config.js" +export default { + i18n: { + defaultLocale: 'en', + locales: ['en', 'fr'], + }, +}; +``` + +## Translate a doc + +Copy the `docs/intro.md` file to the `i18n/fr` folder: + +```bash +mkdir -p i18n/fr/docusaurus-plugin-content-docs/current/ + +cp docs/intro.md i18n/fr/docusaurus-plugin-content-docs/current/intro.md +``` + +Translate `i18n/fr/docusaurus-plugin-content-docs/current/intro.md` in French. + +## Start your localized site + +Start your site on the French locale: + +```bash +npm run start -- --locale fr +``` + +Your localized site is accessible at [http://localhost:3000/fr/](http://localhost:3000/fr/) and the `Getting Started` page is translated. + +:::caution + +In development, you can only use one locale at a time. + +::: + +## Add a Locale Dropdown + +To navigate seamlessly across languages, add a locale dropdown. + +Modify the `docusaurus.config.js` file: + +```js title="docusaurus.config.js" +export default { + themeConfig: { + navbar: { + items: [ + // highlight-start + { + type: 'localeDropdown', + }, + // highlight-end + ], + }, + }, +}; +``` + +The locale dropdown now appears in your navbar: + +![Locale Dropdown](./img/localeDropdown.png) + +## Build your localized site + +Build your site for a specific locale: + +```bash +npm run build -- --locale fr +``` + +Or build your site to include all the locales at once: + +```bash +npm run build +``` diff --git a/apps/docs/docusaurus.config.ts b/apps/docs/docusaurus.config.ts new file mode 100644 index 0000000..671bab5 --- /dev/null +++ b/apps/docs/docusaurus.config.ts @@ -0,0 +1,150 @@ +import {themes as prismThemes} from 'prism-react-renderer'; +import type {Config} from '@docusaurus/types'; +import type * as Preset from '@docusaurus/preset-classic'; + +// This runs in Node.js - Don't use client-side code here (browser APIs, JSX...) + +const config: Config = { + title: 'My Site', + tagline: 'Dinosaurs are cool', + favicon: 'img/favicon.ico', + + // Future flags, see https://docusaurus.io/docs/api/docusaurus-config#future + future: { + v4: true, // Improve compatibility with the upcoming Docusaurus v4 + }, + + // Set the production url of your site here + url: 'https://your-docusaurus-site.example.com', + // Set the // pathname under which your site is served + // For GitHub pages deployment, it is often '//' + baseUrl: '/', + + // GitHub pages deployment config. + // If you aren't using GitHub pages, you don't need these. + organizationName: 'facebook', // Usually your GitHub org/user name. + projectName: 'docusaurus', // Usually your repo name. + + onBrokenLinks: 'throw', + + // Even if you don't use internationalization, you can use this field to set + // useful metadata like html lang. For example, if your site is Chinese, you + // may want to replace "en" with "zh-Hans". + i18n: { + defaultLocale: 'en', + locales: ['en'], + }, + + presets: [ + [ + 'classic', + { + docs: { + sidebarPath: './sidebars.ts', + // Please change this to your repo. + // Remove this to remove the "edit this page" links. + editUrl: + 'https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/', + }, + blog: { + showReadingTime: true, + feedOptions: { + type: ['rss', 'atom'], + xslt: true, + }, + // Please change this to your repo. + // Remove this to remove the "edit this page" links. + editUrl: + 'https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/', + // Useful options to enforce blogging best practices + onInlineTags: 'warn', + onInlineAuthors: 'warn', + onUntruncatedBlogPosts: 'warn', + }, + theme: { + customCss: './src/css/custom.css', + }, + } satisfies Preset.Options, + ], + ], + + themeConfig: { + // Replace with your project's social card + image: 'img/docusaurus-social-card.jpg', + colorMode: { + respectPrefersColorScheme: true, + }, + navbar: { + title: 'My Site', + logo: { + alt: 'My Site Logo', + src: 'img/logo.svg', + }, + items: [ + { + type: 'docSidebar', + sidebarId: 'tutorialSidebar', + position: 'left', + label: 'Tutorial', + }, + {to: '/blog', label: 'Blog', position: 'left'}, + { + href: 'https://github.com/facebook/docusaurus', + label: 'GitHub', + position: 'right', + }, + ], + }, + footer: { + style: 'dark', + links: [ + { + title: 'Docs', + items: [ + { + label: 'Tutorial', + to: '/docs/intro', + }, + ], + }, + { + title: 'Community', + items: [ + { + label: 'Stack Overflow', + href: 'https://stackoverflow.com/questions/tagged/docusaurus', + }, + { + label: 'Discord', + href: 'https://discordapp.com/invite/docusaurus', + }, + { + label: 'X', + href: 'https://x.com/docusaurus', + }, + ], + }, + { + title: 'More', + items: [ + { + label: 'Blog', + to: '/blog', + }, + { + label: 'GitHub', + href: 'https://github.com/facebook/docusaurus', + }, + ], + }, + ], + copyright: `Copyright ยฉ ${new Date().getFullYear()} My Project, Inc. Built with Docusaurus.`, + }, + prism: { + theme: prismThemes.github, + darkTheme: prismThemes.dracula, + }, + } satisfies Preset.ThemeConfig, +}; + +export default config; diff --git a/apps/docs/double-ratchet.md b/apps/docs/double-ratchet.md deleted file mode 100644 index 7923b5b..0000000 --- a/apps/docs/double-ratchet.md +++ /dev/null @@ -1,335 +0,0 @@ -# VerbEth Double Ratchet Protocol - -## Core Design: Ephemeral-Only Initial Secret - -| | Signal X3DH | VerbEth | -|---|---|---| -| Initial secret | `DH(IKa,SPKb) โˆฅ DH(EKa,IKb) โˆฅ DH(EKa,SPKb)` | `DH(EKa, EKb)` | -| Identity keys in secret | Yes | No | -| First message | Encrypted | Plaintext handshake | -| Authentication | Mixed into DH | On-chain `msg.sender` + binding proof | -| Forward secrecy on identity compromise | Initial secret derivable | Initial secret independent | -| Prekey infrastructure | Required | None | - -**The tradeoff:** By accepting a plaintext handshake, VerbEth gains unconditional forward secrecy from message 0 and trustless authentication via Ethereum's transaction model. - ---- - -## Session Model - -### What is a Session? - -A **RatchetSession** is the complete cryptographic state required for bidirectional encrypted messaging. It is: -- **Stateful**: Every encrypt/decrypt operation produces a new session state that must replace the old one -- **Keyed by `conversationId`**: Derived from `keccak256(sort([topicOut, topicIn]))`, not addressesโ€”this handles Safe vs EOA correctly -- **Bilateral**: Both parties maintain symmetric (but not identical) session states - -```typescript -interface RatchetSession { - // Identity - conversationId: string; // Primary key - topicOutbound: `0x${string}`; // My sending topic - topicInbound: `0x${string}`; // My receiving topic - - // Root ratchet - rootKey: Uint8Array; // Advances on every DH ratchet step - - // DH ratchet keys - dhMySecretKey: Uint8Array; // My current DH secret - dhMyPublicKey: Uint8Array; // Sent in message headers - dhTheirPublicKey: Uint8Array; // Their last received DH key - - // Sending chain - sendingChainKey: Uint8Array | null; - sendingMsgNumber: number; // Next message number (Ns) - - // Receiving chain - receivingChainKey: Uint8Array | null; - receivingMsgNumber: number; // Next expected (Nr) - - // Skip handling - previousChainLength: number; // PN header field - skippedKeys: SkippedKey[]; // For out-of-order decryption - - // Metadata - epoch: number; // Increments on session reset - status: SessionStatus; -} -``` - -### Session Initialization - -**Responder (Bob)** creates session when accepting handshake: -``` -sharedSecret = DH(bobEphemeral, aliceEphemeral) -rootKey, sendingChainKey = KDF(zeros, sharedSecret) -``` - -**Initiator (Alice)** creates session after receiving response: -``` -sharedSecret = DH(aliceEphemeral, bobRatchetEphemeral) // From INSIDE payload, not on-chain R -rootKey, bobsSendingChain = KDF(zeros, sharedSecret) -// Immediate DH ratchet step: -aliceDHKeyPair = generateDHKeyPair() -finalRootKey, sendingChainKey = KDF(rootKey, DH(aliceSecret, bobRatchetEphemeral)) -receivingChainKey = bobsSendingChain -``` - -Note: Bob's on-chain `responderEphemeralR` is used only for tag verification. His ratchet ephemeral is inside the encrypted payloadโ€”this provides **unlinkability** between the HandshakeResponse and subsequent messages. - ---- - -## SDK vs App Layer Responsibilities - -| Concern | SDK (`@verbeth/sdk/ratchet`) | App Layer | -|---------|------------------------------|-----------| -| Session state | Produces new immutable session on each operation | Persists session to IndexedDB, manages cache | -| Encryption | `ratchetEncrypt()` โ†’ returns `{session, header, ciphertext, signature}` | Decides when to commit session state | -| Decryption | `ratchetDecrypt()` โ†’ returns `{session, plaintext}` or null | Handles signature verification first | -| Skip keys | Creates/uses/prunes skip keys automatically | Calls `pruneExpiredSkippedKeys()` periodically | -| DoS protection | Provides `verifyMessageSignature()` | Must call before any ratchet operation | -| Two-phase commit | Returns new session without mutating input | Implements commit/rollback logic | -| Concurrent access | None (pure functions) | Must serialize per-conversation | -| Transaction failures | N/A | Decides whether to burn slot or rollback | -| Message queue | N/A | Sequential processing per conversation | - ---- - -## Edge Cases and Crypto Safety - -### Edge Case 1: Out-of-Order Messages - -**Scenario:** Bob sends messages 0, 1, 2. Alice receives 2, then 0, then 1. - -**SDK handling:** -``` -Receive msg 2 (n=2, expected Nr=0): - โ†’ Skip n=0,1: derive and store skip keys for both - โ†’ Decrypt msg 2 with derived key for n=2 - โ†’ Update: Nr=3, skippedKeys=[{n:0}, {n:1}] - -Receive msg 0: - โ†’ Found in skippedKeys โ†’ decrypt, remove from list - -Receive msg 1: - โ†’ Found in skippedKeys โ†’ decrypt, remove from list -``` - -**Bounds:** -- `MAX_SKIP_PER_MESSAGE = 100,000` โ€” rejects messages requiring more skips -- `MAX_STORED_SKIPPED_KEYS = 1,000` โ€” oldest pruned when exceeded -- `MAX_SKIPPED_KEYS_AGE_MS = 24h` โ€” expired keys pruned - -### Edge Case 2: Burned Slots (Failed Sends) - -**Scenario:** Bob encrypts messages 0, 1, 2. Message 1's tx fails. Alice only receives 0 and 2. - -**Why rollback is forbidden:** Rolling back session state would reuse encryption keysโ€”a critical security violation. Each key must be used exactly once. - -**App layer handling (matches Signal):** -```typescript -// useMessageQueue.ts -const { session: nextSession, ... } = ratchetEncrypt(currentSession, plaintext, signingKey); - -// Commit IMMEDIATELY, before tx submission -currentSession = nextSession; -await dbService.saveRatchetSession(nextSession); - -try { - await sendTransaction(payload); -} catch { - // Slot is "burned" โ€” do NOT rollback - // Receiver will create an orphan skip key for n=1 -} -``` - -**Receiver impact:** Alice creates a skip key for n=1 that will never be used. This skip key expires after 24h and is pruned. - -### Edge Case 3: Retry with New Message Number - -**Scenario:** Message "Hello" fails at n=1. User retries. It now encrypts at n=3. - -**This is safe because:** -1. Each slot gets a unique key from chain ratchet -2. Receiver handles gaps via skip keys -3. No cryptographic material is reused -4. Message content can repeat; key material cannot - -**App consideration:** UI should sort by `blockTimestamp`, not message number. The retry appears in chronological order regardless of its `n` value. - -### Edge Case 4: DH Ratchet Advancement - -**Scenario:** Alice and Bob alternate messages (ping-pong pattern). - -**What happens:** -``` -Bobโ†’Alice (msg 0): header.dh = BobDHโ‚€ -Aliceโ†’Bob (msg 0): header.dh = AliceDHโ‚ (new keypair!) - โ†’ Bob performs DH ratchet: new rootKey, new chains -Bobโ†’Alice (msg 0): header.dh = BobDHโ‚ (new keypair!) - โ†’ Alice performs DH ratchet -``` - -Each direction change triggers a DH ratchet step, advancing forward secrecy. Even if an attacker compromises current keys, past messages remain protected. - -### Edge Case 5: Concurrent Sends (App Layer) - -**Scenario:** User clicks send twice rapidly, or sends from multiple tabs. - -**Risk:** Two encryptions read the same session state, both produce n=5, one overwrites the other's session update. - -**App layer solution:** -```typescript -// useMessageQueue.ts - per-conversation queue -const queuesRef = useRef>(new Map()); - -// Sequential processing -while (queue.messages.length > 0) { - const message = queue.messages[0]; - const { session: nextSession } = ratchetEncrypt(currentSession, ...); - currentSession = nextSession; // In-memory update - await dbService.saveRatchetSession(nextSession); // Persist - // ... send tx - queue.messages.shift(); -} -``` - -**Critical:** The in-memory session cache (`sessionCacheRef`) must persist across `processQueue` invocations to prevent race conditions. - -### Edge Case 6: Session Reset (Not Yet Implemented) - -**Scenario:** Keys compromised, or session state corrupted. Need fresh start. - -**Planned approach:** -1. Mark current session as `inactive_reset` -2. Initiate new handshake with fresh ephemeral -3. New session gets incremented `epoch` -4. Old `conversationId` moves to `previousConversationId` on Contact - -**Why epoch matters:** Allows distinguishing messages from old vs new session during transition period. -โš ๏ธ TRADEOFF: Messages sent by Bob after Alice lost state and before - Alice reset are PERMANENTLY LOST from Alice's perspective. - This is inherent to forward secrecy. - ---- - -### State Machine Summary - -``` - โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” - โ”‚ NO SESSION โ”‚ - โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ - โ”‚ Handshake accepted - โ–ผ - โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” - โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–บโ”‚ ACTIVE โ”‚โ—„โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” - โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ - โ”‚ โ”‚ โ”‚ - โ”‚ Send/Receive โ”‚ State lost โ”‚ - โ”‚ (normal ops) โ”‚ โ”‚ - โ”‚ โ–ผ โ”‚ - โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ - โ”‚ โ”‚ INACTIVE_RESET โ”‚ โ”‚ - โ”‚ โ”‚ (waiting peer) โ”‚ โ”‚ - โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ - โ”‚ โ”‚ Peer accepts โ”‚ - โ”‚ โ”‚ reset โ”‚ - โ”‚ โ–ผ โ”‚ - โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ - โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”‚ NEW SESSION โ”‚โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ - โ”‚ (new topics) โ”‚ - โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ - - Old session โ†’ INACTIVE_SUPERSEDED โ†’ FROZEN (archival) -``` - ---- - -## DoS Protection via Signatures - -### The Problem - -Without signatures, an attacker controls how much work you do: -``` -Attacker posts: header = {dh: garbage, pn: 999999, n: 999999} -Victim reads header โ†’ derives ~1M skip keys โ†’ then AEAD fails -Cost: O(N) where attacker controls N -``` - -### The Solution - -Ed25519 signatures are mandatory on all ratchet messages: -``` -Payload = [version (1)] [signature (64)] [dh (32)] [pn (4)] [n (4)] [ciphertext (var)] -``` - -**Verification order:** -```typescript -// App layer MUST do this first -const sigValid = verifyMessageSignature(signature, header, ciphertext, contactSigningPubKey); -if (!sigValid) return; // O(1) rejection, no ratchet operations - -// Only then touch ratchet state -const result = ratchetDecrypt(session, header, ciphertext); -``` - -**Cost comparison:** - -| Attack | Without signatures | With signatures | -|--------|-------------------|-----------------| -| Garbage payload | O(N) skip key derivations | O(1) signature verify | -| Wrong sender | O(N) then AEAD fail | O(1) reject | -| Replay | Depends on n value | O(1) reject (wrong sig) | - ---- - -## Binary Payload Format - -``` -Offset Size Field -โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ -0 1 Version (0x01) -1 64 Ed25519 signature -65 32 DH ratchet public key -97 4 pn (uint32 BE) - previous chain length -101 4 n (uint32 BE) - message number -105 var Ciphertext (nonce + XSalsa20-Poly1305 output) -``` - -Minimum payload: 105 bytes + ciphertext. - ---- - -## KDF Specifications - -**Root key derivation (on DH ratchet step):** -``` -KDF_RK(rk, dh_out) = HKDF-SHA256(ikm=dh_out, salt=rk, info="VerbethRatchet", len=64) - โ†’ new_rk = output[0:32], chain_key = output[32:64] -``` - -**Chain key derivation (per message):** -``` -KDF_CK(ck) = (HMAC-SHA256(ck, 0x02), HMAC-SHA256(ck, 0x01)) - โ†’ new_chain_key, message_key -``` - -**Message encryption:** XSalsa20-Poly1305 (NaCl secretbox) - ---- - -## Summary: What Makes VerbEth Different - -1. **Ephemeral-only initial secret** โ€” No identity keys in DH means unconditional forward secrecy from message 0 - -2. **Trustless authentication** โ€” `msg.sender` is a protocol guarantee; binding proofs tie keys to addresses cryptographically - -3. **No prekey infrastructure** โ€” Bob's ephemeral comes from his live response, not a pre-published bundle - -4. **Burned slots, not rollbacks** โ€” Failed sends consume their slot; receiver's skip keys handle gaps (matches Signal) - -5. **Signatures for DoS protection** โ€” Auth-before-ratchet prevents O(N) attacks from unauthenticated messages - -6. **Session by conversation, not address** โ€” `conversationId` from topics handles Safe/EOA correctly - - diff --git a/apps/docs/metadata-privacy.md b/apps/docs/metadata-privacy.md deleted file mode 100644 index b16890f..0000000 --- a/apps/docs/metadata-privacy.md +++ /dev/null @@ -1,63 +0,0 @@ -# Verbeth Metadata Privacy Model - -## On-Chain Data (Public) - -| Event | Visible Fields | Links Participants? | -|-------|---------------|---------------------| -| **Handshake** | sender, `recipientHash` | โš ๏ธ Confirmable only (requires guessing recipient) | -| **HandshakeResponse** | responder, `inResponseTo` tag | โŒ No (tag is ephemeral-derived) | -| **MessageSent** | sender, `topic`, ciphertext | โŒ No (topic is one-directional) | - -## What Passive Chain Observers Learn - -โœ… **Can determine:** -- Address X uses Verbeth -- Address X sends messages to topic T -- Address X initiated a handshake with *someone* (if recipientHash matched to a guessed address) - -โŒ **Cannot determine:** -- Who receives messages on topic T -- Whether a handshake was accepted (response tag unlinkable) -- That Alice and Bob are conversing (their topics are cryptographically independent) - -## The RPC Problem - -The RPC endpoint sees query parameters, not just on-chain data. - -```typescript -// Alice's RPC sees: -eth_getLogs({ topics: [MessageSent, null, [topicA, topicB, ...]] }) -``` - -| Query Type | RPC Learns | -|------------|------------| -| Handshakes | User's `recipientHash` (trivially reversible) | -| Messages | All active inbound topics for this user | - -**Correlation attack (same RPC):** -``` -Alice queries for topic_X โ†’ RPC logs this -Bob sends to topic_X โ†’ RPC logs this -Conclusion: Bob โ†’ Alice conversation exists -``` - -## Trust Requirements - -| Entity | Trust Level | Justification | -|--------|-------------|---------------| -| Blockchain / Indexers | None required | Cannot link conversations | -| Your RPC provider | **Full trust** | Sees all your topic queries | -| Counterparty's RPC | Independent | Only risks their privacy, not yours | - -## Summary - -Verbeth provides **strong on-chain privacy**: passive observers cannot link conversation participants. The metadata leak is concentrated at the **RPC layer**, which sees topic queries and can correlate them with senders. - -### Mitigation Options - -| Approach | Effectiveness | -|----------|---------------| -| Self-hosted node | Eliminates RPC trust entirely | -| Tor for RPC calls | Hides IP, RPC still sees query content | -| Decoy topic queries | Adds noise, increases bandwidth | -| Rotate RPC endpoints | Dilutes correlation, doesn't eliminate | \ No newline at end of file diff --git a/apps/docs/package.json b/apps/docs/package.json new file mode 100644 index 0000000..e61ba2b --- /dev/null +++ b/apps/docs/package.json @@ -0,0 +1,47 @@ +{ + "name": "docs", + "version": "0.0.0", + "private": true, + "scripts": { + "docusaurus": "docusaurus", + "start": "docusaurus start", + "build": "docusaurus build", + "swizzle": "docusaurus swizzle", + "deploy": "docusaurus deploy", + "clear": "docusaurus clear", + "serve": "docusaurus serve", + "write-translations": "docusaurus write-translations", + "write-heading-ids": "docusaurus write-heading-ids", + "typecheck": "tsc" + }, + "dependencies": { + "@docusaurus/core": "3.9.2", + "@docusaurus/preset-classic": "3.9.2", + "@mdx-js/react": "^3.0.0", + "clsx": "^2.0.0", + "prism-react-renderer": "^2.3.0", + "react": "^19.0.0", + "react-dom": "^19.0.0" + }, + "devDependencies": { + "@docusaurus/module-type-aliases": "3.9.2", + "@docusaurus/tsconfig": "3.9.2", + "@docusaurus/types": "3.9.2", + "typescript": "~5.6.2" + }, + "browserslist": { + "production": [ + ">0.5%", + "not dead", + "not op_mini all" + ], + "development": [ + "last 3 chrome version", + "last 3 firefox version", + "last 5 safari version" + ] + }, + "engines": { + "node": ">=20.0" + } +} diff --git a/apps/docs/replay-protection.md b/apps/docs/replay-protection.md deleted file mode 100644 index 9574935..0000000 --- a/apps/docs/replay-protection.md +++ /dev/null @@ -1,64 +0,0 @@ -# Replay Protection in VerbEth - -VerbEth uses Ethereum event logs as the only transport layer for encrypted messages. -Replay protection is not enforced on-chain and it doesnโ€™t need to be (hence saving on gas). - -## Why? - -Ethereum already gives us: - -- **Sender authentication** via `msg.sender` -- **Spam resistance** via gas costs -- **Immutable message delivery** via event logs -- **Timestamped, ordered history** per sender - -This means every message is: - -- Authenticated by the senderโ€™s Ethereum key -- Costly to publish -- Cryptographically anchored to the chain - -> We rely on AEAD provided by nacl.box (XSalsa20 + Poly1305), -> but avoid additional detached signatures or layered MACs. - ---- - -## So What Does `nonce` Do? - -We include a `uint256 nonce` in each message log event to support: - -- Client-side **message ordering** -- Optional **deduplication** (e.g. prevent duplicate rendering) -- Future support for **group/thread consistency** - -```solidity -event MessageSent( - address indexed sender, - bytes ciphertext, - uint256 timestamp, - bytes32 indexed topic, - uint256 nonce - ); -``` - -But: -๐Ÿ”ธ There is no on-chain enforcement of nonce values -๐Ÿ”ธ Recipients may ignore them entirely or filter replays locally - ---- - -## Should You Verify a Message Wasn't Replayed? - -Only if you want to. The SDK may optionally track `(sender, topic, nonce)` triplets to filter duplicates: - -```ts -const seen = new Set(); -function isReplay(log) { - const key = `${log.sender}:${log.topic}:${log.nonce}`; - if (seen.has(key)) return true; - seen.add(key); - return false; -} -``` - ---- \ No newline at end of file diff --git a/apps/docs/sidebars.ts b/apps/docs/sidebars.ts new file mode 100644 index 0000000..2897139 --- /dev/null +++ b/apps/docs/sidebars.ts @@ -0,0 +1,33 @@ +import type {SidebarsConfig} from '@docusaurus/plugin-content-docs'; + +// This runs in Node.js - Don't use client-side code here (browser APIs, JSX...) + +/** + * Creating a sidebar enables you to: + - create an ordered group of docs + - render a sidebar for each doc of that group + - provide next/previous navigation + + The sidebars can be generated from the filesystem, or explicitly defined here. + + Create as many sidebars as you want. + */ +const sidebars: SidebarsConfig = { + // By default, Docusaurus generates a sidebar from the docs folder structure + tutorialSidebar: [{type: 'autogenerated', dirName: '.'}], + + // But you can create a sidebar manually + /* + tutorialSidebar: [ + 'intro', + 'hello', + { + type: 'category', + label: 'Tutorial', + items: ['tutorial-basics/create-a-document'], + }, + ], + */ +}; + +export default sidebars; diff --git a/apps/docs/src/components/HomepageFeatures/index.tsx b/apps/docs/src/components/HomepageFeatures/index.tsx new file mode 100644 index 0000000..c2551fb --- /dev/null +++ b/apps/docs/src/components/HomepageFeatures/index.tsx @@ -0,0 +1,71 @@ +import type {ReactNode} from 'react'; +import clsx from 'clsx'; +import Heading from '@theme/Heading'; +import styles from './styles.module.css'; + +type FeatureItem = { + title: string; + Svg: React.ComponentType>; + description: ReactNode; +}; + +const FeatureList: FeatureItem[] = [ + { + title: 'Easy to Use', + Svg: require('@site/static/img/undraw_docusaurus_mountain.svg').default, + description: ( + <> + Docusaurus was designed from the ground up to be easily installed and + used to get your website up and running quickly. + + ), + }, + { + title: 'Focus on What Matters', + Svg: require('@site/static/img/undraw_docusaurus_tree.svg').default, + description: ( + <> + Docusaurus lets you focus on your docs, and we'll do the chores. Go + ahead and move your docs into the docs directory. + + ), + }, + { + title: 'Powered by React', + Svg: require('@site/static/img/undraw_docusaurus_react.svg').default, + description: ( + <> + Extend or customize your website layout by reusing React. Docusaurus can + be extended while reusing the same header and footer. + + ), + }, +]; + +function Feature({title, Svg, description}: FeatureItem) { + return ( +
+
+ +
+
+ {title} +

{description}

+
+
+ ); +} + +export default function HomepageFeatures(): ReactNode { + return ( +
+
+
+ {FeatureList.map((props, idx) => ( + + ))} +
+
+
+ ); +} diff --git a/apps/docs/src/components/HomepageFeatures/styles.module.css b/apps/docs/src/components/HomepageFeatures/styles.module.css new file mode 100644 index 0000000..b248eb2 --- /dev/null +++ b/apps/docs/src/components/HomepageFeatures/styles.module.css @@ -0,0 +1,11 @@ +.features { + display: flex; + align-items: center; + padding: 2rem 0; + width: 100%; +} + +.featureSvg { + height: 200px; + width: 200px; +} diff --git a/apps/docs/src/css/custom.css b/apps/docs/src/css/custom.css new file mode 100644 index 0000000..2bc6a4c --- /dev/null +++ b/apps/docs/src/css/custom.css @@ -0,0 +1,30 @@ +/** + * Any CSS included here will be global. The classic template + * bundles Infima by default. Infima is a CSS framework designed to + * work well for content-centric websites. + */ + +/* You can override the default Infima variables here. */ +:root { + --ifm-color-primary: #2e8555; + --ifm-color-primary-dark: #29784c; + --ifm-color-primary-darker: #277148; + --ifm-color-primary-darkest: #205d3b; + --ifm-color-primary-light: #33925d; + --ifm-color-primary-lighter: #359962; + --ifm-color-primary-lightest: #3cad6e; + --ifm-code-font-size: 95%; + --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.1); +} + +/* For readability concerns, you should choose a lighter palette in dark mode. */ +[data-theme='dark'] { + --ifm-color-primary: #25c2a0; + --ifm-color-primary-dark: #21af90; + --ifm-color-primary-darker: #1fa588; + --ifm-color-primary-darkest: #1a8870; + --ifm-color-primary-light: #29d5b0; + --ifm-color-primary-lighter: #32d8b4; + --ifm-color-primary-lightest: #4fddbf; + --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.3); +} diff --git a/apps/docs/src/pages/index.module.css b/apps/docs/src/pages/index.module.css new file mode 100644 index 0000000..9f71a5d --- /dev/null +++ b/apps/docs/src/pages/index.module.css @@ -0,0 +1,23 @@ +/** + * CSS files with the .module.css suffix will be treated as CSS modules + * and scoped locally. + */ + +.heroBanner { + padding: 4rem 0; + text-align: center; + position: relative; + overflow: hidden; +} + +@media screen and (max-width: 996px) { + .heroBanner { + padding: 2rem; + } +} + +.buttons { + display: flex; + align-items: center; + justify-content: center; +} diff --git a/apps/docs/src/pages/index.tsx b/apps/docs/src/pages/index.tsx new file mode 100644 index 0000000..2e006d1 --- /dev/null +++ b/apps/docs/src/pages/index.tsx @@ -0,0 +1,44 @@ +import type {ReactNode} from 'react'; +import clsx from 'clsx'; +import Link from '@docusaurus/Link'; +import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; +import Layout from '@theme/Layout'; +import HomepageFeatures from '@site/src/components/HomepageFeatures'; +import Heading from '@theme/Heading'; + +import styles from './index.module.css'; + +function HomepageHeader() { + const {siteConfig} = useDocusaurusContext(); + return ( +
+
+ + {siteConfig.title} + +

{siteConfig.tagline}

+
+ + Docusaurus Tutorial - 5min โฑ๏ธ + +
+
+
+ ); +} + +export default function Home(): ReactNode { + const {siteConfig} = useDocusaurusContext(); + return ( + + +
+ +
+
+ ); +} diff --git a/apps/docs/src/pages/markdown-page.md b/apps/docs/src/pages/markdown-page.md new file mode 100644 index 0000000..9756c5b --- /dev/null +++ b/apps/docs/src/pages/markdown-page.md @@ -0,0 +1,7 @@ +--- +title: Markdown page example +--- + +# Markdown page example + +You don't need React to write simple standalone pages. diff --git a/apps/docs/static/.nojekyll b/apps/docs/static/.nojekyll new file mode 100644 index 0000000..e69de29 diff --git a/apps/docs/static/img/docusaurus-social-card.jpg b/apps/docs/static/img/docusaurus-social-card.jpg new file mode 100644 index 0000000000000000000000000000000000000000..ffcb448210e1a456cb3588ae8b396a597501f187 GIT binary patch literal 55746 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 fgzs%Vr*-jYG(YMS<ttdtee# literal 0 HcmV?d00001 diff --git a/apps/docs/static/img/docusaurus.png b/apps/docs/static/img/docusaurus.png new file mode 100644 index 0000000000000000000000000000000000000000..f458149e3c8f53335f28fbc162ae67f55575c881 GIT binary patch literal 5142 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 F{0H{b<4^zq literal 0 HcmV?d00001 diff --git a/apps/docs/static/img/favicon.ico b/apps/docs/static/img/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..c01d54bcd39a5f853428f3cd5aa0f383d963c484 GIT binary patch literal 3626 zcmb`Je@s(X6vrR`EK3%b%orErlDW({vnABqA zcfaS{d+xbU5JKp0*;0YOg+;Fl!eT)XRuapIwFLL`=imZCSon$`se`_<%@MB=M~KG+ z=EW^FL`w|Bo>*ktlaS^(fut!95`iG5u=SZ8nfDHO#GaTlH1-XG^;vsjUb^gWTVz0+ z^=WR1wv9-2oeR=_;fL0H7rNWqAzGtO(D;`~cX(RcN0w2v24Y8)6t`cS^_ghs`_ho? z{0ka~1Dgo8TfAP$r*ua?>$_V+kZ!-(TvEJ7O2f;Y#tezt$&R4 zLI}=-y@Z!grf*h3>}DUL{km4R>ya_I5Ag#{h_&?+HpKS!;$x3LC#CqUQ8&nM?X))Q zXAy2?`YL4FbC5CgJu(M&Q|>1st8XXLZ|5MgwgjP$m_2Vt0(J z&Gu7bOlkbGzGm2sh?X`){7w69Y$1#@P@7DF{ZE=4%T0NDS)iH`tiPSKpDNW)zmtn( zw;4$f>k)4$LBc>eBAaTZeCM2(iD+sHlj!qd z2GjRJ>f_Qes(+mnzdA^NH?^NB(^o-%Gmg$c8MNMq&`vm@9Ut;*&$xSD)PKH{wBCEC z4P9%NQ;n2s59ffMn8*5)5AAg4-93gBXBDX`A7S& zH-|%S3Wd%T79fk-e&l`{!?lve8_epXhE{d3Hn$Cg!t=-4D(t$cK~7f&4s?t7wr3ZP z*!SRQ-+tr|e1|hbc__J`k3S!rMy<0PHy&R`v#aJv?`Y?2{avK5sQz%=Us()jcNuZV z*$>auD4cEw>;t`+m>h?f?%VFJZj8D|Y1e_SjxG%J4{-AkFtT2+ZZS5UScS~%;dp!V>)7zi`w(xwSd*FS;Lml=f6hn#jq)2is4nkp+aTrV?)F6N z>DY#SU0IZ;*?Hu%tSj4edd~kYNHMFvS&5}#3-M;mBCOCZL3&;2obdG?qZ>rD|zC|Lu|sny76pn2xl|6sk~Hs{X9{8iBW zwiwgQt+@hi`FYMEhX2 \ No newline at end of file diff --git a/apps/docs/static/img/undraw_docusaurus_mountain.svg b/apps/docs/static/img/undraw_docusaurus_mountain.svg new file mode 100644 index 0000000..af961c4 --- /dev/null +++ b/apps/docs/static/img/undraw_docusaurus_mountain.svg @@ -0,0 +1,171 @@ + + Easy to Use + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/docs/static/img/undraw_docusaurus_react.svg b/apps/docs/static/img/undraw_docusaurus_react.svg new file mode 100644 index 0000000..94b5cf0 --- /dev/null +++ b/apps/docs/static/img/undraw_docusaurus_react.svg @@ -0,0 +1,170 @@ + + Powered by React + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/docs/static/img/undraw_docusaurus_tree.svg b/apps/docs/static/img/undraw_docusaurus_tree.svg new file mode 100644 index 0000000..d9161d3 --- /dev/null +++ b/apps/docs/static/img/undraw_docusaurus_tree.svg @@ -0,0 +1,40 @@ + + Focus on What Matters + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/docs/topic-ratcheting.md b/apps/docs/topic-ratcheting.md deleted file mode 100644 index 2f4d230..0000000 --- a/apps/docs/topic-ratcheting.md +++ /dev/null @@ -1,165 +0,0 @@ -# Topic Ratcheting Mechanism - -This document explains how Verbeth synchronizes topic rotation with the Double Ratchet DH steps, providing forward secrecy at the network layer. - -## Core Principle - -Topics rotate alongside DH ratchet steps. Each new DH shared secret deterministically derives new topics via HKDF, ensuring that compromising a topic reveals nothing about past or future topics. - -``` -DH Ratchet Step โ†’ New DH Shared Secret โ†’ deriveTopicFromDH() โ†’ New Topics -``` - ---- - -## SDK Layer - -### Session State (RatchetSession) - -| Field | Purpose | -|-------|---------| -| `currentTopicOutbound` | Topic for sending messages now | -| `currentTopicInbound` | Topic for receiving messages now | -| `nextTopicOutbound/Inbound` | Pre-computed topics for incoming DH ratchet | -| `previousTopicInbound` | Grace period topic (5 min) | -| `previousTopicExpiry` | Timestamp when previous topic expires | -| `topicEpoch` | Counter for debugging | - -### Topic Derivation (`kdf.ts`) - -```typescript -deriveTopicFromDH(dhSharedSecret, direction, salt) โ†’ bytes32 topic -``` - -Direction labels (`'outbound'`/`'inbound'`) ensure asymmetric topics. The sender's outbound is the receiver's inbound. - -### On Encrypt (`encrypt.ts`) - -Uses `session.currentTopicOutbound`. No topic changes on sendโ€”topics only rotate on DH ratchet (when receiving). - -### On Decrypt (`decrypt.ts` โ†’ `dhRatchetStep`) - -When a message carries a new DH public key: - -1. Compute `dhReceive = DH(mySecret, theirNewPub)` -2. Derive new receiving chain from `dhReceive` -3. Generate new DH keypair for response -4. Compute `dhSend = DH(newSecret, theirNewPub)` -5. **Derive topics from `dhReceive`** (labels swapped since we're receiver): - - `newTopicOut = deriveTopicFromDH(dhReceive, 'inbound', salt)` - - `newTopicIn = deriveTopicFromDH(dhReceive, 'outbound', salt)` -6. **Pre-compute next topics from `dhSend`** (for when peer ratchets): - - `nextTopicOut = deriveTopicFromDH(dhSend, 'outbound', salt)` - - `nextTopicIn = deriveTopicFromDH(dhSend, 'inbound', salt)` -7. Archive current inbound as `previousTopicInbound` with 5-min expiry - ---- - -## App Layer - -### Sending (`useMessageQueue.ts`) - -```typescript -const { topic: ratchetedTopic } = ratchetEncrypt(session, plaintext, signingKey); -await executor.sendMessage(payload, ratchetedTopic, timestamp, nonce); -``` - -The topic comes from `EncryptResult.topic`, which is `session.currentTopicOutbound`. - -### Receiving (`EventProcessorService.ts`) - -1. **Multi-topic lookup**: `getRatchetSessionByAnyInboundTopic(topic)` queries: - - `currentTopicInbound` (primary) - - `nextTopicInbound` (pre-computed for incoming ratchet) - - `previousTopicInbound` (if within grace period) - -2. **Topic promotion**: If message arrives on `nextTopicInbound`: - ```typescript - previousTopicInbound = currentTopicInbound; - previousTopicExpiry = now + 5min; - currentTopicInbound = nextTopicInbound; - currentTopicOutbound = nextTopicOutbound; - nextTopicInbound = undefined; - topicEpoch++; - ``` - -3. **Decryption**: `ratchetDecrypt()` may trigger another DH ratchet step internally, updating topics again. - -### Event Filtering (`useMessageListener.ts`) - -```typescript -const activeTopics = await dbService.getAllActiveInboundTopics(address); -// Returns: current + next + non-expired previous topics for all sessions -``` - -Blockchain log queries filter by all active topics to catch messages during transitions. - -### Database Indexing (`schema.ts`) - -```typescript -ratchetSessions: "conversationId, ..., currentTopicInbound, nextTopicInbound, previousTopicInbound, ..." -``` - -Enables O(1) lookups by any topic variant. - ---- - -## Scenario Handling - -| Scenario | Mechanism | -|----------|-----------| -| **Sequential messages** | Same topic, no ratchet needed | -| **Peer ratchets** | Message on `nextTopicInbound` โ†’ promote topics | -| **Late message on old topic** | `previousTopicInbound` with grace period | -| **Out-of-order within epoch** | Skip keys (topic unchanged) | -| **Session reset** | New handshake โ†’ fresh epoch 0 topics | - ---- - -## Developer Conventions - -1. **Session persistence**: Always save after `ratchetDecrypt()` returnsโ€”topics may have changed. - -2. **Cache by conversationId, not topic**: Topics change; `conversationId` is stable. - -3. **Immediate session commit on encrypt**: Persist before sending tx (two-phase commit protects against slot loss). - -4. **Contact sync**: After processing, update `contact.topicOutbound/Inbound` from session state. - -5. **Grace period**: 5 minutes (`TOPIC_TRANSITION_WINDOW_MS`). Don't rely on longer windows. - -6. **Never filter by single topic**: Always use `getAllActiveInboundTopics()` for event queries. - ---- - -## Typical Flow - -Handshake Exchange - โ†“ -Seed Topic (from ephemeral DH) โ† both parties compute this - โ†“ -First Message (Alice โ†’ Bob on seed topic, includes new DH pub) - โ†“ -DH Ratchet โ†’ New Topics (from message DH) - โ†“ -Subsequent messages use ratcheted topics - -``` -Alice (Initiator) Bob (Responder) -โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ -Epoch 0: handshake topics Epoch 0: handshake topics - -Send msg on topicOutโ‚€ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–บ Receive on topicInโ‚€ - DH ratchet โ†’ Epoch 1 - (next topics pre-computed) - - โ—„โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ Send msg on topicOutโ‚ -Receive on nextTopicIn -Promote โ†’ Epoch 1 -DH ratchet โ†’ pre-compute Epoch 2 - -Send msg on topicOutโ‚ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–บ Receive on topicInโ‚ - ... -``` - -Each direction independently advances its topic epoch when receiving a new DH public key. \ No newline at end of file diff --git a/apps/docs/tsconfig.json b/apps/docs/tsconfig.json new file mode 100644 index 0000000..920d7a6 --- /dev/null +++ b/apps/docs/tsconfig.json @@ -0,0 +1,8 @@ +{ + // This file is not used in compilation. It is here just for a nice editor experience. + "extends": "@docusaurus/tsconfig", + "compilerOptions": { + "baseUrl": "." + }, + "exclude": [".docusaurus", "build"] +} diff --git a/packages/sdk/package.json b/packages/sdk/package.json index b41026d..971288e 100644 --- a/packages/sdk/package.json +++ b/packages/sdk/package.json @@ -17,6 +17,7 @@ "dependencies": { "@noble/curves": "^1.8.1", "@noble/hashes": "^1.8.0", + "@noble/post-quantum": "^0.5.4", "@noble/secp256k1": "^2.2.3", "ethers": "^6.7.0", "tweetnacl": "^1.0.3", diff --git a/packages/sdk/src/client/PendingManager.ts b/packages/sdk/src/client/PendingManager.ts index f973c0b..93991d5 100644 --- a/packages/sdk/src/client/PendingManager.ts +++ b/packages/sdk/src/client/PendingManager.ts @@ -102,10 +102,6 @@ export class PendingManager { await this.store.delete(id); } - // =========================================================================== - // Batch Operations - // =========================================================================== - /** * Clean up stale pending messages. * Called periodically to remove old failed/stuck records. diff --git a/packages/sdk/src/client/VerbethClient.ts b/packages/sdk/src/client/VerbethClient.ts index 5c3a045..7ac19d3 100644 --- a/packages/sdk/src/client/VerbethClient.ts +++ b/packages/sdk/src/client/VerbethClient.ts @@ -14,6 +14,7 @@ import { hexlify, getBytes } from 'ethers'; import { initiateHandshake, respondToHandshake } from '../send.js'; +import { kem } from '../pq/kem.js'; import type { IExecutor } from '../executor.js'; import type { IdentityKeyPair, IdentityProof } from '../types.js'; import type { Signer } from 'ethers'; @@ -53,6 +54,8 @@ export interface CreateInitiatorSessionParams { initiatorEphemeralSecret: Uint8Array; responderEphemeralPubKey: Uint8Array; inResponseToTag: `0x${string}`; + kemCiphertext?: Uint8Array; // from handshake response (for KEM decapsulation) + initiatorKemSecret?: Uint8Array; // stored from sendHandshake } export interface CreateResponderSessionParams { @@ -61,6 +64,7 @@ export interface CreateResponderSessionParams { responderEphemeralPublic: Uint8Array; initiatorEphemeralPubKey: Uint8Array; salt: Uint8Array; + kemSharedSecret?: Uint8Array; // from acceptHandshake (for hybrid KDF) } export class VerbethClient { @@ -107,20 +111,20 @@ export class VerbethClient { /** * Initiates a handshake with a recipient. - * - * Generates an ephemeral keypair for this handshake. - * The ephemeralKeyPair.secretKey must be stored for ratchet session initialization + * + * Generates an ephemeral keypair and ML-KEM keypair for this handshake. + * Both secretKeys must be stored for ratchet session initialization * when the response arrives. - * + * * @param recipientAddress - Blockchain address of the recipient * @param message - Plaintext message to include in the handshake - * @returns Transaction response and the ephemeral keypair + * @returns Transaction response, ephemeral keypair, and KEM keypair */ async sendHandshake( recipientAddress: string, message: string ): Promise { - const { tx, ephemeralKeyPair } = await initiateHandshake({ + const { tx, ephemeralKeyPair, kemKeyPair } = await initiateHandshake({ executor: this.executor, recipientAddress, identityKeyPair: this.identityKeyPair, @@ -129,32 +133,36 @@ export class VerbethClient { signer: this.signer, }); - return { tx, ephemeralKeyPair }; + return { tx, ephemeralKeyPair, kemKeyPair }; } /** * Accepts a handshake from an initiator. - * + * * Derives topics from ephemeral DH shared secret (same approach * as post-handshake topic ratcheting). Returns topicOutbound/topicInbound * directly instead of duplexTopics structure. - * - * @param initiatorEphemeralPubKey - Initiator's ephemeral public key from handshake event + * + * Supports PQ-hybrid: if initiator includes ML-KEM public key (1216 bytes), + * performs KEM encapsulation and returns kemSharedSecret. + * + * @param initiatorEphemeralPubKey - Initiator's ephemeral key (32 bytes X25519 or 1216 bytes with KEM) * @param initiatorIdentityPubKey - Initiator's long-term X25519 identity key (kept for future use) * @param note - Response message to send back - * @returns Transaction, derived topics, and ephemeral keys for ratchet + * @returns Transaction, derived topics, ephemeral keys for ratchet, and KEM shared secret */ async acceptHandshake( initiatorEphemeralPubKey: Uint8Array, initiatorIdentityPubKey: Uint8Array, // Kept for potential future use note: string ): Promise { - const { - tx, - salt, + const { + tx, + salt, tag, responderEphemeralSecret, responderEphemeralPublic, + kemSharedSecret, } = await respondToHandshake({ executor: this.executor, initiatorEphemeralPubKey, @@ -164,21 +172,27 @@ export class VerbethClient { signer: this.signer, }); + // Extract X25519 part for topic derivation (first 32 bytes if extended) + const x25519Pub = initiatorEphemeralPubKey.length > 32 + ? initiatorEphemeralPubKey.slice(0, 32) + : initiatorEphemeralPubKey; + const { topicOutbound, topicInbound } = this.deriveTopicsFromDH( responderEphemeralSecret, - initiatorEphemeralPubKey, + x25519Pub, salt, false // responder swaps labels ); - return { - tx, + return { + tx, topicOutbound, topicInbound, tag, salt, responderEphemeralSecret, responderEphemeralPublic, + kemSharedSecret, }; } @@ -188,16 +202,32 @@ export class VerbethClient { /** * Create a ratchet session as the handshake initiator. - * + * * Call this after receiving and validating a handshake response. * Handles topic derivation from ephemeral DH internally. - * + * + * If KEM ciphertext and secret are provided (PQ-hybrid), decapsulates + * to derive hybrid shared secret for post-quantum security. + * * @param params - Session creation parameters * @returns Ready-to-save RatchetSession */ createInitiatorSession(params: CreateInitiatorSessionParams): RatchetSession { - const { contactAddress, initiatorEphemeralSecret, responderEphemeralPubKey, inResponseToTag } = params; - + const { + contactAddress, + initiatorEphemeralSecret, + responderEphemeralPubKey, + inResponseToTag, + kemCiphertext, + initiatorKemSecret, + } = params; + + // Decapsulate KEM if present + let kemSecret: Uint8Array | undefined; + if (kemCiphertext && initiatorKemSecret) { + kemSecret = kem.decapsulate(kemCiphertext, initiatorKemSecret); + } + const salt = getBytes(inResponseToTag); const { topicOutbound, topicInbound } = this.deriveTopicsFromDH( initiatorEphemeralSecret, @@ -213,25 +243,41 @@ export class VerbethClient { theirResponderEphemeralPubKey: responderEphemeralPubKey, topicOutbound, topicInbound, + kemSecret, }); } /** * Create a ratchet session as the handshake responder. - * + * * Call this after sending a handshake response. * Handles topic derivation from ephemeral DH internally. - * + * + * If kemSharedSecret is provided (PQ-hybrid), uses hybrid KDF + * for post-quantum security. + * * @param params - Session creation parameters * @returns Ready-to-save RatchetSession */ createResponderSession(params: CreateResponderSessionParams): RatchetSession { - const { contactAddress, responderEphemeralSecret, responderEphemeralPublic, initiatorEphemeralPubKey, salt } = params; - - const { topicOutbound, topicInbound } = this.deriveTopicsFromDH( + const { + contactAddress, responderEphemeralSecret, + responderEphemeralPublic, initiatorEphemeralPubKey, salt, + kemSharedSecret, + } = params; + + // Extract X25519 part for topic derivation (first 32 bytes if extended) + const x25519Pub = initiatorEphemeralPubKey.length > 32 + ? initiatorEphemeralPubKey.slice(0, 32) + : initiatorEphemeralPubKey; + + const { topicOutbound, topicInbound } = this.deriveTopicsFromDH( + responderEphemeralSecret, + x25519Pub, + salt, false // responder swaps labels ); @@ -240,9 +286,10 @@ export class VerbethClient { contactAddress, myResponderEphemeralSecret: responderEphemeralSecret, myResponderEphemeralPublic: responderEphemeralPublic, - theirHandshakeEphemeralPubKey: initiatorEphemeralPubKey, + theirHandshakeEphemeralPubKey: x25519Pub, topicOutbound, topicInbound, + kemSecret: kemSharedSecret, }); } @@ -559,67 +606,50 @@ export class VerbethClient { // Low-level API Access // =========================================================================== - /** Crypto utilities */ get crypto() { return crypto; } - /** Payload encoding utilities */ get payload() { return payload; } - /** Verification utilities */ get verify() { return verify; } - /** General utilities */ get utils() { return utils; } - /** Identity derivation utilities */ get identity() { return identity; } - /** Double ratchet module */ get ratchet() { return ratchet; } - /** Executor instance for direct access */ get executorInstance(): IExecutor { return this.executor; } - /** Identity keypair for direct access */ get identityKeyPairInstance(): IdentityKeyPair { return this.identityKeyPair; } - /** User's address */ get userAddress(): string { return this.address; } - /** Identity proof for direct access */ get identityProofInstance(): IdentityProof { return this.identityProof; } - /** - * Generate unique ID for prepared messages. - */ private generatePreparedId(): string { return `prep-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`; } - /** - * Serialize session info for storage. - * Used in pending records for debugging/recovery. - */ private serializeSessionInfo(session: RatchetSession): SerializedSessionInfo { return { conversationId: session.conversationId, diff --git a/packages/sdk/src/client/types.ts b/packages/sdk/src/client/types.ts index 240d500..316cf31 100644 --- a/packages/sdk/src/client/types.ts +++ b/packages/sdk/src/client/types.ts @@ -12,6 +12,7 @@ import type { IExecutor } from '../executor.js'; import type { IdentityKeyPair, IdentityProof } from '../types.js'; import type { RatchetSession } from '../ratchet/types.js'; import type nacl from 'tweetnacl'; +import type { KemKeyPair } from '../send.js'; /** * Configuration for creating a VerbethClient instance. @@ -27,16 +28,18 @@ export interface VerbethClientConfig { export interface HandshakeResult { tx: any; ephemeralKeyPair: nacl.BoxKeyPair; // must persist secretKey for ratchet session init + kemKeyPair: KemKeyPair; // must persist secretKey for KEM decapsulation } export interface HandshakeResponseResult { tx: any; - topicOutbound: `0x${string}`; - topicInbound: `0x${string}`; + topicOutbound: `0x${string}`; + topicInbound: `0x${string}`; tag: `0x${string}`; salt: Uint8Array; responderEphemeralSecret: Uint8Array; // must persist as dhMySecretKey in ratchet responderEphemeralPublic: Uint8Array; + kemSharedSecret?: Uint8Array; // from KEM encapsulation (32 bytes) - for hybrid KDF } /** diff --git a/packages/sdk/src/crypto.ts b/packages/sdk/src/crypto.ts index ab1cf64..49031b6 100644 --- a/packages/sdk/src/crypto.ts +++ b/packages/sdk/src/crypto.ts @@ -106,6 +106,7 @@ export function decryptHandshakeResponse( return { unifiedPubKeys: Uint8Array.from(Buffer.from(obj.unifiedPubKeys, 'base64')), ephemeralPubKey: Uint8Array.from(Buffer.from(obj.ephemeralPubKey, 'base64')), + ...(obj.kemCiphertext && { kemCiphertext: Uint8Array.from(Buffer.from(obj.kemCiphertext, 'base64')) }), note: obj.note, identityProof: obj.identityProof, // topicInfo removed - no longer needed @@ -124,19 +125,21 @@ export function decryptAndExtractHandshakeKeys( identityPubKey: Uint8Array; signingPubKey: Uint8Array; ephemeralPubKey: Uint8Array; + kemCiphertext?: Uint8Array; note?: string; - identityProof: IdentityProof; + identityProof: IdentityProof; } | null { const decrypted = decryptHandshakeResponse(payloadJson, initiatorEphemeralSecretKey); if (!decrypted) return null; - + const extracted = extractKeysFromHandshakeResponse(decrypted); if (!extracted) return null; - + return { identityPubKey: extracted.identityPubKey, signingPubKey: extracted.signingPubKey, ephemeralPubKey: extracted.ephemeralPubKey, + kemCiphertext: decrypted.kemCiphertext, note: decrypted.note, identityProof: decrypted.identityProof }; diff --git a/packages/sdk/src/index.ts b/packages/sdk/src/index.ts index bdfe18d..96f3c71 100644 --- a/packages/sdk/src/index.ts +++ b/packages/sdk/src/index.ts @@ -70,4 +70,6 @@ export type { } from './client/index.js'; export * from './ratchet/index.js'; -export { dh, deriveTopicFromDH } from './ratchet/kdf.js'; \ No newline at end of file +export { dh, deriveTopicFromDH, hybridInitialSecret } from './ratchet/kdf.js'; + +export { kem } from './pq/kem.js'; \ No newline at end of file diff --git a/packages/sdk/src/payload.ts b/packages/sdk/src/payload.ts index 32e1260..cc4021f 100644 --- a/packages/sdk/src/payload.ts +++ b/packages/sdk/src/payload.ts @@ -161,18 +161,12 @@ export interface HandshakePayload { plaintextPayload: string; } -/** - * HandshakeResponseContent - CLEANED - * - * REMOVED: topicInfo field - topics are now derived from ephemeral DH - * in the caller (VerbethClient.acceptHandshake and EventProcessorService) - */ export interface HandshakeResponseContent { unifiedPubKeys: Uint8Array; // 65 bytes: version + X25519 + Ed25519 ephemeralPubKey: Uint8Array; + kemCiphertext?: Uint8Array; // ML-KEM-768 ciphertext (1088 bytes) for PQ hybrid handshake note?: string; identityProof: IdentityProof; - // REMOVED: topicInfo?: TopicInfoWire; } export function encodeHandshakePayload(payload: HandshakePayload): Uint8Array { @@ -193,37 +187,28 @@ export function decodeHandshakePayload(encoded: Uint8Array): HandshakePayload { }; } -/** - * Encodes HandshakeResponseContent - CLEANED - * - * REMOVED: topicInfo encoding - no longer included in handshake response - */ export function encodeHandshakeResponseContent(content: HandshakeResponseContent): Uint8Array { return new TextEncoder().encode(JSON.stringify({ unifiedPubKeys: Buffer.from(content.unifiedPubKeys).toString('base64'), ephemeralPubKey: Buffer.from(content.ephemeralPubKey).toString('base64'), + ...(content.kemCiphertext && { kemCiphertext: Buffer.from(content.kemCiphertext).toString('base64') }), note: content.note, identityProof: content.identityProof, - // REMOVED: topicInfo encoding })); } -/** - * Decodes HandshakeResponseContent - CLEANED - * - * REMOVED: topicInfo decoding - no longer expected in handshake response - */ export function decodeHandshakeResponseContent(encoded: Uint8Array): HandshakeResponseContent { const json = new TextDecoder().decode(encoded); const obj = JSON.parse(json); - + if (!obj.identityProof) { throw new Error("Invalid handshake response: missing identityProof"); } - + return { unifiedPubKeys: Uint8Array.from(Buffer.from(obj.unifiedPubKeys, 'base64')), ephemeralPubKey: Uint8Array.from(Buffer.from(obj.ephemeralPubKey, 'base64')), + ...(obj.kemCiphertext && { kemCiphertext: Uint8Array.from(Buffer.from(obj.kemCiphertext, 'base64')) }), note: obj.note, identityProof: obj.identityProof, // REMOVED: topicInfo decoding @@ -246,29 +231,24 @@ export function createHandshakePayload( }; } -/** - * Creates HandshakeResponseContent from separate identity keys - CLEANED - * - * REMOVED: topicInfo parameter - topics are now derived from ephemeral DH - */ export function createHandshakeResponseContent( identityPubKey: Uint8Array, signingPubKey: Uint8Array, ephemeralPubKey: Uint8Array, note?: string, identityProof?: IdentityProof, - // REMOVED: topicInfo?: TopicInfoWire parameter + kemCiphertext?: Uint8Array, ): HandshakeResponseContent { if (!identityProof) { throw new Error("Identity proof is now mandatory for handshake responses"); } - + return { unifiedPubKeys: encodeUnifiedPubKeys(identityPubKey, signingPubKey), ephemeralPubKey, + ...(kemCiphertext && { kemCiphertext }), note, identityProof, - // REMOVED: topicInfo field }; } diff --git a/packages/sdk/src/pq/kem.ts b/packages/sdk/src/pq/kem.ts new file mode 100644 index 0000000..786e5c2 --- /dev/null +++ b/packages/sdk/src/pq/kem.ts @@ -0,0 +1,46 @@ +// packages/sdk/src/pq/kem.ts + +/** + * ML-KEM-768 Key Encapsulation Mechanism wrapper. + * + * Provides post-quantum key encapsulation for hybrid handshakes. + */ + +import { ml_kem768 } from '@noble/post-quantum/ml-kem.js'; + +export const kem = { + publicKeyBytes: 1184, // in bytes + ciphertextBytes: 1088, + sharedSecretBytes: 32, + + /** + * Generate a new ML-KEM-768 keypair. + * + * @returns Object containing publicKey and secretKey + */ + generateKeyPair(): { publicKey: Uint8Array; secretKey: Uint8Array } { + return ml_kem768.keygen(); + }, + + /** + * Encapsulate a shared secret using the recipient's public key. + * + * @param publicKey - Recipient's ML-KEM-768 public key + * @returns Object containing ciphertext and sharedSecret + */ + encapsulate(publicKey: Uint8Array): { ciphertext: Uint8Array; sharedSecret: Uint8Array } { + const result = ml_kem768.encapsulate(publicKey); + return { ciphertext: result.cipherText, sharedSecret: result.sharedSecret }; + }, + + /** + * Decapsulate a ciphertext using the secret key to recover the shared secret. + * + * @param ciphertext - KEM ciphertext + * @param secretKey - Recipient's ML-KEM-768 secret key + * @returns Shared secret + */ + decapsulate(ciphertext: Uint8Array, secretKey: Uint8Array): Uint8Array { + return ml_kem768.decapsulate(ciphertext, secretKey); + } +}; diff --git a/packages/sdk/src/ratchet/index.ts b/packages/sdk/src/ratchet/index.ts index 3610c12..9be2629 100644 --- a/packages/sdk/src/ratchet/index.ts +++ b/packages/sdk/src/ratchet/index.ts @@ -26,6 +26,7 @@ export { dh, generateDHKeyPair, deriveTopicFromDH, + hybridInitialSecret, } from './kdf.js'; export { diff --git a/packages/sdk/src/ratchet/kdf.ts b/packages/sdk/src/ratchet/kdf.ts index a72d856..9d99c22 100644 --- a/packages/sdk/src/ratchet/kdf.ts +++ b/packages/sdk/src/ratchet/kdf.ts @@ -92,4 +92,21 @@ export function deriveTopicFromDH( const info = `verbeth:topic-${direction}:v2`; const okm = hkdf(sha256, dhSharedSecret, salt, info, 32); return keccak256(okm) as `0x${string}`; +} + +/** + * Combines classical (X25519) and post-quantum (ML-KEM-768) key exchange + * + * @param x25519Secret - X25519 DH shared secret (32 bytes) + * @param kemSecret - ML-KEM-768 shared secret (32 bytes) + * @returns Hybrid shared secret (32 bytes) + */ +export function hybridInitialSecret( + x25519Secret: Uint8Array, + kemSecret: Uint8Array +): Uint8Array { + const combined = new Uint8Array(x25519Secret.length + kemSecret.length); + combined.set(x25519Secret, 0); + combined.set(kemSecret, x25519Secret.length); + return hkdf(sha256, combined, new Uint8Array(32), 'VerbethHybrid', 32); } \ No newline at end of file diff --git a/packages/sdk/src/ratchet/session.ts b/packages/sdk/src/ratchet/session.ts index 6d20c28..669efb6 100644 --- a/packages/sdk/src/ratchet/session.ts +++ b/packages/sdk/src/ratchet/session.ts @@ -10,12 +10,12 @@ */ import { keccak256, toUtf8Bytes, getBytes } from 'ethers'; -import { - RatchetSession, - InitResponderParams, +import { + RatchetSession, + InitResponderParams, InitInitiatorParams, } from './types.js'; -import { kdfRootKey, dh, generateDHKeyPair, deriveTopicFromDH } from './kdf.js'; +import { kdfRootKey, dh, generateDHKeyPair, deriveTopicFromDH, hybridInitialSecret } from './kdf.js'; /** * Compute deterministic conversation ID from topics. @@ -32,13 +32,16 @@ export function computeConversationId(topicA: string, topicB: string): string { /** * Initialize session as responder (Bob). - * + * * Called after receiving handshake, before/during sending response. * The responder must persist myResponderEphemeralSecret immediately. * This becomes dhMySecretKey and is required for all future ratchet operations. - * + * * Responder starts at epoch 0 (handshake topics). - * + * + * If kemSecret is provided (from ML-KEM encapsulation), uses hybrid KDF + * combining X25519 DH and ML-KEM for post-quantum security. + * * @param params - Initialization parameters * @returns Initialized ratchet session */ @@ -51,9 +54,14 @@ export function initSessionAsResponder(params: InitResponderParams): RatchetSess theirHandshakeEphemeralPubKey, topicOutbound, topicInbound, + kemSecret, } = params; - const sharedSecret = dh(myResponderEphemeralSecret, theirHandshakeEphemeralPubKey); + const x25519Secret = dh(myResponderEphemeralSecret, theirHandshakeEphemeralPubKey); + + const sharedSecret = kemSecret + ? hybridInitialSecret(x25519Secret, kemSecret) + : x25519Secret; // Derive initial root key and sending chain key const { rootKey, chainKey: sendingChainKey } = kdfRootKey( @@ -102,13 +110,16 @@ export function initSessionAsResponder(params: InitResponderParams): RatchetSess /** * Initialize session as initiator (Alice). - * + * * Called after receiving and validating handshake response. - * + * * Initiator precomputes epoch 1 topics from its first post-handshake DH step. * Outbound should use epoch 1 as soon as we introduce a new DH pubkey. * Inbound stays on epoch 0 until the responder ratchets. - * + * + * If kemSecret is provided (from ML-KEM decapsulation), uses hybrid KDF + * combining X25519 DH and ML-KEM for post-quantum security. + * * @param params - Initialization parameters * @returns Initialized ratchet session */ @@ -120,9 +131,14 @@ export function initSessionAsInitiator(params: InitInitiatorParams): RatchetSess theirResponderEphemeralPubKey, topicOutbound, topicInbound, + kemSecret, } = params; - const sharedSecret = dh(myHandshakeEphemeralSecret, theirResponderEphemeralPubKey); + const x25519Secret = dh(myHandshakeEphemeralSecret, theirResponderEphemeralPubKey); + + const sharedSecret = kemSecret + ? hybridInitialSecret(x25519Secret, kemSecret) + : x25519Secret; // Derive same initial root key as responder const { rootKey: initialRootKey, chainKey: bobsSendingChain } = kdfRootKey( diff --git a/packages/sdk/src/ratchet/types.ts b/packages/sdk/src/ratchet/types.ts index 5fb3197..84d6927 100644 --- a/packages/sdk/src/ratchet/types.ts +++ b/packages/sdk/src/ratchet/types.ts @@ -180,6 +180,8 @@ export interface InitResponderParams { theirHandshakeEphemeralPubKey: Uint8Array; topicOutbound: `0x${string}`; topicInbound: `0x${string}`; + /** ML-KEM shared secret for PQ-hybrid handshake */ + kemSecret?: Uint8Array; } /** @@ -194,4 +196,6 @@ export interface InitInitiatorParams { theirResponderEphemeralPubKey: Uint8Array; topicOutbound: `0x${string}`; topicInbound: `0x${string}`; + /** ML-KEM shared secret for PQ-hybrid handshake */ + kemSecret?: Uint8Array; } \ No newline at end of file diff --git a/packages/sdk/src/send.ts b/packages/sdk/src/send.ts index 45255ae..5cb24f1 100644 --- a/packages/sdk/src/send.ts +++ b/packages/sdk/src/send.ts @@ -1,17 +1,6 @@ // packages/sdk/src/send.ts -// CLEANED VERSION - topicInfo removed from handshake response -/** - * Handshake and message sending functions. - * - * NOTE: sendEncryptedMessage is REMOVED - use ratchet for established sessions. - * Only handshake functions remain here. - * - * CHANGE: respondToHandshake no longer computes or includes topicInfo. - * Topics are now derived from ephemeral DH by the caller. - */ - -import { +import { keccak256, toUtf8Bytes, hexlify, @@ -20,23 +9,30 @@ import { } from "ethers"; import nacl from 'tweetnacl'; import { encryptStructuredPayload } from './crypto.js'; -// REMOVED: deriveDuplexTopics import -import { - HandshakeContent, +import { + HandshakeContent, serializeHandshakeContent, encodeUnifiedPubKeys, createHandshakeResponseContent, } from './payload.js'; import { IdentityKeyPair, IdentityProof } from './types.js'; -// REMOVED: TopicInfoWire from imports import { IExecutor } from './executor.js'; import { computeTagFromResponder } from './crypto.js'; +import { kem } from './pq/kem.js'; + +/** ML-KEM keypair for PQ-hybrid handshake */ +export interface KemKeyPair { + publicKey: Uint8Array; + secretKey: Uint8Array; +} /** * Initiates an on-chain handshake with unified keys and mandatory identity proof. * Executor-agnostic: works with EOA, UserOp, and Direct EntryPoint (for tests) - * - * @returns Transaction and ephemeral keypair (MUST be persisted for session init) + * + * Includes ML-KEM-768 public key for post-quantum hybrid key exchange. + * + * @returns Transaction, ephemeral keypair, and KEM keypair (MUST be persisted for session init) */ export async function initiateHandshake({ executor, @@ -55,6 +51,7 @@ export async function initiateHandshake({ }): Promise<{ tx: any; ephemeralKeyPair: nacl.BoxKeyPair; + kemKeyPair: KemKeyPair; }> { if (!executor) { throw new Error("Executor must be provided"); @@ -63,6 +60,9 @@ export async function initiateHandshake({ // Generate ephemeral keypair for this handshake const ephemeralKeyPair = nacl.box.keyPair(); + // Generate ML-KEM-768 keypair for PQ-hybrid key exchange + const kemKeyPair = kem.generateKeyPair(); + const recipientHash = keccak256( toUtf8Bytes('contact:' + recipientAddress.toLowerCase()) ); @@ -80,27 +80,33 @@ export async function initiateHandshake({ identityKeyPair.signingPublicKey // Ed25519 for signing ); + // Ephemeral public key now includes KEM public key (32 + 1184 = 1216 bytes) + const ephemeralWithKem = new Uint8Array(32 + kem.publicKeyBytes); + ephemeralWithKem.set(ephemeralKeyPair.publicKey, 0); + ephemeralWithKem.set(kemKeyPair.publicKey, 32); + const tx = await executor.initiateHandshake( recipientHash, hexlify(unifiedPubKeys), - hexlify(ephemeralKeyPair.publicKey), + hexlify(ephemeralWithKem), toUtf8Bytes(serializedPayload) ); return { tx, ephemeralKeyPair, // Caller MUST persist secretKey for ratchet session init + kemKeyPair, // Caller MUST also persist secretKey for KEM decapsulation }; } /** * Responds to a handshake with unified keys and mandatory identity proof. * Executor-agnostic: works with EOA, UserOp, and Direct EntryPoint (for tests) - * - * CHANGE: No longer computes or returns topicInfo. Topics are derived from - * ephemeral DH by the caller using deriveTopicFromDH(). - * - * @returns Transaction, tag, salt, AND ephemeral keys (MUST be persisted for ratchet session) + * + * Supports PQ-hybrid handshake: if initiator includes KEM public key, + * encapsulates a shared secret and includes ciphertext in response. + * + * @returns Transaction, tag, salt, ephemeral keys, and KEM secret */ export async function respondToHandshake({ executor, @@ -109,23 +115,24 @@ export async function respondToHandshake({ note, identityProof, signer, - // REMOVED: initiatorIdentityPubKey - no longer needed for topic derivation }: { executor: IExecutor; + /** Initiator's ephemeral key (32 bytes X25519) OR extended key (1216 bytes: X25519 + ML-KEM) */ initiatorEphemeralPubKey: Uint8Array; responderIdentityKeyPair: IdentityKeyPair; note?: string; identityProof: IdentityProof; signer: Signer; - // REMOVED: initiatorIdentityPubKey?: Uint8Array; }): Promise<{ tx: any; salt: Uint8Array; tag: `0x${string}`; - /** Responder's DH ratchet secret - MUST persist as dhMySecretKey in ratchet session */ + /** Responder's DH ratchet secret - must persist as dhMySecretKey in ratchet session */ responderEphemeralSecret: Uint8Array; - /** Responder's DH ratchet public - inside encrypted payload, NOT on-chain */ + /** Responder's DH ratchet public - inside encrypted payload, not on-chain */ responderEphemeralPublic: Uint8Array; + /** ML-KEM shared secret (32 bytes) - MUST persist for hybrid KDF, undefined if no KEM in handshake */ + kemSharedSecret?: Uint8Array; }> { if (!executor) { throw new Error("Executor must be provided"); @@ -133,7 +140,7 @@ export async function respondToHandshake({ // ========================================================================= // TWO SEPARATE KEYPAIRS for unlinkability: - // + // // 1. tagKeyPair (R, r): ONLY for tag computation // - R goes on-chain as responderEphemeralR // - Used by Alice to verify the tag @@ -147,50 +154,65 @@ export async function respondToHandshake({ // first message's DH header, allowing observers to link HandshakeResponse // to subsequent conversation. With two keypairs, there's no on-chain link. // ========================================================================= - + // Keypair for tag computation - R goes on-chain const tagKeyPair = nacl.box.keyPair(); - + // Keypair for ratchet - public key is HIDDEN inside encrypted payload const ratchetKeyPair = nacl.box.keyPair(); - + + // Check if initiator included KEM public key (extended format: 32 + 1184 = 1216 bytes) + const hasKem = initiatorEphemeralPubKey.length === 32 + kem.publicKeyBytes; + + // Extract X25519 ephemeral key (first 32 bytes) + const initiatorX25519Pub = hasKem + ? initiatorEphemeralPubKey.slice(0, 32) + : initiatorEphemeralPubKey; + // Tag is derived from tagKeyPair, not ratchetKeyPair const inResponseTo = computeTagFromResponder( tagKeyPair.secretKey, - initiatorEphemeralPubKey + initiatorX25519Pub ); const salt: Uint8Array = getBytes(inResponseTo); - // REMOVED: topicInfo computation - caller will derive topics from ephemeral DH - // let topicInfo: TopicInfoWire | undefined = undefined; - // if (initiatorIdentityPubKey) { ... } + // Handle ML-KEM encapsulation if initiator supports it + let kemCiphertext: Uint8Array | undefined; + let kemSharedSecret: Uint8Array | undefined; + + if (hasKem) { + const initiatorKemPub = initiatorEphemeralPubKey.slice(32, 32 + kem.publicKeyBytes); + const { ciphertext, sharedSecret } = kem.encapsulate(initiatorKemPub); + kemCiphertext = ciphertext; + kemSharedSecret = sharedSecret; + } // Response content includes ratchetKeyPair.publicKey (hidden inside encrypted payload) - // UPDATED: No longer includes topicInfo + // and includes kemCiphertext for PQ-hybrid handshake const responseContent = createHandshakeResponseContent( responderIdentityKeyPair.publicKey, // X25519 identity responderIdentityKeyPair.signingPublicKey, // Ed25519 signing ratchetKeyPair.publicKey, // First DH ratchet key (INSIDE payload) note, - identityProof - // REMOVED: topicInfo parameter + identityProof, + kemCiphertext ); - + // Encrypt using ratchetKeyPair (the epk in encrypted payload = ratchetKeyPair.publicKey) const payload = encryptStructuredPayload( responseContent, - initiatorEphemeralPubKey, + initiatorX25519Pub, ratchetKeyPair.secretKey, ratchetKeyPair.publicKey ); // Execute transaction - tagKeyPair.publicKey goes on-chain (NOT ratchetKeyPair) const tx = await executor.respondToHandshake( - inResponseTo, + inResponseTo, hexlify(tagKeyPair.publicKey), // Tag key on-chain for tag verification toUtf8Bytes(payload) ); - + return { tx, salt, @@ -199,5 +221,6 @@ export async function respondToHandshake({ // These are DIFFERENT from the on-chain responderEphemeralR responderEphemeralSecret: ratchetKeyPair.secretKey, responderEphemeralPublic: ratchetKeyPair.publicKey, + kemSharedSecret, }; } \ No newline at end of file diff --git a/packages/sdk/src/verify.ts b/packages/sdk/src/verify.ts index 2d0ccbc..e628dc7 100644 --- a/packages/sdk/src/verify.ts +++ b/packages/sdk/src/verify.ts @@ -255,6 +255,7 @@ export async function verifyAndExtractHandshakeResponseKeys( identityPubKey: Uint8Array; signingPubKey: Uint8Array; ephemeralPubKey: Uint8Array; + kemCiphertext?: Uint8Array; // from PQ-hybrid handshake note?: string; }; }> { @@ -295,16 +296,8 @@ export async function verifyAndExtractHandshakeResponseKeys( identityPubKey: extractedResponse.identityPubKey, signingPubKey: extractedResponse.signingPubKey, ephemeralPubKey: extractedResponse.ephemeralPubKey, + kemCiphertext: extractedResponse.kemCiphertext, note: extractedResponse.note, }, }; -} - -// ============================================================================= -// REMOVED FUNCTIONS: -// ============================================================================= -// -// verifyDerivedDuplexTopics() - removed, no longer using identity-based topics -// Topics now derive from ephemeral DH in ratchet/kdf.ts -// -// ============================================================================= \ No newline at end of file +} \ No newline at end of file diff --git a/packages/sdk/test/pq.test.ts b/packages/sdk/test/pq.test.ts new file mode 100644 index 0000000..87d8f33 --- /dev/null +++ b/packages/sdk/test/pq.test.ts @@ -0,0 +1,264 @@ +// packages/sdk/test/pq.test.ts + +import { describe, it, expect, beforeEach } from 'vitest'; +import nacl from 'tweetnacl'; + +import { kem } from '../src/pq/kem.js'; +import { hybridInitialSecret } from '../src/ratchet/kdf.js'; +import { + initSessionAsResponder, + initSessionAsInitiator, + ratchetEncrypt, + ratchetDecrypt, +} from '../src/ratchet/index.js'; + +describe('kem', () => { + it('generates keypair with correct sizes', () => { + const keyPair = kem.generateKeyPair(); + + expect(keyPair.publicKey.length).toBe(kem.publicKeyBytes); + expect(keyPair.secretKey.length).toBeGreaterThan(0); + }); + + it('encapsulate/decapsulate round-trip produces matching secrets', () => { + const keyPair = kem.generateKeyPair(); + + const { ciphertext, sharedSecret: encapSecret } = kem.encapsulate(keyPair.publicKey); + + expect(ciphertext.length).toBe(kem.ciphertextBytes); + expect(encapSecret.length).toBe(kem.sharedSecretBytes); + + const decapSecret = kem.decapsulate(ciphertext, keyPair.secretKey); + + expect(decapSecret.length).toBe(kem.sharedSecretBytes); + expect(decapSecret).toEqual(encapSecret); + }); + + it('different keypairs produce different shared secrets', () => { + const keyPair1 = kem.generateKeyPair(); + const keyPair2 = kem.generateKeyPair(); + + const { sharedSecret: secret1 } = kem.encapsulate(keyPair1.publicKey); + const { sharedSecret: secret2 } = kem.encapsulate(keyPair2.publicKey); + + expect(secret1).not.toEqual(secret2); + }); + + it('same public key with different encapsulations produces different secrets', () => { + const keyPair = kem.generateKeyPair(); + + const { sharedSecret: secret1, ciphertext: ct1 } = kem.encapsulate(keyPair.publicKey); + const { sharedSecret: secret2, ciphertext: ct2 } = kem.encapsulate(keyPair.publicKey); + + expect(ct1).not.toEqual(ct2); + expect(secret1).not.toEqual(secret2); + }); +}); + +describe('hybridInitialSecret', () => { + it('produces deterministic output for same inputs', () => { + const x25519Secret = nacl.randomBytes(32); + const kemSecret = nacl.randomBytes(32); + + const result1 = hybridInitialSecret(x25519Secret, kemSecret); + const result2 = hybridInitialSecret(x25519Secret, kemSecret); + + expect(result1).toEqual(result2); + expect(result1.length).toBe(32); + }); + + it('produces different output from X25519-only', () => { + const x25519Secret = nacl.randomBytes(32); + const kemSecret = nacl.randomBytes(32); + + const hybridResult = hybridInitialSecret(x25519Secret, kemSecret); + + // Hybrid result should differ from either input + expect(hybridResult).not.toEqual(x25519Secret); + expect(hybridResult).not.toEqual(kemSecret); + }); + + it('produces different output for different KEM secrets', () => { + const x25519Secret = nacl.randomBytes(32); + const kemSecret1 = nacl.randomBytes(32); + const kemSecret2 = nacl.randomBytes(32); + + const result1 = hybridInitialSecret(x25519Secret, kemSecret1); + const result2 = hybridInitialSecret(x25519Secret, kemSecret2); + + expect(result1).not.toEqual(result2); + }); + + it('produces different output for different X25519 secrets', () => { + const x25519Secret1 = nacl.randomBytes(32); + const x25519Secret2 = nacl.randomBytes(32); + const kemSecret = nacl.randomBytes(32); + + const result1 = hybridInitialSecret(x25519Secret1, kemSecret); + const result2 = hybridInitialSecret(x25519Secret2, kemSecret); + + expect(result1).not.toEqual(result2); + }); +}); + +describe('PQ-hybrid session initialization', () => { + let aliceEphemeral: { secretKey: Uint8Array; publicKey: Uint8Array }; + let bobEphemeral: { secretKey: Uint8Array; publicKey: Uint8Array }; + let kemKeyPair: { publicKey: Uint8Array; secretKey: Uint8Array }; + let kemSharedSecret: Uint8Array; + + const topicAliceToBob = '0x' + 'a'.repeat(64) as `0x${string}`; + const topicBobToAlice = '0x' + 'b'.repeat(64) as `0x${string}`; + + beforeEach(() => { + aliceEphemeral = nacl.box.keyPair(); + bobEphemeral = nacl.box.keyPair(); + kemKeyPair = kem.generateKeyPair(); + + // Bob encapsulates to Alice's KEM public key + const encapResult = kem.encapsulate(kemKeyPair.publicKey); + kemSharedSecret = encapResult.sharedSecret; + }); + + it('both parties derive matching root keys with hybrid KDF', () => { + // Alice is initiator, Bob is responder + // Alice decapsulates KEM ciphertext to get kemSecret + // Both use same kemSecret for hybrid KDF + + const bobSession = initSessionAsResponder({ + myAddress: '0xBob', + contactAddress: '0xAlice', + myResponderEphemeralSecret: bobEphemeral.secretKey, + myResponderEphemeralPublic: bobEphemeral.publicKey, + theirHandshakeEphemeralPubKey: aliceEphemeral.publicKey, + topicOutbound: topicBobToAlice, + topicInbound: topicAliceToBob, + kemSecret: kemSharedSecret, + }); + + const aliceSession = initSessionAsInitiator({ + myAddress: '0xAlice', + contactAddress: '0xBob', + myHandshakeEphemeralSecret: aliceEphemeral.secretKey, + theirResponderEphemeralPubKey: bobEphemeral.publicKey, + topicOutbound: topicAliceToBob, + topicInbound: topicBobToAlice, + kemSecret: kemSharedSecret, + }); + + // Root keys should allow message exchange + const signingKeyPair = nacl.sign.keyPair(); + + // Alice encrypts + const plaintext = new TextEncoder().encode('Hello Bob with PQ security!'); + const encryptResult = ratchetEncrypt(aliceSession, plaintext, signingKeyPair.secretKey); + + // Bob decrypts + const decryptResult = ratchetDecrypt(bobSession, encryptResult.header, encryptResult.ciphertext); + + expect(decryptResult).not.toBeNull(); + expect(new TextDecoder().decode(decryptResult!.plaintext)).toBe('Hello Bob with PQ security!'); + }); + + it('hybrid sessions differ from non-hybrid sessions', () => { + // Non-hybrid session + const nonHybridBobSession = initSessionAsResponder({ + myAddress: '0xBob', + contactAddress: '0xAlice', + myResponderEphemeralSecret: bobEphemeral.secretKey, + myResponderEphemeralPublic: bobEphemeral.publicKey, + theirHandshakeEphemeralPubKey: aliceEphemeral.publicKey, + topicOutbound: topicBobToAlice, + topicInbound: topicAliceToBob, + // No kemSecret + }); + + // Hybrid session + const hybridBobSession = initSessionAsResponder({ + myAddress: '0xBob', + contactAddress: '0xAlice', + myResponderEphemeralSecret: bobEphemeral.secretKey, + myResponderEphemeralPublic: bobEphemeral.publicKey, + theirHandshakeEphemeralPubKey: aliceEphemeral.publicKey, + topicOutbound: topicBobToAlice, + topicInbound: topicAliceToBob, + kemSecret: kemSharedSecret, + }); + + // Root keys should be different + expect(nonHybridBobSession.rootKey).not.toEqual(hybridBobSession.rootKey); + }); + + it('mismatched KEM secrets prevent decryption', () => { + // Bob uses correct kemSecret + const bobSession = initSessionAsResponder({ + myAddress: '0xBob', + contactAddress: '0xAlice', + myResponderEphemeralSecret: bobEphemeral.secretKey, + myResponderEphemeralPublic: bobEphemeral.publicKey, + theirHandshakeEphemeralPubKey: aliceEphemeral.publicKey, + topicOutbound: topicBobToAlice, + topicInbound: topicAliceToBob, + kemSecret: kemSharedSecret, + }); + + // Alice uses wrong kemSecret + const wrongKemSecret = nacl.randomBytes(32); + const aliceSession = initSessionAsInitiator({ + myAddress: '0xAlice', + contactAddress: '0xBob', + myHandshakeEphemeralSecret: aliceEphemeral.secretKey, + theirResponderEphemeralPubKey: bobEphemeral.publicKey, + topicOutbound: topicAliceToBob, + topicInbound: topicBobToAlice, + kemSecret: wrongKemSecret, + }); + + const signingKeyPair = nacl.sign.keyPair(); + const plaintext = new TextEncoder().encode('This should fail'); + const encryptResult = ratchetEncrypt(aliceSession, plaintext, signingKeyPair.secretKey); + + // Bob should not be able to decrypt (wrong root key derivation) + const decryptResult = ratchetDecrypt(bobSession, encryptResult.header, encryptResult.ciphertext); + expect(decryptResult).toBeNull(); + }); +}); + +describe('backward compatibility', () => { + it('sessions without kemSecret still work', () => { + const aliceEphemeral = nacl.box.keyPair(); + const bobEphemeral = nacl.box.keyPair(); + + const topicAliceToBob = '0x' + 'a'.repeat(64) as `0x${string}`; + const topicBobToAlice = '0x' + 'b'.repeat(64) as `0x${string}`; + + // Sessions without kemSecret (backward compatible) + const bobSession = initSessionAsResponder({ + myAddress: '0xBob', + contactAddress: '0xAlice', + myResponderEphemeralSecret: bobEphemeral.secretKey, + myResponderEphemeralPublic: bobEphemeral.publicKey, + theirHandshakeEphemeralPubKey: aliceEphemeral.publicKey, + topicOutbound: topicBobToAlice, + topicInbound: topicAliceToBob, + }); + + const aliceSession = initSessionAsInitiator({ + myAddress: '0xAlice', + contactAddress: '0xBob', + myHandshakeEphemeralSecret: aliceEphemeral.secretKey, + theirResponderEphemeralPubKey: bobEphemeral.publicKey, + topicOutbound: topicAliceToBob, + topicInbound: topicBobToAlice, + }); + + const signingKeyPair = nacl.sign.keyPair(); + const plaintext = new TextEncoder().encode('Classic X25519 only'); + const encryptResult = ratchetEncrypt(aliceSession, plaintext, signingKeyPair.secretKey); + + const decryptResult = ratchetDecrypt(bobSession, encryptResult.header, encryptResult.ciphertext); + + expect(decryptResult).not.toBeNull(); + expect(new TextDecoder().decode(decryptResult!.plaintext)).toBe('Classic X25519 only'); + }); +}); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e06b879..69067d7 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -32,25 +32,25 @@ importers: version: 1.0.3 typescript: specifier: ^5.4.0 - version: 5.9.3 + version: 5.6.3 vitest: specifier: ^3.1.4 - version: 3.2.4(@types/debug@4.1.12)(@types/node@20.19.27) + version: 3.2.4(@types/debug@4.1.12)(@types/node@20.19.27)(terser@5.46.0) apps/demo: dependencies: '@rainbow-me/rainbowkit': specifier: ^2.2.8 - version: 2.2.10(@tanstack/react-query@5.90.12(react@18.3.1))(@types/react@18.3.27)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3)(viem@2.43.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1))(wagmi@2.19.5(@tanstack/query-core@5.90.12)(@tanstack/react-query@5.90.12(react@18.3.1))(@types/react@18.3.27)(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(immer@10.0.2)(react@18.3.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.43.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1))(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@4.2.1)) + version: 2.2.10(@tanstack/react-query@5.90.12(react@18.3.1))(@types/react@18.3.27)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3)(viem@2.43.1(bufferutil@4.0.9)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.25.76))(wagmi@2.19.5(@tanstack/query-core@5.90.12)(@tanstack/react-query@5.90.12(react@18.3.1))(@types/react@18.3.27)(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(immer@10.0.2)(react@18.3.1)(typescript@5.6.3)(utf-8-validate@5.0.10)(viem@2.43.1(bufferutil@4.0.9)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.25.76))(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)) '@safe-global/api-kit': specifier: ^4.0.1 - version: 4.0.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) + version: 4.0.1(bufferutil@4.0.9)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.25.76) '@safe-global/protocol-kit': specifier: ^6.1.2 - version: 6.1.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) + version: 6.1.2(bufferutil@4.0.9)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.25.76) '@safe-global/types-kit': specifier: ^3.0.0 - version: 3.0.0(typescript@5.9.3)(zod@4.2.1) + version: 3.0.0(typescript@5.6.3)(zod@3.25.76) '@tanstack/react-query': specifier: ^5.59.20 version: 5.90.12(react@18.3.1) @@ -86,10 +86,10 @@ importers: version: 1.0.3 viem: specifier: ^2.17.11 - version: 2.43.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) + version: 2.43.1(bufferutil@4.0.9)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.25.76) wagmi: specifier: ^2.14.3 - version: 2.19.5(@tanstack/query-core@5.90.12)(@tanstack/react-query@5.90.12(react@18.3.1))(@types/react@18.3.27)(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(immer@10.0.2)(react@18.3.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.43.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1))(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@4.2.1) + version: 2.19.5(@tanstack/query-core@5.90.12)(@tanstack/react-query@5.90.12(react@18.3.1))(@types/react@18.3.27)(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(immer@10.0.2)(react@18.3.1)(typescript@5.6.3)(utf-8-validate@5.0.10)(viem@2.43.1(bufferutil@4.0.9)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.25.76))(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76) devDependencies: '@types/react': specifier: ^18.2.0 @@ -99,7 +99,7 @@ importers: version: 18.3.7(@types/react@18.3.27) '@vitejs/plugin-react': specifier: ^4.0.0 - version: 4.7.0(vite@5.4.21(@types/node@22.7.5)) + version: 4.7.0(vite@5.4.21(@types/node@22.7.5)(terser@5.46.0)) autoprefixer: specifier: ^10.4.20 version: 10.4.23(postcss@8.5.6) @@ -111,13 +111,50 @@ importers: version: 3.4.19 typescript: specifier: ^5.4.0 - version: 5.9.3 + version: 5.6.3 vite: specifier: ^5.0.0 - version: 5.4.21(@types/node@22.7.5) + version: 5.4.21(@types/node@22.7.5)(terser@5.46.0) vite-plugin-wasm: specifier: ^3.4.0 - version: 3.5.0(vite@5.4.21(@types/node@22.7.5)) + version: 3.5.0(vite@5.4.21(@types/node@22.7.5)(terser@5.46.0)) + + apps/docs: + dependencies: + '@docusaurus/core': + specifier: 3.9.2 + version: 3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.27)(react@19.2.3))(bufferutil@4.0.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.6.3)(utf-8-validate@5.0.10) + '@docusaurus/preset-classic': + specifier: 3.9.2 + version: 3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.27)(react@19.2.3))(@types/react@18.3.27)(bufferutil@4.0.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.6.3)(utf-8-validate@5.0.10) + '@mdx-js/react': + specifier: ^3.0.0 + version: 3.1.1(@types/react@18.3.27)(react@19.2.3) + clsx: + specifier: ^2.0.0 + version: 2.1.1 + prism-react-renderer: + specifier: ^2.3.0 + version: 2.4.1(react@19.2.3) + react: + specifier: ^19.0.0 + version: 19.2.3 + react-dom: + specifier: ^19.0.0 + version: 19.2.3(react@19.2.3) + devDependencies: + '@docusaurus/module-type-aliases': + specifier: 3.9.2 + version: 3.9.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@docusaurus/tsconfig': + specifier: 3.9.2 + version: 3.9.2 + '@docusaurus/types': + specifier: 3.9.2 + version: 3.9.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + typescript: + specifier: ~5.6.2 + version: 5.6.3 packages/contracts: dependencies: @@ -130,13 +167,13 @@ importers: version: 0.8.0 '@nomicfoundation/hardhat-ignition': specifier: ^0.15.10 - version: 0.15.16(@nomicfoundation/hardhat-verify@2.1.3(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) + version: 0.15.16(@nomicfoundation/hardhat-verify@2.1.3(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.6.3))(typescript@5.6.3)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.6.3))(typescript@5.6.3)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) '@nomicfoundation/hardhat-toolbox': specifier: ^5.0.0 - version: 5.0.0(718d8c1f3463e528ebfebd4ac5f4e994) + version: 5.0.0(1c68260e3d5fd3faa23987294e569bd7) '@openzeppelin/community-contracts': specifier: github:OpenZeppelin/openzeppelin-community-contracts - version: https://codeload.github.com/OpenZeppelin/openzeppelin-community-contracts/tar.gz/7322fa7de0beabe0e0cf7e8663f879d406bb3f42 + version: https://codeload.github.com/OpenZeppelin/openzeppelin-community-contracts/tar.gz/a12b30ca7affe3320777378eddf2d0cebae8c5b2 '@openzeppelin/contracts': specifier: ^5.4.0 version: 5.4.0 @@ -145,13 +182,13 @@ importers: version: 5.4.0(@openzeppelin/contracts@5.4.0) '@openzeppelin/hardhat-upgrades': specifier: ^3.9.0 - version: 3.9.1(@nomicfoundation/hardhat-ethers@3.1.3(ethers@6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10)))(@nomicfoundation/hardhat-verify@2.1.3(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10)))(ethers@6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10)) + version: 3.9.1(@nomicfoundation/hardhat-ethers@3.1.3(ethers@6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.6.3))(typescript@5.6.3)(utf-8-validate@5.0.10)))(@nomicfoundation/hardhat-verify@2.1.3(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.6.3))(typescript@5.6.3)(utf-8-validate@5.0.10)))(ethers@6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.6.3))(typescript@5.6.3)(utf-8-validate@5.0.10)) '@typechain/ethers-v6': specifier: ^0.5.1 - version: 0.5.1(ethers@6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(typechain@8.3.2(typescript@5.9.3))(typescript@5.9.3) + version: 0.5.1(ethers@6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(typechain@8.3.2(typescript@5.6.3))(typescript@5.6.3) '@typechain/hardhat': specifier: ^9.1.0 - version: 9.1.0(@typechain/ethers-v6@0.5.1(ethers@6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(typechain@8.3.2(typescript@5.9.3))(typescript@5.9.3))(ethers@6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10))(typechain@8.3.2(typescript@5.9.3)) + version: 9.1.0(@typechain/ethers-v6@0.5.1(ethers@6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(typechain@8.3.2(typescript@5.6.3))(typescript@5.6.3))(ethers@6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.6.3))(typescript@5.6.3)(utf-8-validate@5.0.10))(typechain@8.3.2(typescript@5.6.3)) '@types/chai': specifier: ^4.3.20 version: 4.3.20 @@ -166,19 +203,19 @@ importers: version: 6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) hardhat: specifier: ^2.23.0 - version: 2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10) + version: 2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.6.3))(typescript@5.6.3)(utf-8-validate@5.0.10) hardhat-dependency-compiler: specifier: ^1.2.1 - version: 1.2.1(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10)) + version: 1.2.1(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.6.3))(typescript@5.6.3)(utf-8-validate@5.0.10)) hardhat-gas-reporter: specifier: ^1.0.9 - version: 1.0.10(bufferutil@4.0.9)(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) + version: 1.0.10(bufferutil@4.0.9)(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.6.3))(typescript@5.6.3)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) typechain: specifier: ^8.3.2 - version: 8.3.2(typescript@5.9.3) + version: 8.3.2(typescript@5.6.3) typescript: specifier: ^5.0.0 - version: 5.9.3 + version: 5.6.3 packages/sdk: dependencies: @@ -188,6 +225,9 @@ importers: '@noble/hashes': specifier: ^1.8.0 version: 1.8.0 + '@noble/post-quantum': + specifier: ^0.5.4 + version: 0.5.4 '@noble/secp256k1': specifier: ^2.2.3 version: 2.3.0 @@ -199,23 +239,23 @@ importers: version: 1.0.3 viem: specifier: ^2.37.5 - version: 2.43.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) + version: 2.43.1(bufferutil@4.0.9)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@4.2.1) devDependencies: '@verbeth/contracts': specifier: workspace:^0.1.0 version: link:../contracts ts-node: specifier: ^10.9.2 - version: 10.9.2(@types/node@22.7.5)(typescript@5.9.3) + version: 10.9.2(@types/node@22.7.5)(typescript@5.6.3) typechain: specifier: ^8.3.2 - version: 8.3.2(typescript@5.9.3) + version: 8.3.2(typescript@5.6.3) typescript: specifier: ^5.4.0 - version: 5.9.3 + version: 5.6.3 vitest: specifier: ^3.1.4 - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.7.5) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.7.5)(terser@5.46.0) packages: @@ -228,6 +268,65 @@ packages: '@adraffy/ens-normalize@1.11.1': resolution: {integrity: sha512-nhCBV3quEgesuf7c7KYfperqSS14T8bYuvJ8PcLJp6znkZpFc0AuW4qBtr8eKVyPPe/8RSr7sglCWPU5eaxwKQ==} + '@algolia/abtesting@1.13.0': + resolution: {integrity: sha512-Zrqam12iorp3FjiKMXSTpedGYznZ3hTEOAr2oCxI8tbF8bS1kQHClyDYNq/eV0ewMNLyFkgZVWjaS+8spsOYiQ==} + engines: {node: '>= 14.0.0'} + + '@algolia/client-abtesting@5.47.0': + resolution: {integrity: sha512-aOpsdlgS9xTEvz47+nXmw8m0NtUiQbvGWNuSEb7fA46iPL5FxOmOUZkh8PREBJpZ0/H8fclSc7BMJCVr+Dn72w==} + engines: {node: '>= 14.0.0'} + + '@algolia/client-analytics@5.47.0': + resolution: {integrity: sha512-EcF4w7IvIk1sowrO7Pdy4Ako7x/S8+nuCgdk6En+u5jsaNQM4rTT09zjBPA+WQphXkA2mLrsMwge96rf6i7Mow==} + engines: {node: '>= 14.0.0'} + + '@algolia/client-common@5.47.0': + resolution: {integrity: sha512-Wzg5Me2FqgRDj0lFuPWFK05UOWccSMsIBL2YqmTmaOzxVlLZ+oUqvKbsUSOE5ud8Fo1JU7JyiLmEXBtgDKzTwg==} + engines: {node: '>= 14.0.0'} + + '@algolia/client-insights@5.47.0': + resolution: {integrity: sha512-Ci+cn/FDIsDxSKMRBEiyKrqybblbk8xugo6ujDN1GSTv9RIZxwxqZYuHfdLnLEwLlX7GB8pqVyqrUSlRnR+sJA==} + engines: {node: '>= 14.0.0'} + + '@algolia/client-personalization@5.47.0': + resolution: {integrity: sha512-gsLnHPZmWcX0T3IigkDL2imCNtsQ7dR5xfnwiFsb+uTHCuYQt+IwSNjsd8tok6HLGLzZrliSaXtB5mfGBtYZvQ==} + engines: {node: '>= 14.0.0'} + + '@algolia/client-query-suggestions@5.47.0': + resolution: {integrity: sha512-PDOw0s8WSlR2fWFjPQldEpmm/gAoUgLigvC3k/jCSi/DzigdGX6RdC0Gh1RR1P8Cbk5KOWYDuL3TNzdYwkfDyA==} + engines: {node: '>= 14.0.0'} + + '@algolia/client-search@5.47.0': + resolution: {integrity: sha512-b5hlU69CuhnS2Rqgsz7uSW0t4VqrLMLTPbUpEl0QVz56rsSwr1Sugyogrjb493sWDA+XU1FU5m9eB8uH7MoI0g==} + engines: {node: '>= 14.0.0'} + + '@algolia/events@4.0.1': + resolution: {integrity: sha512-FQzvOCgoFXAbf5Y6mYozw2aj5KCJoA3m4heImceldzPSMbdyS4atVjJzXKMsfX3wnZTFYwkkt8/z8UesLHlSBQ==} + + '@algolia/ingestion@1.47.0': + resolution: {integrity: sha512-WvwwXp5+LqIGISK3zHRApLT1xkuEk320/EGeD7uYy+K8WwDd5OjXnhjuXRhYr1685KnkvWkq1rQ/ihCJjOfHpQ==} + engines: {node: '>= 14.0.0'} + + '@algolia/monitoring@1.47.0': + resolution: {integrity: sha512-j2EUFKAlzM0TE4GRfkDE3IDfkVeJdcbBANWzK16Tb3RHz87WuDfQ9oeEW6XiRE1/bEkq2xf4MvZesvSeQrZRDA==} + engines: {node: '>= 14.0.0'} + + '@algolia/recommend@5.47.0': + resolution: {integrity: sha512-+kTSE4aQ1ARj2feXyN+DMq0CIDHJwZw1kpxIunedkmpWUg8k3TzFwWsMCzJVkF2nu1UcFbl7xsIURz3Q3XwOXA==} + engines: {node: '>= 14.0.0'} + + '@algolia/requester-browser-xhr@5.47.0': + resolution: {integrity: sha512-Ja+zPoeSA2SDowPwCNRbm5Q2mzDvVV8oqxCQ4m6SNmbKmPlCfe30zPfrt9ho3kBHnsg37pGucwOedRIOIklCHw==} + engines: {node: '>= 14.0.0'} + + '@algolia/requester-fetch@5.47.0': + resolution: {integrity: sha512-N6nOvLbaR4Ge+oVm7T4W/ea1PqcSbsHR4O58FJ31XtZjFPtOyxmnhgCmGCzP9hsJI6+x0yxJjkW5BMK/XI8OvA==} + engines: {node: '>= 14.0.0'} + + '@algolia/requester-node-http@5.47.0': + resolution: {integrity: sha512-z1oyLq5/UVkohVXNDEY70mJbT/sv/t6HYtCvCwNrOri6pxBJDomP9R83KOlwcat+xqBQEdJHjbrPh36f1avmZA==} + engines: {node: '>= 14.0.0'} + '@alloc/quick-lru@5.2.0': resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==} engines: {node: '>=10'} @@ -366,10 +465,18 @@ packages: resolution: {integrity: sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==} engines: {node: '>=6.9.0'} + '@babel/code-frame@7.28.6': + resolution: {integrity: sha512-JYgintcMjRiCvS8mMECzaEn+m3PfoQiyqukOMCCVQtoJGYJw8j/8LBJEiqkHLkfwCcs74E3pbAUFNg7d9VNJ+Q==} + engines: {node: '>=6.9.0'} + '@babel/compat-data@7.28.5': resolution: {integrity: sha512-6uFXyCayocRbqhZOB+6XcuZbkMNimwfVGFji8CTZnCzOHVGvDqzvitu1re2AU5LROliz7eQPhB8CpAMvnx9EjA==} engines: {node: '>=6.9.0'} + '@babel/compat-data@7.28.6': + resolution: {integrity: sha512-2lfu57JtzctfIrcGMz992hyLlByuzgIk58+hhGCxjKZ3rWI82NnVLjXcaTqkI2NvlcvOskZaiZ5kjUALo3Lpxg==} + engines: {node: '>=6.9.0'} + '@babel/core@7.28.5': resolution: {integrity: sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==} engines: {node: '>=6.9.0'} @@ -378,28 +485,95 @@ packages: resolution: {integrity: sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ==} engines: {node: '>=6.9.0'} + '@babel/generator@7.28.6': + resolution: {integrity: sha512-lOoVRwADj8hjf7al89tvQ2a1lf53Z+7tiXMgpZJL3maQPDxh0DgLMN62B2MKUOFcoodBHLMbDM6WAbKgNy5Suw==} + 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.27.2': resolution: {integrity: sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==} engines: {node: '>=6.9.0'} + '@babel/helper-compilation-targets@7.28.6': + resolution: {integrity: sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-create-class-features-plugin@7.28.6': + resolution: {integrity: sha512-dTOdvsjnG3xNT9Y0AUg1wAl38y+4Rl4sf9caSQZOXdNqVn+H+HbbJ4IyyHaIqNR6SW9oJpA/RuRjsjCw2IdIow==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-create-regexp-features-plugin@7.28.5': + resolution: {integrity: sha512-N1EhvLtHzOvj7QQOUCCS3NrPJP8c5W6ZXCHDn7Yialuy1iu4r5EmIYkXlKNqT99Ciw+W0mDqWoR6HWMZlFP3hw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-define-polyfill-provider@0.6.5': + resolution: {integrity: sha512-uJnGFcPsWQK8fvjgGP5LZUZZsYGIoPeRjSF5PGwrelYgq7Q15/Ft9NGFp1zglwgIv//W0uG4BevRuSJRyylZPg==} + peerDependencies: + '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 + '@babel/helper-globals@7.28.0': resolution: {integrity: sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==} engines: {node: '>=6.9.0'} + '@babel/helper-member-expression-to-functions@7.28.5': + resolution: {integrity: sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg==} + engines: {node: '>=6.9.0'} + '@babel/helper-module-imports@7.27.1': resolution: {integrity: sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==} engines: {node: '>=6.9.0'} + '@babel/helper-module-imports@7.28.6': + resolution: {integrity: sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==} + engines: {node: '>=6.9.0'} + '@babel/helper-module-transforms@7.28.3': resolution: {integrity: sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 + '@babel/helper-module-transforms@7.28.6': + resolution: {integrity: sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-optimise-call-expression@7.27.1': + resolution: {integrity: sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw==} + engines: {node: '>=6.9.0'} + '@babel/helper-plugin-utils@7.27.1': resolution: {integrity: sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==} engines: {node: '>=6.9.0'} + '@babel/helper-plugin-utils@7.28.6': + resolution: {integrity: sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==} + engines: {node: '>=6.9.0'} + + '@babel/helper-remap-async-to-generator@7.27.1': + resolution: {integrity: sha512-7fiA521aVw8lSPeI4ZOD3vRFkoqkJcS+z4hFo82bFSH/2tNd6eJ5qCVMS5OzDmZh/kaHQeBaeyxK6wljcPtveA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-replace-supers@7.28.6': + resolution: {integrity: sha512-mq8e+laIk94/yFec3DxSjCRD2Z0TAjhVbEJY3UQrlwVo15Lmt7C2wAUbK4bjnTs4APkwsYLTahXRraQXhb1WCg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-skip-transparent-expression-wrappers@7.27.1': + resolution: {integrity: sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg==} + engines: {node: '>=6.9.0'} + '@babel/helper-string-parser@7.27.1': resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} engines: {node: '>=6.9.0'} @@ -412,6 +586,10 @@ packages: resolution: {integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==} engines: {node: '>=6.9.0'} + '@babel/helper-wrap-function@7.28.6': + resolution: {integrity: sha512-z+PwLziMNBeSQJonizz2AGnndLsP2DeGHIxDAn+wdHOGuo4Fo1x1HBPPXeE9TAOPHNNWQKCSlA2VZyYyyibDnQ==} + engines: {node: '>=6.9.0'} + '@babel/helpers@7.28.4': resolution: {integrity: sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==} engines: {node: '>=6.9.0'} @@ -421,10462 +599,19395 @@ packages: engines: {node: '>=6.0.0'} hasBin: true - '@babel/plugin-transform-react-jsx-self@7.27.1': - resolution: {integrity: sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==} + '@babel/parser@7.28.6': + resolution: {integrity: sha512-TeR9zWR18BvbfPmGbLampPMW+uW1NZnJlRuuHso8i87QZNq2JRF9i6RgxRqtEq+wQGsS19NNTWr2duhnE49mfQ==} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.28.5': + resolution: {integrity: sha512-87GDMS3tsmMSi/3bWOte1UblL+YUTFMV8SZPZ2eSEL17s74Cw/l63rR6NmGVKMYW2GYi85nE+/d6Hw5N0bEk2Q==} engines: {node: '>=6.9.0'} peerDependencies: - '@babel/core': ^7.0.0-0 + '@babel/core': ^7.0.0 - '@babel/plugin-transform-react-jsx-source@7.27.1': - resolution: {integrity: sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==} + '@babel/plugin-bugfix-safari-class-field-initializer-scope@7.27.1': + resolution: {integrity: sha512-qNeq3bCKnGgLkEXUuFry6dPlGfCdQNZbn7yUAPCInwAJHMU7THJfrBSozkcWq5sNM6RcF3S8XyQL2A52KNR9IA==} engines: {node: '>=6.9.0'} peerDependencies: - '@babel/core': ^7.0.0-0 + '@babel/core': ^7.0.0 - '@babel/runtime@7.28.4': - resolution: {integrity: sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==} + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.27.1': + resolution: {integrity: sha512-g4L7OYun04N1WyqMNjldFwlfPCLVkgB54A/YCXICZYBsvJJE3kByKv9c9+R/nAfmIfjl2rKYLNyMHboYbZaWaA==} engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 - '@babel/template@7.27.2': - resolution: {integrity: sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==} + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.27.1': + resolution: {integrity: sha512-oO02gcONcD5O1iTLi/6frMJBIwWEHceWGSGqrpCmEL8nogiS6J9PBlE48CaK20/Jx1LuRml9aDftLgdjXT8+Cw==} engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.13.0 - '@babel/traverse@7.28.5': - resolution: {integrity: sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ==} + '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.28.6': + resolution: {integrity: sha512-a0aBScVTlNaiUe35UtfxAN7A/tehvvG4/ByO6+46VPKTRSlfnAFsgKy0FUh+qAkQrDTmhDkT+IBOKlOoMUxQ0g==} engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 - '@babel/types@7.28.5': - resolution: {integrity: sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==} + '@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2': + resolution: {integrity: sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==} engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@base-org/account@2.4.0': - resolution: {integrity: sha512-A4Umpi8B9/pqR78D1Yoze4xHyQaujioVRqqO3d6xuDFw9VRtjg6tK3bPlwE0aW+nVH/ntllCpPa2PbI8Rnjcug==} - - '@bytecodealliance/preview2-shim@0.17.0': - resolution: {integrity: sha512-JorcEwe4ud0x5BS/Ar2aQWOQoFzjq/7jcnxYXCvSMh0oRm0dQXzOA+hqLDBnOMks1LLBA7dmiLLsEBl09Yd6iQ==} + '@babel/plugin-syntax-dynamic-import@7.8.3': + resolution: {integrity: sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@coinbase/cdp-sdk@1.40.1': - resolution: {integrity: sha512-VZxAUYvWbqM4gw/ZHyr9fKBlCAKdMbBQzJxpV9rMUNkdulHIrj0cko2Mw3dyVyw+gdT62jAVxzVkPuQTRnECLw==} + '@babel/plugin-syntax-import-assertions@7.28.6': + resolution: {integrity: sha512-pSJUpFHdx9z5nqTSirOCMtYVP2wFgoWhP0p3g8ONK/4IHhLIBd0B9NYqAvIUAhq+OkhO4VM1tENCt0cjlsNShw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@coinbase/wallet-sdk@3.9.3': - resolution: {integrity: sha512-N/A2DRIf0Y3PHc1XAMvbBUu4zisna6qAdqABMZwBMNEfWrXpAwx16pZGkYCLGE+Rvv1edbcB2LYDRnACNcmCiw==} + '@babel/plugin-syntax-import-attributes@7.28.6': + resolution: {integrity: sha512-jiLC0ma9XkQT3TKJ9uYvlakm66Pamywo+qwL+oL8HJOvc6TWdZXVfhqJr8CCzbSGUAbDOzlGHJC1U+vRfLQDvw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@coinbase/wallet-sdk@4.3.6': - resolution: {integrity: sha512-4q8BNG1ViL4mSAAvPAtpwlOs1gpC+67eQtgIwNvT3xyeyFFd+guwkc8bcX5rTmQhXpqnhzC4f0obACbP9CqMSA==} + '@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 - '@cspotcode/source-map-support@0.8.1': - resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} - engines: {node: '>=12'} + '@babel/plugin-syntax-typescript@7.28.6': + resolution: {integrity: sha512-+nDNmQye7nlnuuHDboPbGm00Vqg3oO8niRRL27/4LYHUsHYh0zJ1xWOz0uRwNFmM1Avzk8wZbc6rdiYhomzv/A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@ecies/ciphers@0.2.5': - resolution: {integrity: sha512-GalEZH4JgOMHYYcYmVqnFirFsjZHeoGMDt9IxEnM9F7GRUUyUksJ7Ou53L83WHJq3RWKD3AcBpo0iQh0oMpf8A==} - engines: {bun: '>=1', deno: '>=2', node: '>=16'} + '@babel/plugin-syntax-unicode-sets-regex@7.18.6': + resolution: {integrity: sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==} + engines: {node: '>=6.9.0'} peerDependencies: - '@noble/ciphers': ^1.0.0 + '@babel/core': ^7.0.0 - '@emotion/hash@0.9.2': - resolution: {integrity: sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g==} + '@babel/plugin-transform-arrow-functions@7.27.1': + resolution: {integrity: sha512-8Z4TGic6xW70FKThA5HYEKKyBpOOsucTOD1DjU3fZxDg+K3zBJcXMFnt/4yQiZnf5+MiOMSXQ9PaEK/Ilh1DeA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@esbuild/aix-ppc64@0.21.5': - resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==} - engines: {node: '>=12'} - cpu: [ppc64] - os: [aix] + '@babel/plugin-transform-async-generator-functions@7.28.6': + resolution: {integrity: sha512-9knsChgsMzBV5Yh3kkhrZNxH3oCYAfMBkNNaVN4cP2RVlFPe8wYdwwcnOsAbkdDoV9UjFtOXWrWB52M8W4jNeA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@esbuild/android-arm64@0.21.5': - resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==} - engines: {node: '>=12'} - cpu: [arm64] - os: [android] + '@babel/plugin-transform-async-to-generator@7.28.6': + resolution: {integrity: sha512-ilTRcmbuXjsMmcZ3HASTe4caH5Tpo93PkTxF9oG2VZsSWsahydmcEHhix9Ik122RcTnZnUzPbmux4wh1swfv7g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@esbuild/android-arm@0.21.5': - resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==} - engines: {node: '>=12'} - cpu: [arm] - os: [android] + '@babel/plugin-transform-block-scoped-functions@7.27.1': + resolution: {integrity: sha512-cnqkuOtZLapWYZUYM5rVIdv1nXYuFVIltZ6ZJ7nIj585QsjKM5dhL2Fu/lICXZ1OyIAFc7Qy+bvDAtTXqGrlhg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@esbuild/android-x64@0.21.5': - resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==} - engines: {node: '>=12'} - cpu: [x64] - os: [android] + '@babel/plugin-transform-block-scoping@7.28.6': + resolution: {integrity: sha512-tt/7wOtBmwHPNMPu7ax4pdPz6shjFrmHDghvNC+FG9Qvj7D6mJcoRQIF5dy4njmxR941l6rgtvfSB2zX3VlUIw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@esbuild/darwin-arm64@0.21.5': - resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==} - engines: {node: '>=12'} - cpu: [arm64] - os: [darwin] + '@babel/plugin-transform-class-properties@7.28.6': + resolution: {integrity: sha512-dY2wS3I2G7D697VHndN91TJr8/AAfXQNt5ynCTI/MpxMsSzHp+52uNivYT5wCPax3whc47DR8Ba7cmlQMg24bw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@esbuild/darwin-x64@0.21.5': - resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==} - engines: {node: '>=12'} - cpu: [x64] - os: [darwin] + '@babel/plugin-transform-class-static-block@7.28.6': + resolution: {integrity: sha512-rfQ++ghVwTWTqQ7w8qyDxL1XGihjBss4CmTgGRCTAC9RIbhVpyp4fOeZtta0Lbf+dTNIVJer6ych2ibHwkZqsQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.12.0 - '@esbuild/freebsd-arm64@0.21.5': - resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==} - engines: {node: '>=12'} - cpu: [arm64] - os: [freebsd] + '@babel/plugin-transform-classes@7.28.6': + resolution: {integrity: sha512-EF5KONAqC5zAqT783iMGuM2ZtmEBy+mJMOKl2BCvPZ2lVrwvXnB6o+OBWCS+CoeCCpVRF2sA2RBKUxvT8tQT5Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@esbuild/freebsd-x64@0.21.5': - resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [freebsd] + '@babel/plugin-transform-computed-properties@7.28.6': + resolution: {integrity: sha512-bcc3k0ijhHbc2lEfpFHgx7eYw9KNXqOerKWfzbxEHUGKnS3sz9C4CNL9OiFN1297bDNfUiSO7DaLzbvHQQQ1BQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@esbuild/linux-arm64@0.21.5': - resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==} - engines: {node: '>=12'} - cpu: [arm64] - os: [linux] + '@babel/plugin-transform-destructuring@7.28.5': + resolution: {integrity: sha512-Kl9Bc6D0zTUcFUvkNuQh4eGXPKKNDOJQXVyyM4ZAQPMveniJdxi8XMJwLo+xSoW3MIq81bD33lcUe9kZpl0MCw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@esbuild/linux-arm@0.21.5': - resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==} - engines: {node: '>=12'} - cpu: [arm] - os: [linux] + '@babel/plugin-transform-dotall-regex@7.28.6': + resolution: {integrity: sha512-SljjowuNKB7q5Oayv4FoPzeB74g3QgLt8IVJw9ADvWy3QnUb/01aw8I4AVv8wYnPvQz2GDDZ/g3GhcNyDBI4Bg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@esbuild/linux-ia32@0.21.5': - resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==} - engines: {node: '>=12'} - cpu: [ia32] - os: [linux] + '@babel/plugin-transform-duplicate-keys@7.27.1': + resolution: {integrity: sha512-MTyJk98sHvSs+cvZ4nOauwTTG1JeonDjSGvGGUNHreGQns+Mpt6WX/dVzWBHgg+dYZhkC4X+zTDfkTU+Vy9y7Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@esbuild/linux-loong64@0.21.5': - resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==} - engines: {node: '>=12'} - cpu: [loong64] - os: [linux] + '@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.28.6': + resolution: {integrity: sha512-5suVoXjC14lUN6ZL9OLKIHCNVWCrqGqlmEp/ixdXjvgnEl/kauLvvMO/Xw9NyMc95Joj1AeLVPVMvibBgSoFlA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 - '@esbuild/linux-mips64el@0.21.5': - resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==} - engines: {node: '>=12'} - cpu: [mips64el] - os: [linux] + '@babel/plugin-transform-dynamic-import@7.27.1': + resolution: {integrity: sha512-MHzkWQcEmjzzVW9j2q8LGjwGWpG2mjwaaB0BNQwst3FIjqsg8Ct/mIZlvSPJvfi9y2AC8mi/ktxbFVL9pZ1I4A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@esbuild/linux-ppc64@0.21.5': - resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==} - engines: {node: '>=12'} - cpu: [ppc64] - os: [linux] + '@babel/plugin-transform-explicit-resource-management@7.28.6': + resolution: {integrity: sha512-Iao5Konzx2b6g7EPqTy40UZbcdXE126tTxVFr/nAIj+WItNxjKSYTEw3RC+A2/ZetmdJsgueL1KhaMCQHkLPIg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@esbuild/linux-riscv64@0.21.5': - resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==} - engines: {node: '>=12'} - cpu: [riscv64] - os: [linux] - - '@esbuild/linux-s390x@0.21.5': - resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==} - engines: {node: '>=12'} - cpu: [s390x] - os: [linux] + '@babel/plugin-transform-exponentiation-operator@7.28.6': + resolution: {integrity: sha512-WitabqiGjV/vJ0aPOLSFfNY1u9U3R7W36B03r5I2KoNix+a3sOhJ3pKFB3R5It9/UiK78NiO0KE9P21cMhlPkw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@esbuild/linux-x64@0.21.5': - resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [linux] + '@babel/plugin-transform-export-namespace-from@7.27.1': + resolution: {integrity: sha512-tQvHWSZ3/jH2xuq/vZDy0jNn+ZdXJeM8gHvX4lnJmsc3+50yPlWdZXIc5ay+umX+2/tJIqHqiEqcJvxlmIvRvQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@esbuild/netbsd-x64@0.21.5': - resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==} - engines: {node: '>=12'} - cpu: [x64] - os: [netbsd] + '@babel/plugin-transform-for-of@7.27.1': + resolution: {integrity: sha512-BfbWFFEJFQzLCQ5N8VocnCtA8J1CLkNTe2Ms2wocj75dd6VpiqS5Z5quTYcUoo4Yq+DN0rtikODccuv7RU81sw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@esbuild/openbsd-x64@0.21.5': - resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==} - engines: {node: '>=12'} - cpu: [x64] - os: [openbsd] + '@babel/plugin-transform-function-name@7.27.1': + resolution: {integrity: sha512-1bQeydJF9Nr1eBCMMbC+hdwmRlsv5XYOMu03YSWFwNs0HsAmtSxxF1fyuYPqemVldVyFmlCU7w8UE14LupUSZQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@esbuild/sunos-x64@0.21.5': - resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==} - engines: {node: '>=12'} - cpu: [x64] - os: [sunos] + '@babel/plugin-transform-json-strings@7.28.6': + resolution: {integrity: sha512-Nr+hEN+0geQkzhbdgQVPoqr47lZbm+5fCUmO70722xJZd0Mvb59+33QLImGj6F+DkK3xgDi1YVysP8whD6FQAw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@esbuild/win32-arm64@0.21.5': - resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==} - engines: {node: '>=12'} - cpu: [arm64] - os: [win32] + '@babel/plugin-transform-literals@7.27.1': + resolution: {integrity: sha512-0HCFSepIpLTkLcsi86GG3mTUzxV5jpmbv97hTETW3yzrAij8aqlD36toB1D0daVFJM8NK6GvKO0gslVQmm+zZA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@esbuild/win32-ia32@0.21.5': - resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==} - engines: {node: '>=12'} - cpu: [ia32] - os: [win32] + '@babel/plugin-transform-logical-assignment-operators@7.28.6': + resolution: {integrity: sha512-+anKKair6gpi8VsM/95kmomGNMD0eLz1NQ8+Pfw5sAwWH9fGYXT50E55ZpV0pHUHWf6IUTWPM+f/7AAff+wr9A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@esbuild/win32-x64@0.21.5': - resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==} - engines: {node: '>=12'} - cpu: [x64] - os: [win32] + '@babel/plugin-transform-member-expression-literals@7.27.1': + resolution: {integrity: sha512-hqoBX4dcZ1I33jCSWcXrP+1Ku7kdqXf1oeah7ooKOIiAdKQ+uqftgCFNOSzA5AMS2XIHEYeGFg4cKRCdpxzVOQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@ethereumjs/common@3.2.0': - resolution: {integrity: sha512-pksvzI0VyLgmuEF2FA/JR/4/y6hcPq8OUail3/AvycBaW1d5VSauOZzqGvJ3RTmR4MU35lWE8KseKOsEhrFRBA==} + '@babel/plugin-transform-modules-amd@7.27.1': + resolution: {integrity: sha512-iCsytMg/N9/oFq6n+gFTvUYDZQOMK5kEdeYxmxt91fcJGycfxVP9CnrxoliM0oumFERba2i8ZtwRUCMhvP1LnA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@ethereumjs/rlp@4.0.1': - resolution: {integrity: sha512-tqsQiBQDQdmPWE1xkkBq4rlSW5QZpLOUJ5RJh2/9fug+q9tnUhuZoVLk7s0scUIKTOzEtR72DFBXI4WiZcMpvw==} - engines: {node: '>=14'} - hasBin: true + '@babel/plugin-transform-modules-commonjs@7.28.6': + resolution: {integrity: sha512-jppVbf8IV9iWWwWTQIxJMAJCWBuuKx71475wHwYytrRGQ2CWiDvYlADQno3tcYpS/T2UUWFQp3nVtYfK/YBQrA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@ethereumjs/rlp@5.0.2': - resolution: {integrity: sha512-DziebCdg4JpGlEqEdGgXmjqcFoJi+JGulUXwEjsZGAscAQ7MyD/7LE/GVCP29vEQxKc7AAwjT3A2ywHp2xfoCA==} - engines: {node: '>=18'} - hasBin: true + '@babel/plugin-transform-modules-systemjs@7.28.5': + resolution: {integrity: sha512-vn5Jma98LCOeBy/KpeQhXcV2WZgaRUtjwQmjoBuLNlOmkg0fB5pdvYVeWRYI69wWKwK2cD1QbMiUQnoujWvrew==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@ethereumjs/tx@4.2.0': - resolution: {integrity: sha512-1nc6VO4jtFd172BbSnTnDQVr9IYBFl1y4xPzZdtkrkKIncBCkdbgfdRV+MiTkJYAtTxvV12GRZLqBFT1PNK6Yw==} - engines: {node: '>=14'} + '@babel/plugin-transform-modules-umd@7.27.1': + resolution: {integrity: sha512-iQBE/xC5BV1OxJbp6WG7jq9IWiD+xxlZhLrdwpPkTX3ydmXdvoCpyfJN7acaIBZaOqTfr76pgzqBJflNbeRK+w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@ethereumjs/util@8.1.0': - resolution: {integrity: sha512-zQ0IqbdX8FZ9aw11vP+dZkKDkS+kgIvQPHnSAXzP9pLu+Rfu3D3XEeLbicvoXJTYnhZiPmsZUxgdzXwNKxRPbA==} - engines: {node: '>=14'} + '@babel/plugin-transform-named-capturing-groups-regex@7.27.1': + resolution: {integrity: sha512-SstR5JYy8ddZvD6MhV0tM/j16Qds4mIpJTOd1Yu9J9pJjH93bxHECF7pgtc28XvkzTD6Pxcm/0Z73Hvk7kb3Ng==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 - '@ethereumjs/util@9.1.0': - resolution: {integrity: sha512-XBEKsYqLGXLah9PNJbgdkigthkG7TAGvlD/sH12beMXEyHDyigfcbdvHhmLyDWgDyOJn4QwiQUaF7yeuhnjdog==} - engines: {node: '>=18'} + '@babel/plugin-transform-new-target@7.27.1': + resolution: {integrity: sha512-f6PiYeqXQ05lYq3TIfIDu/MtliKUbNwkGApPUvyo6+tc7uaR4cPjPe7DFPr15Uyycg2lZU6btZ575CuQoYh7MQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@ethersproject/abi@5.8.0': - resolution: {integrity: sha512-b9YS/43ObplgyV6SlyQsG53/vkSal0MNA1fskSC4mbnCMi8R+NkcH8K9FPYNESf6jUefBUniE4SOKms0E/KK1Q==} + '@babel/plugin-transform-nullish-coalescing-operator@7.28.6': + resolution: {integrity: sha512-3wKbRgmzYbw24mDJXT7N+ADXw8BC/imU9yo9c9X9NKaLF1fW+e5H1U5QjMUBe4Qo4Ox/o++IyUkl1sVCLgevKg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@ethersproject/abstract-provider@5.8.0': - resolution: {integrity: sha512-wC9SFcmh4UK0oKuLJQItoQdzS/qZ51EJegK6EmAWlh+OptpQ/npECOR3QqECd8iGHC0RJb4WKbVdSfif4ammrg==} + '@babel/plugin-transform-numeric-separator@7.28.6': + resolution: {integrity: sha512-SJR8hPynj8outz+SlStQSwvziMN4+Bq99it4tMIf5/Caq+3iOc0JtKyse8puvyXkk3eFRIA5ID/XfunGgO5i6w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@ethersproject/abstract-signer@5.8.0': - resolution: {integrity: sha512-N0XhZTswXcmIZQdYtUnd79VJzvEwXQw6PK0dTl9VoYrEBxxCPXqS0Eod7q5TNKRxe1/5WUMuR0u0nqTF/avdCA==} + '@babel/plugin-transform-object-rest-spread@7.28.6': + resolution: {integrity: sha512-5rh+JR4JBC4pGkXLAcYdLHZjXudVxWMXbB6u6+E9lRL5TrGVbHt1TjxGbZ8CkmYw9zjkB7jutzOROArsqtncEA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@ethersproject/address@5.6.1': - resolution: {integrity: sha512-uOgF0kS5MJv9ZvCz7x6T2EXJSzotiybApn4XlOgoTX0xdtyVIJ7pF+6cGPxiEq/dpBiTfMiw7Yc81JcwhSYA0Q==} + '@babel/plugin-transform-object-super@7.27.1': + resolution: {integrity: sha512-SFy8S9plRPbIcxlJ8A6mT/CxFdJx/c04JEctz4jf8YZaVS2px34j7NXRrlGlHkN/M2gnpL37ZpGRGVFLd3l8Ng==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@ethersproject/address@5.8.0': - resolution: {integrity: sha512-GhH/abcC46LJwshoN+uBNoKVFPxUuZm6dA257z0vZkKmU1+t8xTn8oK7B9qrj8W2rFRMch4gbJl6PmVxjxBEBA==} + '@babel/plugin-transform-optional-catch-binding@7.28.6': + resolution: {integrity: sha512-R8ja/Pyrv0OGAvAXQhSTmWyPJPml+0TMqXlO5w+AsMEiwb2fg3WkOvob7UxFSL3OIttFSGSRFKQsOhJ/X6HQdQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@ethersproject/base64@5.8.0': - resolution: {integrity: sha512-lN0oIwfkYj9LbPx4xEkie6rAMJtySbpOAFXSDVQaBnAzYfB4X2Qr+FXJGxMoc3Bxp2Sm8OwvzMrywxyw0gLjIQ==} + '@babel/plugin-transform-optional-chaining@7.28.6': + resolution: {integrity: sha512-A4zobikRGJTsX9uqVFdafzGkqD30t26ck2LmOzAuLL8b2x6k3TIqRiT2xVvA9fNmFeTX484VpsdgmKNA0bS23w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@ethersproject/basex@5.8.0': - resolution: {integrity: sha512-PIgTszMlDRmNwW9nhS6iqtVfdTAKosA7llYXNmGPw4YAI1PUyMv28988wAb41/gHF/WqGdoLv0erHaRcHRKW2Q==} + '@babel/plugin-transform-parameters@7.27.7': + resolution: {integrity: sha512-qBkYTYCb76RRxUM6CcZA5KRu8K4SM8ajzVeUgVdMVO9NN9uI/GaVmBg/WKJJGnNokV9SY8FxNOVWGXzqzUidBg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@ethersproject/bignumber@5.8.0': - resolution: {integrity: sha512-ZyaT24bHaSeJon2tGPKIiHszWjD/54Sz8t57Toch475lCLljC6MgPmxk7Gtzz+ddNN5LuHea9qhAe0x3D+uYPA==} + '@babel/plugin-transform-private-methods@7.28.6': + resolution: {integrity: sha512-piiuapX9CRv7+0st8lmuUlRSmX6mBcVeNQ1b4AYzJxfCMuBfB0vBXDiGSmm03pKJw1v6cZ8KSeM+oUnM6yAExg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@ethersproject/bytes@5.8.0': - resolution: {integrity: sha512-vTkeohgJVCPVHu5c25XWaWQOZ4v+DkGoC42/TS2ond+PARCxTJvgTFUNDZovyQ/uAQ4EcpqqowKydcdmRKjg7A==} + '@babel/plugin-transform-private-property-in-object@7.28.6': + resolution: {integrity: sha512-b97jvNSOb5+ehyQmBpmhOCiUC5oVK4PMnpRvO7+ymFBoqYjeDHIU9jnrNUuwHOiL9RpGDoKBpSViarV+BU+eVA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@ethersproject/constants@5.8.0': - resolution: {integrity: sha512-wigX4lrf5Vu+axVTIvNsuL6YrV4O5AXl5ubcURKMEME5TnWBouUh0CDTWxZ2GpnRn1kcCgE7l8O5+VbV9QTTcg==} + '@babel/plugin-transform-property-literals@7.27.1': + resolution: {integrity: sha512-oThy3BCuCha8kDZ8ZkgOg2exvPYUlprMukKQXI1r1pJ47NCvxfkEy8vK+r/hT9nF0Aa4H1WUPZZjHTFtAhGfmQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@ethersproject/contracts@5.8.0': - resolution: {integrity: sha512-0eFjGz9GtuAi6MZwhb4uvUM216F38xiuR0yYCjKJpNfSEy4HUM8hvqqBj9Jmm0IUz8l0xKEhWwLIhPgxNY0yvQ==} + '@babel/plugin-transform-react-constant-elements@7.27.1': + resolution: {integrity: sha512-edoidOjl/ZxvYo4lSBOQGDSyToYVkTAwyVoa2tkuYTSmjrB1+uAedoL5iROVLXkxH+vRgA7uP4tMg2pUJpZ3Ug==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@ethersproject/hash@5.8.0': - resolution: {integrity: sha512-ac/lBcTbEWW/VGJij0CNSw/wPcw9bSRgCB0AIBz8CvED/jfvDoV9hsIIiWfvWmFEi8RcXtlNwp2jv6ozWOsooA==} + '@babel/plugin-transform-react-display-name@7.28.0': + resolution: {integrity: sha512-D6Eujc2zMxKjfa4Zxl4GHMsmhKKZ9VpcqIchJLvwTxad9zWIYulwYItBovpDOoNLISpcZSXoDJ5gaGbQUDqViA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@ethersproject/hdnode@5.8.0': - resolution: {integrity: sha512-4bK1VF6E83/3/Im0ERnnUeWOY3P1BZml4ZD3wcH8Ys0/d1h1xaFt6Zc+Dh9zXf9TapGro0T4wvO71UTCp3/uoA==} + '@babel/plugin-transform-react-jsx-development@7.27.1': + resolution: {integrity: sha512-ykDdF5yI4f1WrAolLqeF3hmYU12j9ntLQl/AOG1HAS21jxyg1Q0/J/tpREuYLfatGdGmXp/3yS0ZA76kOlVq9Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@ethersproject/json-wallets@5.8.0': - resolution: {integrity: sha512-HxblNck8FVUtNxS3VTEYJAcwiKYsBIF77W15HufqlBF9gGfhmYOJtYZp8fSDZtn9y5EaXTE87zDwzxRoTFk11w==} + '@babel/plugin-transform-react-jsx-self@7.27.1': + resolution: {integrity: sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@ethersproject/keccak256@5.8.0': - resolution: {integrity: sha512-A1pkKLZSz8pDaQ1ftutZoaN46I6+jvuqugx5KYNeQOPqq+JZ0Txm7dlWesCHB5cndJSu5vP2VKptKf7cksERng==} + '@babel/plugin-transform-react-jsx-source@7.27.1': + resolution: {integrity: sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@ethersproject/logger@5.8.0': - resolution: {integrity: sha512-Qe6knGmY+zPPWTC+wQrpitodgBfH7XoceCGL5bJVejmH+yCS3R8jJm8iiWuvWbG76RUmyEG53oqv6GMVWqunjA==} + '@babel/plugin-transform-react-jsx@7.28.6': + resolution: {integrity: sha512-61bxqhiRfAACulXSLd/GxqmAedUSrRZIu/cbaT18T1CetkTmtDN15it7i80ru4DVqRK1WMxQhXs+Lf9kajm5Ow==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@ethersproject/networks@5.8.0': - resolution: {integrity: sha512-egPJh3aPVAzbHwq8DD7Po53J4OUSsA1MjQp8Vf/OZPav5rlmWUaFLiq8cvQiGK0Z5K6LYzm29+VA/p4RL1FzNg==} + '@babel/plugin-transform-react-pure-annotations@7.27.1': + resolution: {integrity: sha512-JfuinvDOsD9FVMTHpzA/pBLisxpv1aSf+OIV8lgH3MuWrks19R27e6a6DipIg4aX1Zm9Wpb04p8wljfKrVSnPA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@ethersproject/pbkdf2@5.8.0': - resolution: {integrity: sha512-wuHiv97BrzCmfEaPbUFpMjlVg/IDkZThp9Ri88BpjRleg4iePJaj2SW8AIyE8cXn5V1tuAaMj6lzvsGJkGWskg==} + '@babel/plugin-transform-regenerator@7.28.6': + resolution: {integrity: sha512-eZhoEZHYQLL5uc1gS5e9/oTknS0sSSAtd5TkKMUp3J+S/CaUjagc0kOUPsEbDmMeva0nC3WWl4SxVY6+OBuxfw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@ethersproject/properties@5.8.0': - resolution: {integrity: sha512-PYuiEoQ+FMaZZNGrStmN7+lWjlsoufGIHdww7454FIaGdbe/p5rnaCXTr5MtBYl3NkeoVhHZuyzChPeGeKIpQw==} + '@babel/plugin-transform-regexp-modifiers@7.28.6': + resolution: {integrity: sha512-QGWAepm9qxpaIs7UM9FvUSnCGlb8Ua1RhyM4/veAxLwt3gMat/LSGrZixyuj4I6+Kn9iwvqCyPTtbdxanYoWYg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 - '@ethersproject/providers@5.8.0': - resolution: {integrity: sha512-3Il3oTzEx3o6kzcg9ZzbE+oCZYyY+3Zh83sKkn4s1DZfTUjIegHnN2Cm0kbn9YFy45FDVcuCLLONhU7ny0SsCw==} + '@babel/plugin-transform-reserved-words@7.27.1': + resolution: {integrity: sha512-V2ABPHIJX4kC7HegLkYoDpfg9PVmuWy/i6vUM5eGK22bx4YVFD3M5F0QQnWQoDs6AGsUWTVOopBiMFQgHaSkVw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@ethersproject/random@5.8.0': - resolution: {integrity: sha512-E4I5TDl7SVqyg4/kkA/qTfuLWAQGXmSOgYyO01So8hLfwgKvYK5snIlzxJMk72IFdG/7oh8yuSqY2KX7MMwg+A==} + '@babel/plugin-transform-runtime@7.28.5': + resolution: {integrity: sha512-20NUVgOrinudkIBzQ2bNxP08YpKprUkRTiRSd2/Z5GOdPImJGkoN4Z7IQe1T5AdyKI1i5L6RBmluqdSzvaq9/w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@ethersproject/rlp@5.8.0': - resolution: {integrity: sha512-LqZgAznqDbiEunaUvykH2JAoXTT9NV0Atqk8rQN9nx9SEgThA/WMx5DnW8a9FOufo//6FZOCHZ+XiClzgbqV9Q==} + '@babel/plugin-transform-shorthand-properties@7.27.1': + resolution: {integrity: sha512-N/wH1vcn4oYawbJ13Y/FxcQrWk63jhfNa7jef0ih7PHSIHX2LB7GWE1rkPrOnka9kwMxb6hMl19p7lidA+EHmQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@ethersproject/sha2@5.8.0': - resolution: {integrity: sha512-dDOUrXr9wF/YFltgTBYS0tKslPEKr6AekjqDW2dbn1L1xmjGR+9GiKu4ajxovnrDbwxAKdHjW8jNcwfz8PAz4A==} + '@babel/plugin-transform-spread@7.28.6': + resolution: {integrity: sha512-9U4QObUC0FtJl05AsUcodau/RWDytrU6uKgkxu09mLR9HLDAtUMoPuuskm5huQsoktmsYpI+bGmq+iapDcriKA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@ethersproject/signing-key@5.8.0': - resolution: {integrity: sha512-LrPW2ZxoigFi6U6aVkFN/fa9Yx/+4AtIUe4/HACTvKJdhm0eeb107EVCIQcrLZkxaSIgc/eCrX8Q1GtbH+9n3w==} + '@babel/plugin-transform-sticky-regex@7.27.1': + resolution: {integrity: sha512-lhInBO5bi/Kowe2/aLdBAawijx+q1pQzicSgnkB6dUPc1+RC8QmJHKf2OjvU+NZWitguJHEaEmbV6VWEouT58g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@ethersproject/solidity@5.8.0': - resolution: {integrity: sha512-4CxFeCgmIWamOHwYN9d+QWGxye9qQLilpgTU0XhYs1OahkclF+ewO+3V1U0mvpiuQxm5EHHmv8f7ClVII8EHsA==} + '@babel/plugin-transform-template-literals@7.27.1': + resolution: {integrity: sha512-fBJKiV7F2DxZUkg5EtHKXQdbsbURW3DZKQUWphDum0uRP6eHGGa/He9mc0mypL680pb+e/lDIthRohlv8NCHkg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@ethersproject/strings@5.8.0': - resolution: {integrity: sha512-qWEAk0MAvl0LszjdfnZ2uC8xbR2wdv4cDabyHiBh3Cldq/T8dPH3V4BbBsAYJUeonwD+8afVXld274Ls+Y1xXg==} + '@babel/plugin-transform-typeof-symbol@7.27.1': + resolution: {integrity: sha512-RiSILC+nRJM7FY5srIyc4/fGIwUhyDuuBSdWn4y6yT6gm652DpCHZjIipgn6B7MQ1ITOUnAKWixEUjQRIBIcLw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@ethersproject/transactions@5.8.0': - resolution: {integrity: sha512-UglxSDjByHG0TuU17bDfCemZ3AnKO2vYrL5/2n2oXvKzvb7Cz+W9gOWXKARjp2URVwcWlQlPOEQyAviKwT4AHg==} + '@babel/plugin-transform-typescript@7.28.6': + resolution: {integrity: sha512-0YWL2RFxOqEm9Efk5PvreamxPME8OyY0wM5wh5lHjF+VtVhdneCWGzZeSqzOfiobVqQaNCd2z0tQvnI9DaPWPw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@ethersproject/units@5.8.0': - resolution: {integrity: sha512-lxq0CAnc5kMGIiWW4Mr041VT8IhNM+Pn5T3haO74XZWFulk7wH1Gv64HqE96hT4a7iiNMdOCFEBgaxWuk8ETKQ==} + '@babel/plugin-transform-unicode-escapes@7.27.1': + resolution: {integrity: sha512-Ysg4v6AmF26k9vpfFuTZg8HRfVWzsh1kVfowA23y9j/Gu6dOuahdUVhkLqpObp3JIv27MLSii6noRnuKN8H0Mg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@ethersproject/wallet@5.8.0': - resolution: {integrity: sha512-G+jnzmgg6UxurVKRKvw27h0kvG75YKXZKdlLYmAHeF32TGUzHkOFd7Zn6QHOTYRFWnfjtSSFjBowKo7vfrXzPA==} + '@babel/plugin-transform-unicode-property-regex@7.28.6': + resolution: {integrity: sha512-4Wlbdl/sIZjzi/8St0evF0gEZrgOswVO6aOzqxh1kDZOl9WmLrHq2HtGhnOJZmHZYKP8WZ1MDLCt5DAWwRo57A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@ethersproject/web@5.8.0': - resolution: {integrity: sha512-j7+Ksi/9KfGviws6Qtf9Q7KCqRhpwrYKQPs+JBA/rKVFF/yaWLHJEH3zfVP2plVu+eys0d2DlFmhoQJayFewcw==} - - '@ethersproject/wordlists@5.8.0': - resolution: {integrity: sha512-2df9bbXicZws2Sb5S6ET493uJ0Z84Fjr3pC4tu/qlnZERibZCeUVuqdtt+7Tv9xxhUxHoIekIA7avrKUWHrezg==} + '@babel/plugin-transform-unicode-regex@7.27.1': + resolution: {integrity: sha512-xvINq24TRojDuyt6JGtHmkVkrfVV3FPT16uytxImLeBZqW3/H52yN+kM1MGuyPkIQxrzKwPHs5U/MP3qKyzkGw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@fastify/busboy@2.1.1': - resolution: {integrity: sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==} - engines: {node: '>=14'} + '@babel/plugin-transform-unicode-sets-regex@7.28.6': + resolution: {integrity: sha512-/wHc/paTUmsDYN7SZkpWxogTOBNnlx7nBQYfy6JJlCT7G3mVhltk3e++N7zV0XfgGsrqBxd4rJQt9H16I21Y1Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 - '@gemini-wallet/core@0.3.2': - resolution: {integrity: sha512-Z4aHi3ECFf5oWYWM3F1rW83GJfB9OvhBYPTmb5q+VyK3uvzvS48lwo+jwh2eOoCRWEuT/crpb9Vwp2QaS5JqgQ==} + '@babel/preset-env@7.28.6': + resolution: {integrity: sha512-GaTI4nXDrs7l0qaJ6Rg06dtOXTBCG6TMDB44zbqofCIC4PqC7SEvmFFtpxzCDw9W5aJ7RKVshgXTLvLdBFV/qw==} + engines: {node: '>=6.9.0'} peerDependencies: - viem: '>=2.0.0' + '@babel/core': ^7.0.0-0 - '@isaacs/balanced-match@4.0.1': - resolution: {integrity: sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==} - engines: {node: 20 || >=22} + '@babel/preset-modules@0.1.6-no-external-plugins': + resolution: {integrity: sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==} + peerDependencies: + '@babel/core': ^7.0.0-0 || ^8.0.0-0 <8.0.0 - '@isaacs/brace-expansion@5.0.0': - resolution: {integrity: sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==} - engines: {node: 20 || >=22} + '@babel/preset-react@7.28.5': + resolution: {integrity: sha512-Z3J8vhRq7CeLjdC58jLv4lnZ5RKFUJWqH5emvxmv9Hv3BD1T9R/Im713R4MTKwvFaV74ejZ3sM01LyEKk4ugNQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@jridgewell/gen-mapping@0.3.13': - resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} + '@babel/preset-typescript@7.28.5': + resolution: {integrity: sha512-+bQy5WOI2V6LJZpPVxY+yp66XdZ2yifu0Mc1aP5CQKgjn4QM5IN2i5fAZ4xKop47pr8rpVhiAeu+nDQa12C8+g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@jridgewell/remapping@2.3.5': - resolution: {integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==} + '@babel/runtime-corejs3@7.28.6': + resolution: {integrity: sha512-kz2fAQ5UzjV7X7D3ySxmj3vRq89dTpqOZWv76Z6pNPztkwb/0Yj1Mtx1xFrYj6mbIHysxtBot8J4o0JLCblcFw==} + engines: {node: '>=6.9.0'} - '@jridgewell/resolve-uri@3.1.2': - resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} - engines: {node: '>=6.0.0'} + '@babel/runtime@7.28.4': + resolution: {integrity: sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==} + engines: {node: '>=6.9.0'} - '@jridgewell/sourcemap-codec@1.5.5': - resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} + '@babel/template@7.27.2': + resolution: {integrity: sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==} + engines: {node: '>=6.9.0'} - '@jridgewell/trace-mapping@0.3.31': - resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} + '@babel/template@7.28.6': + resolution: {integrity: sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==} + engines: {node: '>=6.9.0'} - '@jridgewell/trace-mapping@0.3.9': - resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} + '@babel/traverse@7.28.5': + resolution: {integrity: sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ==} + engines: {node: '>=6.9.0'} - '@lit-labs/ssr-dom-shim@1.4.0': - resolution: {integrity: sha512-ficsEARKnmmW5njugNYKipTm4SFnbik7CXtoencDZzmzo/dQ+2Q0bgkzJuoJP20Aj0F+izzJjOqsnkd6F/o1bw==} + '@babel/traverse@7.28.6': + resolution: {integrity: sha512-fgWX62k02qtjqdSNTAGxmKYY/7FSL9WAS1o2Hu5+I5m9T0yxZzr4cnrfXQ/MX0rIifthCSs6FKTlzYbJcPtMNg==} + engines: {node: '>=6.9.0'} - '@lit/reactive-element@2.1.1': - resolution: {integrity: sha512-N+dm5PAYdQ8e6UlywyyrgI2t++wFGXfHx+dSJ1oBrg6FAxUj40jId++EaRm80MKX5JnlH1sBsyZ5h0bcZKemCg==} + '@babel/types@7.28.5': + resolution: {integrity: sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==} + engines: {node: '>=6.9.0'} - '@metamask/eth-json-rpc-provider@1.0.1': - resolution: {integrity: sha512-whiUMPlAOrVGmX8aKYVPvlKyG4CpQXiNNyt74vE1xb5sPvmx5oA7B/kOi/JdBvhGQq97U1/AVdXEdk2zkP8qyA==} - engines: {node: '>=14.0.0'} + '@babel/types@7.28.6': + resolution: {integrity: sha512-0ZrskXVEHSWIqZM/sQZ4EV3jZJXRkio/WCxaqKZP1g//CEWEPSfeZFcms4XeKBCHU0ZKnIkdJeU/kF+eRp5lBg==} + engines: {node: '>=6.9.0'} - '@metamask/json-rpc-engine@7.3.3': - resolution: {integrity: sha512-dwZPq8wx9yV3IX2caLi9q9xZBw2XeIoYqdyihDDDpuHVCEiqadJLwqM3zy+uwf6F1QYQ65A8aOMQg1Uw7LMLNg==} - engines: {node: '>=16.0.0'} + '@base-org/account@2.4.0': + resolution: {integrity: sha512-A4Umpi8B9/pqR78D1Yoze4xHyQaujioVRqqO3d6xuDFw9VRtjg6tK3bPlwE0aW+nVH/ntllCpPa2PbI8Rnjcug==} - '@metamask/json-rpc-engine@8.0.2': - resolution: {integrity: sha512-IoQPmql8q7ABLruW7i4EYVHWUbF74yrp63bRuXV5Zf9BQwcn5H9Ww1eLtROYvI1bUXwOiHZ6qT5CWTrDc/t/AA==} - engines: {node: '>=16.0.0'} + '@bytecodealliance/preview2-shim@0.17.0': + resolution: {integrity: sha512-JorcEwe4ud0x5BS/Ar2aQWOQoFzjq/7jcnxYXCvSMh0oRm0dQXzOA+hqLDBnOMks1LLBA7dmiLLsEBl09Yd6iQ==} - '@metamask/json-rpc-middleware-stream@7.0.2': - resolution: {integrity: sha512-yUdzsJK04Ev98Ck4D7lmRNQ8FPioXYhEUZOMS01LXW8qTvPGiRVXmVltj2p4wrLkh0vW7u6nv0mNl5xzC5Qmfg==} - engines: {node: '>=16.0.0'} + '@coinbase/cdp-sdk@1.40.1': + resolution: {integrity: sha512-VZxAUYvWbqM4gw/ZHyr9fKBlCAKdMbBQzJxpV9rMUNkdulHIrj0cko2Mw3dyVyw+gdT62jAVxzVkPuQTRnECLw==} - '@metamask/object-multiplex@2.1.0': - resolution: {integrity: sha512-4vKIiv0DQxljcXwfpnbsXcfa5glMj5Zg9mqn4xpIWqkv6uJ2ma5/GtUfLFSxhlxnR8asRMv8dDmWya1Tc1sDFA==} - engines: {node: ^16.20 || ^18.16 || >=20} + '@coinbase/wallet-sdk@3.9.3': + resolution: {integrity: sha512-N/A2DRIf0Y3PHc1XAMvbBUu4zisna6qAdqABMZwBMNEfWrXpAwx16pZGkYCLGE+Rvv1edbcB2LYDRnACNcmCiw==} - '@metamask/onboarding@1.0.1': - resolution: {integrity: sha512-FqHhAsCI+Vacx2qa5mAFcWNSrTcVGMNjzxVgaX8ECSny/BJ9/vgXP9V7WF/8vb9DltPeQkxr+Fnfmm6GHfmdTQ==} + '@coinbase/wallet-sdk@4.3.6': + resolution: {integrity: sha512-4q8BNG1ViL4mSAAvPAtpwlOs1gpC+67eQtgIwNvT3xyeyFFd+guwkc8bcX5rTmQhXpqnhzC4f0obACbP9CqMSA==} - '@metamask/providers@16.1.0': - resolution: {integrity: sha512-znVCvux30+3SaUwcUGaSf+pUckzT5ukPRpcBmy+muBLC0yaWnBcvDqGfcsw6CBIenUdFrVoAFa8B6jsuCY/a+g==} - engines: {node: ^18.18 || >=20} + '@colors/colors@1.5.0': + resolution: {integrity: sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==} + engines: {node: '>=0.1.90'} - '@metamask/rpc-errors@6.4.0': - resolution: {integrity: sha512-1ugFO1UoirU2esS3juZanS/Fo8C8XYocCuBpfZI5N7ECtoG+zu0wF+uWZASik6CkO6w9n/Iebt4iI4pT0vptpg==} - engines: {node: '>=16.0.0'} + '@cspotcode/source-map-support@0.8.1': + resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} + engines: {node: '>=12'} - '@metamask/rpc-errors@7.0.2': - resolution: {integrity: sha512-YYYHsVYd46XwY2QZzpGeU4PSdRhHdxnzkB8piWGvJW2xbikZ3R+epAYEL4q/K8bh9JPTucsUdwRFnACor1aOYw==} - engines: {node: ^18.20 || ^20.17 || >=22} + '@csstools/cascade-layer-name-parser@2.0.5': + resolution: {integrity: sha512-p1ko5eHgV+MgXFVa4STPKpvPxr6ReS8oS2jzTukjR74i5zJNyWO1ZM1m8YKBXnzDKWfBN1ztLYlHxbVemDD88A==} + engines: {node: '>=18'} + peerDependencies: + '@csstools/css-parser-algorithms': ^3.0.5 + '@csstools/css-tokenizer': ^3.0.4 - '@metamask/safe-event-emitter@2.0.0': - resolution: {integrity: sha512-/kSXhY692qiV1MXu6EeOZvg5nECLclxNXcKCxJ3cXQgYuRymRHpdx/t7JXfsK+JLjwA1e1c1/SBrlQYpusC29Q==} + '@csstools/color-helpers@5.1.0': + resolution: {integrity: sha512-S11EXWJyy0Mz5SYvRmY8nJYTFFd1LCNV+7cXyAgQtOOuzb4EsgfqDufL+9esx72/eLhsRdGZwaldu/h+E4t4BA==} + engines: {node: '>=18'} - '@metamask/safe-event-emitter@3.1.2': - resolution: {integrity: sha512-5yb2gMI1BDm0JybZezeoX/3XhPDOtTbcFvpTXM9kxsoZjPZFh4XciqRbpD6N86HYZqWDhEaKUDuOyR0sQHEjMA==} - engines: {node: '>=12.0.0'} + '@csstools/css-calc@2.1.4': + resolution: {integrity: sha512-3N8oaj+0juUw/1H3YwmDDJXCgTB1gKU6Hc/bB502u9zR0q2vd786XJH9QfrKIEgFlZmhZiq6epXl4rHqhzsIgQ==} + engines: {node: '>=18'} + peerDependencies: + '@csstools/css-parser-algorithms': ^3.0.5 + '@csstools/css-tokenizer': ^3.0.4 - '@metamask/sdk-analytics@0.0.5': - resolution: {integrity: sha512-fDah+keS1RjSUlC8GmYXvx6Y26s3Ax1U9hGpWb6GSY5SAdmTSIqp2CvYy6yW0WgLhnYhW+6xERuD0eVqV63QIQ==} + '@csstools/css-color-parser@3.1.0': + resolution: {integrity: sha512-nbtKwh3a6xNVIp/VRuXV64yTKnb1IjTAEEh3irzS+HkKjAOYLTGNb9pmVNntZ8iVBHcWDA2Dof0QtPgFI1BaTA==} + engines: {node: '>=18'} + peerDependencies: + '@csstools/css-parser-algorithms': ^3.0.5 + '@csstools/css-tokenizer': ^3.0.4 - '@metamask/sdk-communication-layer@0.33.1': - resolution: {integrity: sha512-0bI9hkysxcfbZ/lk0T2+aKVo1j0ynQVTuB3sJ5ssPWlz+Z3VwveCkP1O7EVu1tsVVCb0YV5WxK9zmURu2FIiaA==} + '@csstools/css-parser-algorithms@3.0.5': + resolution: {integrity: sha512-DaDeUkXZKjdGhgYaHNJTV9pV7Y9B3b644jCLs9Upc3VeNGg6LWARAT6O+Q+/COo+2gg/bM5rhpMAtf70WqfBdQ==} + engines: {node: '>=18'} peerDependencies: - cross-fetch: ^4.0.0 - eciesjs: '*' - eventemitter2: ^6.4.9 - readable-stream: ^3.6.2 - socket.io-client: ^4.5.1 + '@csstools/css-tokenizer': ^3.0.4 - '@metamask/sdk-install-modal-web@0.32.1': - resolution: {integrity: sha512-MGmAo6qSjf1tuYXhCu2EZLftq+DSt5Z7fsIKr2P+lDgdTPWgLfZB1tJKzNcwKKOdf6q9Qmmxn7lJuI/gq5LrKw==} + '@csstools/css-tokenizer@3.0.4': + resolution: {integrity: sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw==} + engines: {node: '>=18'} - '@metamask/sdk@0.33.1': - resolution: {integrity: sha512-1mcOQVGr9rSrVcbKPNVzbZ8eCl1K0FATsYH3WJ/MH4WcZDWGECWrXJPNMZoEAkLxWiMe8jOQBumg2pmcDa9zpQ==} + '@csstools/media-query-list-parser@4.0.3': + resolution: {integrity: sha512-HAYH7d3TLRHDOUQK4mZKf9k9Ph/m8Akstg66ywKR4SFAigjs3yBiUeZtFxywiTm5moZMAp/5W/ZuFnNXXYLuuQ==} + engines: {node: '>=18'} + peerDependencies: + '@csstools/css-parser-algorithms': ^3.0.5 + '@csstools/css-tokenizer': ^3.0.4 - '@metamask/superstruct@3.2.1': - resolution: {integrity: sha512-fLgJnDOXFmuVlB38rUN5SmU7hAFQcCjrg3Vrxz67KTY7YHFnSNEKvX4avmEBdOI0yTCxZjwMCFEqsC8k2+Wd3g==} - engines: {node: '>=16.0.0'} + '@csstools/postcss-alpha-function@1.0.1': + resolution: {integrity: sha512-isfLLwksH3yHkFXfCI2Gcaqg7wGGHZZwunoJzEZk0yKYIokgre6hYVFibKL3SYAoR1kBXova8LB+JoO5vZzi9w==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 - '@metamask/utils@11.9.0': - resolution: {integrity: sha512-wRnoSDD9jTWOge/+reFviJQANhS+uy8Y+OEwRanp5mQeGTjBFmK1r2cTOnei2UCZRV1crXHzeJVSFEoDDcgRbA==} - engines: {node: ^18.18 || ^20.14 || >=22} + '@csstools/postcss-cascade-layers@5.0.2': + resolution: {integrity: sha512-nWBE08nhO8uWl6kSAeCx4im7QfVko3zLrtgWZY4/bP87zrSPpSyN/3W3TDqz1jJuH+kbKOHXg5rJnK+ZVYcFFg==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 - '@metamask/utils@5.0.2': - resolution: {integrity: sha512-yfmE79bRQtnMzarnKfX7AEJBwFTxvTyw3nBQlu/5rmGXrjAeAMltoGxO62TFurxrQAFMNa/fEjIHNvungZp0+g==} - engines: {node: '>=14.0.0'} + '@csstools/postcss-color-function-display-p3-linear@1.0.1': + resolution: {integrity: sha512-E5qusdzhlmO1TztYzDIi8XPdPoYOjoTY6HBYBCYSj+Gn4gQRBlvjgPQXzfzuPQqt8EhkC/SzPKObg4Mbn8/xMg==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 - '@metamask/utils@8.5.0': - resolution: {integrity: sha512-I6bkduevXb72TIM9q2LRO63JSsF9EXduh3sBr9oybNX2hNNpr/j1tEjXrsG0Uabm4MJ1xkGAQEMwifvKZIkyxQ==} - engines: {node: '>=16.0.0'} + '@csstools/postcss-color-function@4.0.12': + resolution: {integrity: sha512-yx3cljQKRaSBc2hfh8rMZFZzChaFgwmO2JfFgFr1vMcF3C/uyy5I4RFIBOIWGq1D+XbKCG789CGkG6zzkLpagA==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 - '@metamask/utils@9.3.0': - resolution: {integrity: sha512-w8CVbdkDrVXFJbfBSlDfafDR6BAkpDmv1bC1UJVCoVny5tW2RKAdn9i68Xf7asYT4TnUhl/hN4zfUiKQq9II4g==} - engines: {node: '>=16.0.0'} + '@csstools/postcss-color-mix-function@3.0.12': + resolution: {integrity: sha512-4STERZfCP5Jcs13P1U5pTvI9SkgLgfMUMhdXW8IlJWkzOOOqhZIjcNhWtNJZes2nkBDsIKJ0CJtFtuaZ00moag==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 - '@noble/ciphers@1.2.1': - resolution: {integrity: sha512-rONPWMC7PeExE077uLE4oqWrZ1IvAfz3oH9LibVAcVCopJiA9R62uavnbEzdkVmJYI6M6Zgkbeb07+tWjlq2XA==} - engines: {node: ^14.21.3 || >=16} + '@csstools/postcss-color-mix-variadic-function-arguments@1.0.2': + resolution: {integrity: sha512-rM67Gp9lRAkTo+X31DUqMEq+iK+EFqsidfecmhrteErxJZb6tUoJBVQca1Vn1GpDql1s1rD1pKcuYzMsg7Z1KQ==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 - '@noble/ciphers@1.3.0': - resolution: {integrity: sha512-2I0gnIVPtfnMw9ee9h1dJG7tp81+8Ob3OJb3Mv37rx5L40/b0i7djjCVvGOVqc9AEIQyvyu1i6ypKdFw8R8gQw==} - engines: {node: ^14.21.3 || >=16} + '@csstools/postcss-content-alt-text@2.0.8': + resolution: {integrity: sha512-9SfEW9QCxEpTlNMnpSqFaHyzsiRpZ5J5+KqCu1u5/eEJAWsMhzT40qf0FIbeeglEvrGRMdDzAxMIz3wqoGSb+Q==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 - '@noble/curves@1.2.0': - resolution: {integrity: sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==} + '@csstools/postcss-contrast-color-function@2.0.12': + resolution: {integrity: sha512-YbwWckjK3qwKjeYz/CijgcS7WDUCtKTd8ShLztm3/i5dhh4NaqzsbYnhm4bjrpFpnLZ31jVcbK8YL77z3GBPzA==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 - '@noble/curves@1.4.2': - resolution: {integrity: sha512-TavHr8qycMChk8UwMld0ZDRvatedkzWfH8IiaeGCfymOP5i0hSCozz9vHOL0nkwk7HRMlFnAiKpS2jrUmSybcw==} + '@csstools/postcss-exponential-functions@2.0.9': + resolution: {integrity: sha512-abg2W/PI3HXwS/CZshSa79kNWNZHdJPMBXeZNyPQFbbj8sKO3jXxOt/wF7juJVjyDTc6JrvaUZYFcSBZBhaxjw==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 - '@noble/curves@1.8.0': - resolution: {integrity: sha512-j84kjAbzEnQHaSIhRPUmB3/eVXu2k3dKPl2LOrR8fSOIL+89U+7lV117EWHtq/GHM3ReGHM46iRBdZfpc4HRUQ==} - engines: {node: ^14.21.3 || >=16} + '@csstools/postcss-font-format-keywords@4.0.0': + resolution: {integrity: sha512-usBzw9aCRDvchpok6C+4TXC57btc4bJtmKQWOHQxOVKen1ZfVqBUuCZ/wuqdX5GHsD0NRSr9XTP+5ID1ZZQBXw==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 - '@noble/curves@1.8.1': - resolution: {integrity: sha512-warwspo+UYUPep0Q+vtdVB4Ugn8GGQj8iyB3gnRWsztmUHTI3S1nhdiWNsPUGL0vud7JlRRk1XEu7Lq1KGTnMQ==} - engines: {node: ^14.21.3 || >=16} + '@csstools/postcss-gamut-mapping@2.0.11': + resolution: {integrity: sha512-fCpCUgZNE2piVJKC76zFsgVW1apF6dpYsqGyH8SIeCcM4pTEsRTWTLCaJIMKFEundsCKwY1rwfhtrio04RJ4Dw==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 - '@noble/curves@1.8.2': - resolution: {integrity: sha512-vnI7V6lFNe0tLAuJMu+2sX+FcL14TaCWy1qiczg1VwRmPrpQCdq5ESXQMqUc2tluRNf6irBXrWbl1mGN8uaU/g==} - engines: {node: ^14.21.3 || >=16} + '@csstools/postcss-gradients-interpolation-method@5.0.12': + resolution: {integrity: sha512-jugzjwkUY0wtNrZlFeyXzimUL3hN4xMvoPnIXxoZqxDvjZRiSh+itgHcVUWzJ2VwD/VAMEgCLvtaJHX+4Vj3Ow==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 - '@noble/curves@1.9.1': - resolution: {integrity: sha512-k11yZxZg+t+gWvBbIswW0yoJlu8cHOC7dhunwOzoWH/mXGBiYyR4YY6hAEK/3EUs4UpB8la1RfdRpeGsFHkWsA==} - engines: {node: ^14.21.3 || >=16} + '@csstools/postcss-hwb-function@4.0.12': + resolution: {integrity: sha512-mL/+88Z53KrE4JdePYFJAQWFrcADEqsLprExCM04GDNgHIztwFzj0Mbhd/yxMBngq0NIlz58VVxjt5abNs1VhA==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 - '@noble/curves@1.9.7': - resolution: {integrity: sha512-gbKGcRUYIjA3/zCCNaWDciTMFI0dCkvou3TL8Zmy5Nc7sJ47a0jtOeZoTaMxkuqRo9cRhjOdZJXegxYE5FN/xw==} - engines: {node: ^14.21.3 || >=16} + '@csstools/postcss-ic-unit@4.0.4': + resolution: {integrity: sha512-yQ4VmossuOAql65sCPppVO1yfb7hDscf4GseF0VCA/DTDaBc0Wtf8MTqVPfjGYlT5+2buokG0Gp7y0atYZpwjg==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 - '@noble/hashes@1.2.0': - resolution: {integrity: sha512-FZfhjEDbT5GRswV3C6uvLPHMiVD6lQBmpoX5+eSiPaMTXte/IKqI5dykDxzZB/WBeK/CDuQRBWarPdi3FNY2zQ==} + '@csstools/postcss-initial@2.0.1': + resolution: {integrity: sha512-L1wLVMSAZ4wovznquK0xmC7QSctzO4D0Is590bxpGqhqjboLXYA16dWZpfwImkdOgACdQ9PqXsuRroW6qPlEsg==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 - '@noble/hashes@1.3.2': - resolution: {integrity: sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==} - engines: {node: '>= 16'} + '@csstools/postcss-is-pseudo-class@5.0.3': + resolution: {integrity: sha512-jS/TY4SpG4gszAtIg7Qnf3AS2pjcUM5SzxpApOrlndMeGhIbaTzWBzzP/IApXoNWEW7OhcjkRT48jnAUIFXhAQ==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 - '@noble/hashes@1.4.0': - resolution: {integrity: sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==} - engines: {node: '>= 16'} + '@csstools/postcss-light-dark-function@2.0.11': + resolution: {integrity: sha512-fNJcKXJdPM3Lyrbmgw2OBbaioU7yuKZtiXClf4sGdQttitijYlZMD5K7HrC/eF83VRWRrYq6OZ0Lx92leV2LFA==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 - '@noble/hashes@1.7.0': - resolution: {integrity: sha512-HXydb0DgzTpDPwbVeDGCG1gIu7X6+AuU6Zl6av/E/KG8LMsvPntvq+w17CHRpKBmN6Ybdrt1eP3k4cj8DJa78w==} - engines: {node: ^14.21.3 || >=16} + '@csstools/postcss-logical-float-and-clear@3.0.0': + resolution: {integrity: sha512-SEmaHMszwakI2rqKRJgE+8rpotFfne1ZS6bZqBoQIicFyV+xT1UF42eORPxJkVJVrH9C0ctUgwMSn3BLOIZldQ==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 - '@noble/hashes@1.7.1': - resolution: {integrity: sha512-B8XBPsn4vT/KJAGqDzbwztd+6Yte3P4V7iafm24bxgDe/mlRuK6xmWPuCNrKt2vDafZ8MfJLlchDG/vYafQEjQ==} - engines: {node: ^14.21.3 || >=16} + '@csstools/postcss-logical-overflow@2.0.0': + resolution: {integrity: sha512-spzR1MInxPuXKEX2csMamshR4LRaSZ3UXVaRGjeQxl70ySxOhMpP2252RAFsg8QyyBXBzuVOOdx1+bVO5bPIzA==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 - '@noble/hashes@1.7.2': - resolution: {integrity: sha512-biZ0NUSxyjLLqo6KxEJ1b+C2NAx0wtDoFvCaXHGgUkeHzf3Xc1xKumFKREuT7f7DARNZ/slvYUwFG6B0f2b6hQ==} - engines: {node: ^14.21.3 || >=16} + '@csstools/postcss-logical-overscroll-behavior@2.0.0': + resolution: {integrity: sha512-e/webMjoGOSYfqLunyzByZj5KKe5oyVg/YSbie99VEaSDE2kimFm0q1f6t/6Jo+VVCQ/jbe2Xy+uX+C4xzWs4w==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 - '@noble/hashes@1.8.0': - resolution: {integrity: sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==} - engines: {node: ^14.21.3 || >=16} + '@csstools/postcss-logical-resize@3.0.0': + resolution: {integrity: sha512-DFbHQOFW/+I+MY4Ycd/QN6Dg4Hcbb50elIJCfnwkRTCX05G11SwViI5BbBlg9iHRl4ytB7pmY5ieAFk3ws7yyg==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 - '@noble/secp256k1@1.7.1': - resolution: {integrity: sha512-hOUk6AyBFmqVrv7k5WAw/LpszxVbj9gGN4JRkIX52fdFAj1UA61KXmZDvqVEm+pOyec3+fIeZB02LYa/pWOArw==} + '@csstools/postcss-logical-viewport-units@3.0.4': + resolution: {integrity: sha512-q+eHV1haXA4w9xBwZLKjVKAWn3W2CMqmpNpZUk5kRprvSiBEGMgrNH3/sJZ8UA3JgyHaOt3jwT9uFa4wLX4EqQ==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 - '@noble/secp256k1@2.3.0': - resolution: {integrity: sha512-0TQed2gcBbIrh7Ccyw+y/uZQvbJwm7Ao4scBUxqpBCcsOlZG0O4KGfjtNAy/li4W8n1xt3dxrwJ0beZ2h2G6Kw==} + '@csstools/postcss-media-minmax@2.0.9': + resolution: {integrity: sha512-af9Qw3uS3JhYLnCbqtZ9crTvvkR+0Se+bBqSr7ykAnl9yKhk6895z9rf+2F4dClIDJWxgn0iZZ1PSdkhrbs2ig==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 - '@nodelib/fs.scandir@2.1.5': - resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} - engines: {node: '>= 8'} + '@csstools/postcss-media-queries-aspect-ratio-number-values@3.0.5': + resolution: {integrity: sha512-zhAe31xaaXOY2Px8IYfoVTB3wglbJUVigGphFLj6exb7cjZRH9A6adyE22XfFK3P2PzwRk0VDeTJmaxpluyrDg==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 - '@nodelib/fs.stat@2.0.5': - resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} - engines: {node: '>= 8'} + '@csstools/postcss-nested-calc@4.0.0': + resolution: {integrity: sha512-jMYDdqrQQxE7k9+KjstC3NbsmC063n1FTPLCgCRS2/qHUbHM0mNy9pIn4QIiQGs9I/Bg98vMqw7mJXBxa0N88A==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 - '@nodelib/fs.walk@1.2.8': - resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} - engines: {node: '>= 8'} + '@csstools/postcss-normalize-display-values@4.0.1': + resolution: {integrity: sha512-TQUGBuRvxdc7TgNSTevYqrL8oItxiwPDixk20qCB5me/W8uF7BPbhRrAvFuhEoywQp/woRsUZ6SJ+sU5idZAIA==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 - '@nomicfoundation/edr-darwin-arm64@0.12.0-next.17': - resolution: {integrity: sha512-gI9/9ysLeAid0+VSTBeutxOJ0/Rrh00niGkGL9+4lR577igDY+v55XGN0oBMST49ILS0f12J6ZY90LG8sxPXmQ==} - engines: {node: '>= 20'} + '@csstools/postcss-oklab-function@4.0.12': + resolution: {integrity: sha512-HhlSmnE1NKBhXsTnNGjxvhryKtO7tJd1w42DKOGFD6jSHtYOrsJTQDKPMwvOfrzUAk8t7GcpIfRyM7ssqHpFjg==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 - '@nomicfoundation/edr-darwin-x64@0.12.0-next.17': - resolution: {integrity: sha512-zSZtwf584RkIyb8awELDt7ctskogH0p4pmqOC4vhykc8ODOv2XLuG1IgeE4WgYhWGZOufbCtgLfpJQrWqN6mmw==} - engines: {node: '>= 20'} + '@csstools/postcss-position-area-property@1.0.0': + resolution: {integrity: sha512-fUP6KR8qV2NuUZV3Cw8itx0Ep90aRjAZxAEzC3vrl6yjFv+pFsQbR18UuQctEKmA72K9O27CoYiKEgXxkqjg8Q==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 - '@nomicfoundation/edr-linux-arm64-gnu@0.12.0-next.17': - resolution: {integrity: sha512-WjdfgV6B7gT5Q0NXtSIWyeK8gzaJX5HK6/jclYVHarWuEtS1LFgePYgMjK8rmm7IRTkM9RsE/PCuQEP1nrSsuA==} - engines: {node: '>= 20'} + '@csstools/postcss-progressive-custom-properties@4.2.1': + resolution: {integrity: sha512-uPiiXf7IEKtUQXsxu6uWtOlRMXd2QWWy5fhxHDnPdXKCQckPP3E34ZgDoZ62r2iT+UOgWsSbM4NvHE5m3mAEdw==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 - '@nomicfoundation/edr-linux-arm64-musl@0.12.0-next.17': - resolution: {integrity: sha512-26rObKhhCDb9JkZbToyr7JVZo4tSVAFvzoJSJVmvpOl0LOHrfFsgVQu2n/8cNkwMAqulPubKL2E0jdnmEoZjWA==} - engines: {node: '>= 20'} + '@csstools/postcss-property-rule-prelude-list@1.0.0': + resolution: {integrity: sha512-IxuQjUXq19fobgmSSvUDO7fVwijDJaZMvWQugxfEUxmjBeDCVaDuMpsZ31MsTm5xbnhA+ElDi0+rQ7sQQGisFA==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 - '@nomicfoundation/edr-linux-x64-gnu@0.12.0-next.17': - resolution: {integrity: sha512-dPkHScIf/CU6h6k3k4HNUnQyQcVSLKanviHCAcs5HkviiJPxvVtOMMvtNBxoIvKZRxGFxf2eutcqQW4ZV1wRQQ==} - engines: {node: '>= 20'} + '@csstools/postcss-random-function@2.0.1': + resolution: {integrity: sha512-q+FQaNiRBhnoSNo+GzqGOIBKoHQ43lYz0ICrV+UudfWnEF6ksS6DsBIJSISKQT2Bvu3g4k6r7t0zYrk5pDlo8w==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 - '@nomicfoundation/edr-linux-x64-musl@0.12.0-next.17': - resolution: {integrity: sha512-5Ixe/bpyWZxC3AjIb8EomAOK44ajemBVx/lZRHZiWSBlwQpbSWriYAtKjKcReQQPwuYVjnFpAD2AtuCvseIjHw==} - engines: {node: '>= 20'} + '@csstools/postcss-relative-color-syntax@3.0.12': + resolution: {integrity: sha512-0RLIeONxu/mtxRtf3o41Lq2ghLimw0w9ByLWnnEVuy89exmEEq8bynveBxNW3nyHqLAFEeNtVEmC1QK9MZ8Huw==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 - '@nomicfoundation/edr-win32-x64-msvc@0.12.0-next.17': - resolution: {integrity: sha512-29YlvdgofSdXG1mUzIuH4kMXu1lmVc1hvYWUGWEH59L+LaakdhfJ/Wu5izeclKkrTh729Amtk/Hk1m29kFOO8A==} - engines: {node: '>= 20'} + '@csstools/postcss-scope-pseudo-class@4.0.1': + resolution: {integrity: sha512-IMi9FwtH6LMNuLea1bjVMQAsUhFxJnyLSgOp/cpv5hrzWmrUYU5fm0EguNDIIOHUqzXode8F/1qkC/tEo/qN8Q==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 - '@nomicfoundation/edr@0.12.0-next.17': - resolution: {integrity: sha512-Y8Kwqd5JpBmI/Kst6NJ/bZ81FeJea9J6WEwoSRTZnEvwfqW9dk9PI8zJs2UJpOACL1fXEPvN+doETbxT9EhwXA==} - engines: {node: '>= 20'} + '@csstools/postcss-sign-functions@1.1.4': + resolution: {integrity: sha512-P97h1XqRPcfcJndFdG95Gv/6ZzxUBBISem0IDqPZ7WMvc/wlO+yU0c5D/OCpZ5TJoTt63Ok3knGk64N+o6L2Pg==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 - '@nomicfoundation/hardhat-chai-matchers@2.1.0': - resolution: {integrity: sha512-GPhBNafh1fCnVD9Y7BYvoLnblnvfcq3j8YDbO1gGe/1nOFWzGmV7gFu5DkwFXF+IpYsS+t96o9qc/mPu3V3Vfw==} + '@csstools/postcss-stepped-value-functions@4.0.9': + resolution: {integrity: sha512-h9btycWrsex4dNLeQfyU3y3w40LMQooJWFMm/SK9lrKguHDcFl4VMkncKKoXi2z5rM9YGWbUQABI8BT2UydIcA==} + engines: {node: '>=18'} peerDependencies: - '@nomicfoundation/hardhat-ethers': ^3.1.0 - chai: ^4.2.0 - ethers: ^6.14.0 - hardhat: ^2.26.0 + postcss: ^8.4 - '@nomicfoundation/hardhat-ethers@3.1.3': - resolution: {integrity: sha512-208JcDeVIl+7Wu3MhFUUtiA8TJ7r2Rn3Wr+lSx9PfsDTKkbsAsWPY6N6wQ4mtzDv0/pB9nIbJhkjoHe1EsgNsA==} + '@csstools/postcss-syntax-descriptor-syntax-production@1.0.1': + resolution: {integrity: sha512-GneqQWefjM//f4hJ/Kbox0C6f2T7+pi4/fqTqOFGTL3EjnvOReTqO1qUQ30CaUjkwjYq9qZ41hzarrAxCc4gow==} + engines: {node: '>=18'} peerDependencies: - ethers: ^6.14.0 - hardhat: ^2.28.0 + postcss: ^8.4 - '@nomicfoundation/hardhat-ignition-ethers@0.15.17': - resolution: {integrity: sha512-io6Wrp1dUsJ94xEI3pw6qkPfhc9TFA+e6/+o16yQ8pvBTFMjgK5x8wIHKrrIHr9L3bkuTMtmDjyN4doqO2IqFQ==} + '@csstools/postcss-system-ui-font-family@1.0.0': + resolution: {integrity: sha512-s3xdBvfWYfoPSBsikDXbuorcMG1nN1M6GdU0qBsGfcmNR0A/qhloQZpTxjA3Xsyrk1VJvwb2pOfiOT3at/DuIQ==} + engines: {node: '>=18'} peerDependencies: - '@nomicfoundation/hardhat-ethers': ^3.1.0 - '@nomicfoundation/hardhat-ignition': ^0.15.16 - '@nomicfoundation/ignition-core': ^0.15.15 - ethers: ^6.14.0 - hardhat: ^2.26.0 + postcss: ^8.4 - '@nomicfoundation/hardhat-ignition@0.15.16': - resolution: {integrity: sha512-T0JTnuib7QcpsWkHCPLT7Z6F483EjTdcdjb1e00jqS9zTGCPqinPB66LLtR/duDLdvgoiCVS6K8WxTQkA/xR1Q==} + '@csstools/postcss-text-decoration-shorthand@4.0.3': + resolution: {integrity: sha512-KSkGgZfx0kQjRIYnpsD7X2Om9BUXX/Kii77VBifQW9Ih929hK0KNjVngHDH0bFB9GmfWcR9vJYJJRvw/NQjkrA==} + engines: {node: '>=18'} peerDependencies: - '@nomicfoundation/hardhat-verify': ^2.1.0 - hardhat: ^2.26.0 + postcss: ^8.4 - '@nomicfoundation/hardhat-network-helpers@1.1.2': - resolution: {integrity: sha512-p7HaUVDbLj7ikFivQVNhnfMHUBgiHYMwQWvGn9AriieuopGOELIrwj2KjyM2a6z70zai5YKO264Vwz+3UFJZPQ==} + '@csstools/postcss-trigonometric-functions@4.0.9': + resolution: {integrity: sha512-Hnh5zJUdpNrJqK9v1/E3BbrQhaDTj5YiX7P61TOvUhoDHnUmsNNxcDAgkQ32RrcWx9GVUvfUNPcUkn8R3vIX6A==} + engines: {node: '>=18'} peerDependencies: - hardhat: ^2.26.0 + postcss: ^8.4 - '@nomicfoundation/hardhat-toolbox@5.0.0': - resolution: {integrity: sha512-FnUtUC5PsakCbwiVNsqlXVIWG5JIb5CEZoSXbJUsEBun22Bivx2jhF1/q9iQbzuaGpJKFQyOhemPB2+XlEE6pQ==} + '@csstools/postcss-unset-value@4.0.0': + resolution: {integrity: sha512-cBz3tOCI5Fw6NIFEwU3RiwK6mn3nKegjpJuzCndoGq3BZPkUjnsq7uQmIeMNeMbMk7YD2MfKcgCpZwX5jyXqCA==} + engines: {node: '>=18'} peerDependencies: - '@nomicfoundation/hardhat-chai-matchers': ^2.0.0 - '@nomicfoundation/hardhat-ethers': ^3.0.0 - '@nomicfoundation/hardhat-ignition-ethers': ^0.15.0 - '@nomicfoundation/hardhat-network-helpers': ^1.0.0 - '@nomicfoundation/hardhat-verify': ^2.0.0 - '@typechain/ethers-v6': ^0.5.0 - '@typechain/hardhat': ^9.0.0 - '@types/chai': ^4.2.0 - '@types/mocha': '>=9.1.0' - '@types/node': '>=18.0.0' - chai: ^4.2.0 - ethers: ^6.4.0 - hardhat: ^2.11.0 - hardhat-gas-reporter: ^1.0.8 - solidity-coverage: ^0.8.1 - ts-node: '>=8.0.0' - typechain: ^8.3.0 - typescript: '>=4.5.0' + postcss: ^8.4 - '@nomicfoundation/hardhat-verify@2.1.3': - resolution: {integrity: sha512-danbGjPp2WBhLkJdQy9/ARM3WQIK+7vwzE0urNem1qZJjh9f54Kf5f1xuQv8DvqewUAkuPxVt/7q4Grz5WjqSg==} + '@csstools/selector-resolve-nested@3.1.0': + resolution: {integrity: sha512-mf1LEW0tJLKfWyvn5KdDrhpxHyuxpbNwTIwOYLIvsTffeyOf85j5oIzfG0yosxDgx/sswlqBnESYUcQH0vgZ0g==} + engines: {node: '>=18'} peerDependencies: - hardhat: ^2.26.0 + postcss-selector-parser: ^7.0.0 - '@nomicfoundation/ignition-core@0.15.15': - resolution: {integrity: sha512-JdKFxYknTfOYtFXMN6iFJ1vALJPednuB+9p9OwGIRdoI6HYSh4ZBzyRURgyXtHFyaJ/SF9lBpsYV9/1zEpcYwg==} + '@csstools/selector-specificity@5.0.0': + resolution: {integrity: sha512-PCqQV3c4CoVm3kdPhyeZ07VmBRdH2EpMFA/pd9OASpOEC3aXNGoqPDAZ80D0cLpMBxnmk0+yNhGsEx31hq7Gtw==} + engines: {node: '>=18'} + peerDependencies: + postcss-selector-parser: ^7.0.0 - '@nomicfoundation/ignition-ui@0.15.13': - resolution: {integrity: sha512-HbTszdN1iDHCkUS9hLeooqnLEW2U45FaqFwFEYT8nIno2prFZhG+n68JEERjmfFCB5u0WgbuJwk3CgLoqtSL7Q==} + '@csstools/utilities@2.0.0': + resolution: {integrity: sha512-5VdOr0Z71u+Yp3ozOx8T11N703wIFGVRgOWbOZMKgglPJsWA54MRIoMNVMa7shUToIhx5J8vX4sOZgD2XiihiQ==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 - '@nomicfoundation/slang@0.18.3': - resolution: {integrity: sha512-YqAWgckqbHM0/CZxi9Nlf4hjk9wUNLC9ngWCWBiqMxPIZmzsVKYuChdlrfeBPQyvQQBoOhbx+7C1005kLVQDZQ==} + '@discoveryjs/json-ext@0.5.7': + resolution: {integrity: sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==} + engines: {node: '>=10.0.0'} - '@nomicfoundation/solidity-analyzer-darwin-arm64@0.1.2': - resolution: {integrity: sha512-JaqcWPDZENCvm++lFFGjrDd8mxtf+CtLd2MiXvMNTBD33dContTZ9TWETwNFwg7JTJT5Q9HEecH7FA+HTSsIUw==} - engines: {node: '>= 12'} + '@docsearch/css@4.5.2': + resolution: {integrity: sha512-SostZzX+ZwBEf1Z6WJ9W7kqU6GuhDeVm9PWWDJ38yeVT0IkXhbWuDNRIFdlwVbBB1Gk86071pTpJ9/0qhutoYQ==} - '@nomicfoundation/solidity-analyzer-darwin-x64@0.1.2': - resolution: {integrity: sha512-fZNmVztrSXC03e9RONBT+CiksSeYcxI1wlzqyr0L7hsQlK1fzV+f04g2JtQ1c/Fe74ZwdV6aQBdd6Uwl1052sw==} - engines: {node: '>= 12'} + '@docsearch/react@4.5.2': + resolution: {integrity: sha512-9Za+MWCRwWvC1Crd3X4GP/ku7byAKd7OSZ0QVJBRLh3QSTFrfbmzRceflYyzbgV6vBQlOJuhlGapzjID4/6Z8A==} + peerDependencies: + '@types/react': '>= 16.8.0 < 20.0.0' + react: '>= 16.8.0 < 20.0.0' + react-dom: '>= 16.8.0 < 20.0.0' + search-insights: '>= 1 < 3' + peerDependenciesMeta: + '@types/react': + optional: true + react: + optional: true + react-dom: + optional: true + search-insights: + optional: true - '@nomicfoundation/solidity-analyzer-linux-arm64-gnu@0.1.2': - resolution: {integrity: sha512-3d54oc+9ZVBuB6nbp8wHylk4xh0N0Gc+bk+/uJae+rUgbOBwQSfuGIbAZt1wBXs5REkSmynEGcqx6DutoK0tPA==} - engines: {node: '>= 12'} + '@docusaurus/babel@3.9.2': + resolution: {integrity: sha512-GEANdi/SgER+L7Japs25YiGil/AUDnFFHaCGPBbundxoWtCkA2lmy7/tFmgED4y1htAy6Oi4wkJEQdGssnw9MA==} + engines: {node: '>=20.0'} - '@nomicfoundation/solidity-analyzer-linux-arm64-musl@0.1.2': - resolution: {integrity: sha512-iDJfR2qf55vgsg7BtJa7iPiFAsYf2d0Tv/0B+vhtnI16+wfQeTbP7teookbGvAo0eJo7aLLm0xfS/GTkvHIucA==} - engines: {node: '>= 12'} + '@docusaurus/bundler@3.9.2': + resolution: {integrity: sha512-ZOVi6GYgTcsZcUzjblpzk3wH1Fya2VNpd5jtHoCCFcJlMQ1EYXZetfAnRHLcyiFeBABaI1ltTYbOBtH/gahGVA==} + engines: {node: '>=20.0'} + peerDependencies: + '@docusaurus/faster': '*' + peerDependenciesMeta: + '@docusaurus/faster': + optional: true - '@nomicfoundation/solidity-analyzer-linux-x64-gnu@0.1.2': - resolution: {integrity: sha512-9dlHMAt5/2cpWyuJ9fQNOUXFB/vgSFORg1jpjX1Mh9hJ/MfZXlDdHQ+DpFCs32Zk5pxRBb07yGvSHk9/fezL+g==} - engines: {node: '>= 12'} + '@docusaurus/core@3.9.2': + resolution: {integrity: sha512-HbjwKeC+pHUFBfLMNzuSjqFE/58+rLVKmOU3lxQrpsxLBOGosYco/Q0GduBb0/jEMRiyEqjNT/01rRdOMWq5pw==} + engines: {node: '>=20.0'} + hasBin: true + peerDependencies: + '@mdx-js/react': ^3.0.0 + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 - '@nomicfoundation/solidity-analyzer-linux-x64-musl@0.1.2': - resolution: {integrity: sha512-GzzVeeJob3lfrSlDKQw2bRJ8rBf6mEYaWY+gW0JnTDHINA0s2gPR4km5RLIj1xeZZOYz4zRw+AEeYgLRqB2NXg==} - engines: {node: '>= 12'} + '@docusaurus/cssnano-preset@3.9.2': + resolution: {integrity: sha512-8gBKup94aGttRduABsj7bpPFTX7kbwu+xh3K9NMCF5K4bWBqTFYW+REKHF6iBVDHRJ4grZdIPbvkiHd/XNKRMQ==} + engines: {node: '>=20.0'} - '@nomicfoundation/solidity-analyzer-win32-x64-msvc@0.1.2': - resolution: {integrity: sha512-Fdjli4DCcFHb4Zgsz0uEJXZ2K7VEO+w5KVv7HmT7WO10iODdU9csC2az4jrhEsRtiR9Gfd74FlG0NYlw1BMdyA==} - engines: {node: '>= 12'} + '@docusaurus/logger@3.9.2': + resolution: {integrity: sha512-/SVCc57ByARzGSU60c50rMyQlBuMIJCjcsJlkphxY6B0GV4UH3tcA1994N8fFfbJ9kX3jIBe/xg3XP5qBtGDbA==} + engines: {node: '>=20.0'} - '@nomicfoundation/solidity-analyzer@0.1.2': - resolution: {integrity: sha512-q4n32/FNKIhQ3zQGGw5CvPF6GTvDCpYwIf7bEY/dZTZbgfDsHyjJwURxUJf3VQuuJj+fDIFl4+KkBVbw4Ef6jA==} - engines: {node: '>= 12'} + '@docusaurus/mdx-loader@3.9.2': + resolution: {integrity: sha512-wiYoGwF9gdd6rev62xDU8AAM8JuLI/hlwOtCzMmYcspEkzecKrP8J8X+KpYnTlACBUUtXNJpSoCwFWJhLRevzQ==} + engines: {node: '>=20.0'} + peerDependencies: + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 - '@openzeppelin/community-contracts@https://codeload.github.com/OpenZeppelin/openzeppelin-community-contracts/tar.gz/7322fa7de0beabe0e0cf7e8663f879d406bb3f42': - resolution: {tarball: https://codeload.github.com/OpenZeppelin/openzeppelin-community-contracts/tar.gz/7322fa7de0beabe0e0cf7e8663f879d406bb3f42} - version: 0.0.1 + '@docusaurus/module-type-aliases@3.9.2': + resolution: {integrity: sha512-8qVe2QA9hVLzvnxP46ysuofJUIc/yYQ82tvA/rBTrnpXtCjNSFLxEZfd5U8cYZuJIVlkPxamsIgwd5tGZXfvew==} + peerDependencies: + react: '*' + react-dom: '*' - '@openzeppelin/contracts-upgradeable@5.4.0': - resolution: {integrity: sha512-STJKyDzUcYuB35Zub1JpWW58JxvrFFVgQ+Ykdr8A9PGXgtq/obF5uoh07k2XmFyPxfnZdPdBdhkJ/n2YxJ87HQ==} + '@docusaurus/plugin-content-blog@3.9.2': + resolution: {integrity: sha512-3I2HXy3L1QcjLJLGAoTvoBnpOwa6DPUa3Q0dMK19UTY9mhPkKQg/DYhAGTiBUKcTR0f08iw7kLPqOhIgdV3eVQ==} + engines: {node: '>=20.0'} peerDependencies: - '@openzeppelin/contracts': 5.4.0 + '@docusaurus/plugin-content-docs': '*' + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 - '@openzeppelin/contracts@3.4.2-solc-0.7': - resolution: {integrity: sha512-W6QmqgkADuFcTLzHL8vVoNBtkwjvQRpYIAom7KiUNoLKghyx3FgH0GBjt8NRvigV1ZmMOBllvE1By1C+bi8WpA==} + '@docusaurus/plugin-content-docs@3.9.2': + resolution: {integrity: sha512-C5wZsGuKTY8jEYsqdxhhFOe1ZDjH0uIYJ9T/jebHwkyxqnr4wW0jTkB72OMqNjsoQRcb0JN3PcSeTwFlVgzCZg==} + engines: {node: '>=20.0'} + peerDependencies: + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 - '@openzeppelin/contracts@5.4.0': - resolution: {integrity: sha512-eCYgWnLg6WO+X52I16TZt8uEjbtdkgLC0SUX/xnAksjjrQI4Xfn4iBRoI5j55dmlOhDv1Y7BoR3cU7e3WWhC6A==} + '@docusaurus/plugin-content-pages@3.9.2': + resolution: {integrity: sha512-s4849w/p4noXUrGpPUF0BPqIAfdAe76BLaRGAGKZ1gTDNiGxGcpsLcwJ9OTi1/V8A+AzvsmI9pkjie2zjIQZKA==} + engines: {node: '>=20.0'} + peerDependencies: + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 - '@openzeppelin/defender-sdk-base-client@2.7.0': - resolution: {integrity: sha512-J5IpvbFfdIJM4IadBcXfhCXVdX2yEpaZtRR1ecq87d8CdkmmEpniYfef/yVlG98yekvu125LaIRg0yXQOt9Bdg==} + '@docusaurus/plugin-css-cascade-layers@3.9.2': + resolution: {integrity: sha512-w1s3+Ss+eOQbscGM4cfIFBlVg/QKxyYgj26k5AnakuHkKxH6004ZtuLe5awMBotIYF2bbGDoDhpgQ4r/kcj4rQ==} + engines: {node: '>=20.0'} - '@openzeppelin/defender-sdk-deploy-client@2.7.0': - resolution: {integrity: sha512-YOHZmnHmM1y6uSqXWGfk2/5/ae4zZJE6xG92yFEAIOy8vqh1dxznWMsoCcAXRXTCWc8RdCDpFdMfEy4SBTyYtg==} + '@docusaurus/plugin-debug@3.9.2': + resolution: {integrity: sha512-j7a5hWuAFxyQAkilZwhsQ/b3T7FfHZ+0dub6j/GxKNFJp2h9qk/P1Bp7vrGASnvA9KNQBBL1ZXTe7jlh4VdPdA==} + engines: {node: '>=20.0'} + peerDependencies: + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 - '@openzeppelin/defender-sdk-network-client@2.7.0': - resolution: {integrity: sha512-4CYWPa9+kSjojE5KS7kRmP161qsBATdp97TCrzyDdGoVahj0GyqgafRL9AAjm0eHZOM1c7EIYEpbvYRtFi8vyA==} + '@docusaurus/plugin-google-analytics@3.9.2': + resolution: {integrity: sha512-mAwwQJ1Us9jL/lVjXtErXto4p4/iaLlweC54yDUK1a97WfkC6Z2k5/769JsFgwOwOP+n5mUQGACXOEQ0XDuVUw==} + engines: {node: '>=20.0'} + peerDependencies: + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 - '@openzeppelin/hardhat-upgrades@3.9.1': - resolution: {integrity: sha512-pSDjlOnIpP+PqaJVe144dK6VVKZw2v6YQusyt0OOLiCsl+WUzfo4D0kylax7zjrOxqy41EK2ipQeIF4T+cCn2A==} - hasBin: true + '@docusaurus/plugin-google-gtag@3.9.2': + resolution: {integrity: sha512-YJ4lDCphabBtw19ooSlc1MnxtYGpjFV9rEdzjLsUnBCeis2djUyCozZaFhCg6NGEwOn7HDDyMh0yzcdRpnuIvA==} + engines: {node: '>=20.0'} peerDependencies: - '@nomicfoundation/hardhat-ethers': ^3.0.6 - '@nomicfoundation/hardhat-verify': ^2.0.14 - ethers: ^6.6.0 - hardhat: ^2.24.1 - peerDependenciesMeta: - '@nomicfoundation/hardhat-verify': - optional: true + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 - '@openzeppelin/upgrades-core@1.44.2': - resolution: {integrity: sha512-m6iorjyhPK9ow5/trNs7qsBC/SOzJCO51pvvAF2W9nOiZ1t0RtCd+rlRmRmlWTv4M33V0wzIUeamJ2BPbzgUXA==} - hasBin: true + '@docusaurus/plugin-google-tag-manager@3.9.2': + resolution: {integrity: sha512-LJtIrkZN/tuHD8NqDAW1Tnw0ekOwRTfobWPsdO15YxcicBo2ykKF0/D6n0vVBfd3srwr9Z6rzrIWYrMzBGrvNw==} + engines: {node: '>=20.0'} + peerDependencies: + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 - '@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' + '@docusaurus/plugin-sitemap@3.9.2': + resolution: {integrity: sha512-WLh7ymgDXjG8oPoM/T4/zUP7KcSuFYRZAUTl8vR6VzYkfc18GBM4xLhcT+AKOwun6kBivYKUJf+vlqYJkm+RHw==} + engines: {node: '>=20.0'} + peerDependencies: + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 - '@peculiar/asn1-schema@2.6.0': - resolution: {integrity: sha512-xNLYLBFTBKkCzEZIw842BxytQQATQv+lDTCEMZ8C196iJcJJMBUZxrhSTxLaohMyKK8QlzRNTRkUmanucnDSqg==} + '@docusaurus/plugin-svgr@3.9.2': + resolution: {integrity: sha512-n+1DE+5b3Lnf27TgVU5jM1d4x5tUh2oW5LTsBxJX4PsAPV0JGcmI6p3yLYtEY0LRVEIJh+8RsdQmRE66wSV8mw==} + engines: {node: '>=20.0'} + peerDependencies: + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 - '@rainbow-me/rainbowkit@2.2.10': - resolution: {integrity: sha512-8+E4die1A2ovN9t3lWxWnwqTGEdFqThXDQRj+E4eDKuUKyymYD+66Gzm6S9yfg8E95c6hmGlavGUfYPtl1EagA==} - engines: {node: '>=12.4'} + '@docusaurus/preset-classic@3.9.2': + resolution: {integrity: sha512-IgyYO2Gvaigi21LuDIe+nvmN/dfGXAiMcV/murFqcpjnZc7jxFAxW+9LEjdPt61uZLxG4ByW/oUmX/DDK9t/8w==} + engines: {node: '>=20.0'} peerDependencies: - '@tanstack/react-query': '>=5.0.0' - react: '>=18' - react-dom: '>=18' - viem: 2.x - wagmi: ^2.9.0 + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 - '@reown/appkit-common@1.7.8': - resolution: {integrity: sha512-ridIhc/x6JOp7KbDdwGKY4zwf8/iK8EYBl+HtWrruutSLwZyVi5P8WaZa+8iajL6LcDcDF7LoyLwMTym7SRuwQ==} + '@docusaurus/react-loadable@6.0.0': + resolution: {integrity: sha512-YMMxTUQV/QFSnbgrP3tjDzLHRg7vsbMn8e9HAa8o/1iXoiomo48b7sk/kkmWEuWNDPJVlKSJRB6Y2fHqdJk+SQ==} + peerDependencies: + react: '*' - '@reown/appkit-controllers@1.7.8': - resolution: {integrity: sha512-IdXlJlivrlj6m63VsGLsjtPHHsTWvKGVzWIP1fXZHVqmK+rZCBDjCi9j267Rb9/nYRGHWBtlFQhO8dK35WfeDA==} + '@docusaurus/theme-classic@3.9.2': + resolution: {integrity: sha512-IGUsArG5hhekXd7RDb11v94ycpJpFdJPkLnt10fFQWOVxAtq5/D7hT6lzc2fhyQKaaCE62qVajOMKL7OiAFAIA==} + engines: {node: '>=20.0'} + peerDependencies: + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 - '@reown/appkit-pay@1.7.8': - resolution: {integrity: sha512-OSGQ+QJkXx0FEEjlpQqIhT8zGJKOoHzVnyy/0QFrl3WrQTjCzg0L6+i91Ad5Iy1zb6V5JjqtfIFpRVRWN4M3pw==} + '@docusaurus/theme-common@3.9.2': + resolution: {integrity: sha512-6c4DAbR6n6nPbnZhY2V3tzpnKnGL+6aOsLvFL26VRqhlczli9eWG0VDUNoCQEPnGwDMhPS42UhSAnz5pThm5Ag==} + engines: {node: '>=20.0'} + peerDependencies: + '@docusaurus/plugin-content-docs': '*' + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 - '@reown/appkit-polyfills@1.7.8': - resolution: {integrity: sha512-W/kq786dcHHAuJ3IV2prRLEgD/2iOey4ueMHf1sIFjhhCGMynMkhsOhQMUH0tzodPqUgAC494z4bpIDYjwWXaA==} + '@docusaurus/theme-search-algolia@3.9.2': + resolution: {integrity: sha512-GBDSFNwjnh5/LdkxCKQHkgO2pIMX1447BxYUBG2wBiajS21uj64a+gH/qlbQjDLxmGrbrllBrtJkUHxIsiwRnw==} + engines: {node: '>=20.0'} + peerDependencies: + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 - '@reown/appkit-scaffold-ui@1.7.8': - resolution: {integrity: sha512-RCeHhAwOrIgcvHwYlNWMcIDibdI91waaoEYBGw71inE0kDB8uZbE7tE6DAXJmDkvl0qPh+DqlC4QbJLF1FVYdQ==} + '@docusaurus/theme-translations@3.9.2': + resolution: {integrity: sha512-vIryvpP18ON9T9rjgMRFLr2xJVDpw1rtagEGf8Ccce4CkTrvM/fRB8N2nyWYOW5u3DdjkwKw5fBa+3tbn9P4PA==} + engines: {node: '>=20.0'} - '@reown/appkit-ui@1.7.8': - resolution: {integrity: sha512-1hjCKjf6FLMFzrulhl0Y9Vb9Fu4royE+SXCPSWh4VhZhWqlzUFc7kutnZKx8XZFVQH4pbBvY62SpRC93gqoHow==} + '@docusaurus/tsconfig@3.9.2': + resolution: {integrity: sha512-j6/Fp4Rlpxsc632cnRnl5HpOWeb6ZKssDj6/XzzAzVGXXfm9Eptx3rxCC+fDzySn9fHTS+CWJjPineCR1bB5WQ==} - '@reown/appkit-utils@1.7.8': - resolution: {integrity: sha512-8X7UvmE8GiaoitCwNoB86pttHgQtzy4ryHZM9kQpvjQ0ULpiER44t1qpVLXNM4X35O0v18W0Dk60DnYRMH2WRw==} + '@docusaurus/types@3.9.2': + resolution: {integrity: sha512-Ux1JUNswg+EfUEmajJjyhIohKceitY/yzjRUpu04WXgvVz+fbhVC0p+R0JhvEu4ytw8zIAys2hrdpQPBHRIa8Q==} peerDependencies: - valtio: 1.13.2 + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 - '@reown/appkit-wallet@1.7.8': - resolution: {integrity: sha512-kspz32EwHIOT/eg/ZQbFPxgXq0B/olDOj3YMu7gvLEFz4xyOFd/wgzxxAXkp5LbG4Cp++s/elh79rVNmVFdB9A==} + '@docusaurus/utils-common@3.9.2': + resolution: {integrity: sha512-I53UC1QctruA6SWLvbjbhCpAw7+X7PePoe5pYcwTOEXD/PxeP8LnECAhTHHwWCblyUX5bMi4QLRkxvyZ+IT8Aw==} + engines: {node: '>=20.0'} - '@reown/appkit@1.7.8': - resolution: {integrity: sha512-51kTleozhA618T1UvMghkhKfaPcc9JlKwLJ5uV+riHyvSoWPKPRIa5A6M1Wano5puNyW0s3fwywhyqTHSilkaA==} + '@docusaurus/utils-validation@3.9.2': + resolution: {integrity: sha512-l7yk3X5VnNmATbwijJkexdhulNsQaNDwoagiwujXoxFbWLcxHQqNQ+c/IAlzrfMMOfa/8xSBZ7KEKDesE/2J7A==} + engines: {node: '>=20.0'} - '@rolldown/pluginutils@1.0.0-beta.27': - resolution: {integrity: sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA==} + '@docusaurus/utils@3.9.2': + resolution: {integrity: sha512-lBSBiRruFurFKXr5Hbsl2thmGweAPmddhF3jb99U4EMDA5L+e5Y1rAkOS07Nvrup7HUMBDrCV45meaxZnt28nQ==} + engines: {node: '>=20.0'} - '@rollup/rollup-android-arm-eabi@4.53.5': - resolution: {integrity: sha512-iDGS/h7D8t7tvZ1t6+WPK04KD0MwzLZrG0se1hzBjSi5fyxlsiggoJHwh18PCFNn7tG43OWb6pdZ6Y+rMlmyNQ==} - cpu: [arm] - os: [android] + '@ecies/ciphers@0.2.5': + resolution: {integrity: sha512-GalEZH4JgOMHYYcYmVqnFirFsjZHeoGMDt9IxEnM9F7GRUUyUksJ7Ou53L83WHJq3RWKD3AcBpo0iQh0oMpf8A==} + engines: {bun: '>=1', deno: '>=2', node: '>=16'} + peerDependencies: + '@noble/ciphers': ^1.0.0 - '@rollup/rollup-android-arm64@4.53.5': - resolution: {integrity: sha512-wrSAViWvZHBMMlWk6EJhvg8/rjxzyEhEdgfMMjREHEq11EtJ6IP6yfcCH57YAEca2Oe3FNCE9DSTgU70EIGmVw==} + '@emotion/hash@0.9.2': + resolution: {integrity: sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g==} + + '@esbuild/aix-ppc64@0.21.5': + resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.21.5': + resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==} + engines: {node: '>=12'} cpu: [arm64] os: [android] - '@rollup/rollup-darwin-arm64@4.53.5': - resolution: {integrity: sha512-S87zZPBmRO6u1YXQLwpveZm4JfPpAa6oHBX7/ghSiGH3rz/KDgAu1rKdGutV+WUI6tKDMbaBJomhnT30Y2t4VQ==} + '@esbuild/android-arm@0.21.5': + resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.21.5': + resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.21.5': + resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==} + engines: {node: '>=12'} cpu: [arm64] os: [darwin] - '@rollup/rollup-darwin-x64@4.53.5': - resolution: {integrity: sha512-YTbnsAaHo6VrAczISxgpTva8EkfQus0VPEVJCEaboHtZRIb6h6j0BNxRBOwnDciFTZLDPW5r+ZBmhL/+YpTZgA==} + '@esbuild/darwin-x64@0.21.5': + resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==} + engines: {node: '>=12'} cpu: [x64] os: [darwin] - '@rollup/rollup-freebsd-arm64@4.53.5': - resolution: {integrity: sha512-1T8eY2J8rKJWzaznV7zedfdhD1BqVs1iqILhmHDq/bqCUZsrMt+j8VCTHhP0vdfbHK3e1IQ7VYx3jlKqwlf+vw==} + '@esbuild/freebsd-arm64@0.21.5': + resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==} + engines: {node: '>=12'} cpu: [arm64] os: [freebsd] - '@rollup/rollup-freebsd-x64@4.53.5': - resolution: {integrity: sha512-sHTiuXyBJApxRn+VFMaw1U+Qsz4kcNlxQ742snICYPrY+DDL8/ZbaC4DVIB7vgZmp3jiDaKA0WpBdP0aqPJoBQ==} + '@esbuild/freebsd-x64@0.21.5': + resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==} + engines: {node: '>=12'} cpu: [x64] os: [freebsd] - '@rollup/rollup-linux-arm-gnueabihf@4.53.5': - resolution: {integrity: sha512-dV3T9MyAf0w8zPVLVBptVlzaXxka6xg1f16VAQmjg+4KMSTWDvhimI/Y6mp8oHwNrmnmVl9XxJ/w/mO4uIQONA==} - cpu: [arm] + '@esbuild/linux-arm64@0.21.5': + resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==} + engines: {node: '>=12'} + cpu: [arm64] os: [linux] - '@rollup/rollup-linux-arm-musleabihf@4.53.5': - resolution: {integrity: sha512-wIGYC1x/hyjP+KAu9+ewDI+fi5XSNiUi9Bvg6KGAh2TsNMA3tSEs+Sh6jJ/r4BV/bx/CyWu2ue9kDnIdRyafcQ==} + '@esbuild/linux-arm@0.21.5': + resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==} + engines: {node: '>=12'} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm64-gnu@4.53.5': - resolution: {integrity: sha512-Y+qVA0D9d0y2FRNiG9oM3Hut/DgODZbU9I8pLLPwAsU0tUKZ49cyV1tzmB/qRbSzGvY8lpgGkJuMyuhH7Ma+Vg==} - cpu: [arm64] - os: [linux] - - '@rollup/rollup-linux-arm64-musl@4.53.5': - resolution: {integrity: sha512-juaC4bEgJsyFVfqhtGLz8mbopaWD+WeSOYr5E16y+1of6KQjc0BpwZLuxkClqY1i8sco+MdyoXPNiCkQou09+g==} - cpu: [arm64] + '@esbuild/linux-ia32@0.21.5': + resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==} + engines: {node: '>=12'} + cpu: [ia32] os: [linux] - '@rollup/rollup-linux-loong64-gnu@4.53.5': - resolution: {integrity: sha512-rIEC0hZ17A42iXtHX+EPJVL/CakHo+tT7W0pbzdAGuWOt2jxDFh7A/lRhsNHBcqL4T36+UiAgwO8pbmn3dE8wA==} + '@esbuild/linux-loong64@0.21.5': + resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==} + engines: {node: '>=12'} cpu: [loong64] os: [linux] - '@rollup/rollup-linux-ppc64-gnu@4.53.5': - resolution: {integrity: sha512-T7l409NhUE552RcAOcmJHj3xyZ2h7vMWzcwQI0hvn5tqHh3oSoclf9WgTl+0QqffWFG8MEVZZP1/OBglKZx52Q==} - cpu: [ppc64] + '@esbuild/linux-mips64el@0.21.5': + resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==} + engines: {node: '>=12'} + cpu: [mips64el] os: [linux] - '@rollup/rollup-linux-riscv64-gnu@4.53.5': - resolution: {integrity: sha512-7OK5/GhxbnrMcxIFoYfhV/TkknarkYC1hqUw1wU2xUN3TVRLNT5FmBv4KkheSG2xZ6IEbRAhTooTV2+R5Tk0lQ==} - cpu: [riscv64] + '@esbuild/linux-ppc64@0.21.5': + resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==} + engines: {node: '>=12'} + cpu: [ppc64] os: [linux] - '@rollup/rollup-linux-riscv64-musl@4.53.5': - resolution: {integrity: sha512-GwuDBE/PsXaTa76lO5eLJTyr2k8QkPipAyOrs4V/KJufHCZBJ495VCGJol35grx9xryk4V+2zd3Ri+3v7NPh+w==} + '@esbuild/linux-riscv64@0.21.5': + resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==} + engines: {node: '>=12'} cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-s390x-gnu@4.53.5': - resolution: {integrity: sha512-IAE1Ziyr1qNfnmiQLHBURAD+eh/zH1pIeJjeShleII7Vj8kyEm2PF77o+lf3WTHDpNJcu4IXJxNO0Zluro8bOw==} + '@esbuild/linux-s390x@0.21.5': + resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==} + engines: {node: '>=12'} cpu: [s390x] os: [linux] - '@rollup/rollup-linux-x64-gnu@4.53.5': - resolution: {integrity: sha512-Pg6E+oP7GvZ4XwgRJBuSXZjcqpIW3yCBhK4BcsANvb47qMvAbCjR6E+1a/U2WXz1JJxp9/4Dno3/iSJLcm5auw==} + '@esbuild/linux-x64@0.21.5': + resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==} + engines: {node: '>=12'} cpu: [x64] os: [linux] - '@rollup/rollup-linux-x64-musl@4.53.5': - resolution: {integrity: sha512-txGtluxDKTxaMDzUduGP0wdfng24y1rygUMnmlUJ88fzCCULCLn7oE5kb2+tRB+MWq1QDZT6ObT5RrR8HFRKqg==} + '@esbuild/netbsd-x64@0.21.5': + resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==} + engines: {node: '>=12'} cpu: [x64] - os: [linux] + os: [netbsd] - '@rollup/rollup-openharmony-arm64@4.53.5': - resolution: {integrity: sha512-3DFiLPnTxiOQV993fMc+KO8zXHTcIjgaInrqlG8zDp1TlhYl6WgrOHuJkJQ6M8zHEcntSJsUp1XFZSY8C1DYbg==} - cpu: [arm64] - os: [openharmony] + '@esbuild/openbsd-x64@0.21.5': + resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] - '@rollup/rollup-win32-arm64-msvc@4.53.5': - resolution: {integrity: sha512-nggc/wPpNTgjGg75hu+Q/3i32R00Lq1B6N1DO7MCU340MRKL3WZJMjA9U4K4gzy3dkZPXm9E1Nc81FItBVGRlA==} + '@esbuild/sunos-x64@0.21.5': + resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.21.5': + resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==} + engines: {node: '>=12'} cpu: [arm64] os: [win32] - '@rollup/rollup-win32-ia32-msvc@4.53.5': - resolution: {integrity: sha512-U/54pTbdQpPLBdEzCT6NBCFAfSZMvmjr0twhnD9f4EIvlm9wy3jjQ38yQj1AGznrNO65EWQMgm/QUjuIVrYF9w==} + '@esbuild/win32-ia32@0.21.5': + resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==} + engines: {node: '>=12'} cpu: [ia32] os: [win32] - '@rollup/rollup-win32-x64-gnu@4.53.5': - resolution: {integrity: sha512-2NqKgZSuLH9SXBBV2dWNRCZmocgSOx8OJSdpRaEcRlIfX8YrKxUT6z0F1NpvDVhOsl190UFTRh2F2WDWWCYp3A==} - cpu: [x64] - os: [win32] - - '@rollup/rollup-win32-x64-msvc@4.53.5': - resolution: {integrity: sha512-JRpZUhCfhZ4keB5v0fe02gQJy05GqboPOaxvjugW04RLSYYoB/9t2lx2u/tMs/Na/1NXfY8QYjgRljRpN+MjTQ==} + '@esbuild/win32-x64@0.21.5': + resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==} + engines: {node: '>=12'} cpu: [x64] os: [win32] - '@safe-global/api-kit@4.0.1': - resolution: {integrity: sha512-pNtDLgMHlCSr4Hwwe6jsnvMheAu2SZCTqjYlnNe4cKH2pSKINVRTiILoeJ0wOpixrMCH4NlgJ+9N3QruRNcCpQ==} + '@ethereumjs/common@3.2.0': + resolution: {integrity: sha512-pksvzI0VyLgmuEF2FA/JR/4/y6hcPq8OUail3/AvycBaW1d5VSauOZzqGvJ3RTmR4MU35lWE8KseKOsEhrFRBA==} - '@safe-global/protocol-kit@6.1.2': - resolution: {integrity: sha512-cTpPdUAS2AMfGCkD1T601rQNjT0rtMQLA2TH7L/C+iFPAC6WrrDFop2B9lzeHjczlnVzrRpfFe4cL1bLrJ9NZw==} + '@ethereumjs/rlp@4.0.1': + resolution: {integrity: sha512-tqsQiBQDQdmPWE1xkkBq4rlSW5QZpLOUJ5RJh2/9fug+q9tnUhuZoVLk7s0scUIKTOzEtR72DFBXI4WiZcMpvw==} + engines: {node: '>=14'} + hasBin: true - '@safe-global/safe-apps-provider@0.18.6': - resolution: {integrity: sha512-4LhMmjPWlIO8TTDC2AwLk44XKXaK6hfBTWyljDm0HQ6TWlOEijVWNrt2s3OCVMSxlXAcEzYfqyu1daHZooTC2Q==} + '@ethereumjs/rlp@5.0.2': + resolution: {integrity: sha512-DziebCdg4JpGlEqEdGgXmjqcFoJi+JGulUXwEjsZGAscAQ7MyD/7LE/GVCP29vEQxKc7AAwjT3A2ywHp2xfoCA==} + engines: {node: '>=18'} + hasBin: true - '@safe-global/safe-apps-sdk@9.1.0': - resolution: {integrity: sha512-N5p/ulfnnA2Pi2M3YeWjULeWbjo7ei22JwU/IXnhoHzKq3pYCN6ynL9mJBOlvDVv892EgLPCWCOwQk/uBT2v0Q==} + '@ethereumjs/tx@4.2.0': + resolution: {integrity: sha512-1nc6VO4jtFd172BbSnTnDQVr9IYBFl1y4xPzZdtkrkKIncBCkdbgfdRV+MiTkJYAtTxvV12GRZLqBFT1PNK6Yw==} + engines: {node: '>=14'} - '@safe-global/safe-deployments@1.37.49': - resolution: {integrity: sha512-132QgqMY1/HktXqmda/uPp5b+73UXTgKRB00Xgc1kduFqceSw/ZyF1Q9jJjbND9q91hhapnXhYKWN2/HiWkRcg==} + '@ethereumjs/util@8.1.0': + resolution: {integrity: sha512-zQ0IqbdX8FZ9aw11vP+dZkKDkS+kgIvQPHnSAXzP9pLu+Rfu3D3XEeLbicvoXJTYnhZiPmsZUxgdzXwNKxRPbA==} + engines: {node: '>=14'} - '@safe-global/safe-gateway-typescript-sdk@3.23.1': - resolution: {integrity: sha512-6ORQfwtEJYpalCeVO21L4XXGSdbEMfyp2hEv6cP82afKXSwvse6d3sdelgaPWUxHIsFRkWvHDdzh8IyyKHZKxw==} - engines: {node: '>=16'} + '@ethereumjs/util@9.1.0': + resolution: {integrity: sha512-XBEKsYqLGXLah9PNJbgdkigthkG7TAGvlD/sH12beMXEyHDyigfcbdvHhmLyDWgDyOJn4QwiQUaF7yeuhnjdog==} + engines: {node: '>=18'} - '@safe-global/safe-modules-deployments@2.2.21': - resolution: {integrity: sha512-fveOlRv0ccwsuaZjP1u7ZbXrwCyqMTYYiqETOGo8NdzTaceRUyR9TNzagSWovOSuHPVyUGJ9lnsxizikt/+PiQ==} + '@ethersproject/abi@5.8.0': + resolution: {integrity: sha512-b9YS/43ObplgyV6SlyQsG53/vkSal0MNA1fskSC4mbnCMi8R+NkcH8K9FPYNESf6jUefBUniE4SOKms0E/KK1Q==} - '@safe-global/types-kit@3.0.0': - resolution: {integrity: sha512-AZWIlR5MguDPdGiOj7BB4JQPY2afqmWQww1mu8m8Oi16HHBW99G01kFOu4NEHBwEU1cgwWOMY19hsI5KyL4W2w==} + '@ethersproject/abstract-provider@5.8.0': + resolution: {integrity: sha512-wC9SFcmh4UK0oKuLJQItoQdzS/qZ51EJegK6EmAWlh+OptpQ/npECOR3QqECd8iGHC0RJb4WKbVdSfif4ammrg==} - '@scure/base@1.1.9': - resolution: {integrity: sha512-8YKhl8GHiNI/pU2VMaofa2Tor7PJRAjwQLBBuilkJ9L5+13yVbC7JO/wS7piioAvPSwR3JKM1IJ/u4xQzbcXKg==} + '@ethersproject/abstract-signer@5.8.0': + resolution: {integrity: sha512-N0XhZTswXcmIZQdYtUnd79VJzvEwXQw6PK0dTl9VoYrEBxxCPXqS0Eod7q5TNKRxe1/5WUMuR0u0nqTF/avdCA==} - '@scure/base@1.2.6': - resolution: {integrity: sha512-g/nm5FgUa//MCj1gV09zTJTaM6KBAHqLN907YVQqf7zC49+DcO4B1so4ZX07Ef10Twr6nuqYEH9GEggFXA4Fmg==} + '@ethersproject/address@5.6.1': + resolution: {integrity: sha512-uOgF0kS5MJv9ZvCz7x6T2EXJSzotiybApn4XlOgoTX0xdtyVIJ7pF+6cGPxiEq/dpBiTfMiw7Yc81JcwhSYA0Q==} - '@scure/bip32@1.1.5': - resolution: {integrity: sha512-XyNh1rB0SkEqd3tXcXMi+Xe1fvg+kUIcoRIEujP1Jgv7DqW2r9lg3Ah0NkFaCs9sTkQAQA8kw7xiRXzENi9Rtw==} + '@ethersproject/address@5.8.0': + resolution: {integrity: sha512-GhH/abcC46LJwshoN+uBNoKVFPxUuZm6dA257z0vZkKmU1+t8xTn8oK7B9qrj8W2rFRMch4gbJl6PmVxjxBEBA==} - '@scure/bip32@1.4.0': - resolution: {integrity: sha512-sVUpc0Vq3tXCkDGYVWGIZTRfnvu8LoTDaev7vbwh0omSvVORONr960MQWdKqJDCReIEmTj3PAr73O3aoxz7OPg==} + '@ethersproject/base64@5.8.0': + resolution: {integrity: sha512-lN0oIwfkYj9LbPx4xEkie6rAMJtySbpOAFXSDVQaBnAzYfB4X2Qr+FXJGxMoc3Bxp2Sm8OwvzMrywxyw0gLjIQ==} - '@scure/bip32@1.6.2': - resolution: {integrity: sha512-t96EPDMbtGgtb7onKKqxRLfE5g05k7uHnHRM2xdE6BP/ZmxaLtPek4J4KfVn/90IQNrU1IOAqMgiDtUdtbe3nw==} + '@ethersproject/basex@5.8.0': + resolution: {integrity: sha512-PIgTszMlDRmNwW9nhS6iqtVfdTAKosA7llYXNmGPw4YAI1PUyMv28988wAb41/gHF/WqGdoLv0erHaRcHRKW2Q==} - '@scure/bip32@1.7.0': - resolution: {integrity: sha512-E4FFX/N3f4B80AKWp5dP6ow+flD1LQZo/w8UnLGYZO674jS6YnYeepycOOksv+vLPSpgN35wgKgy+ybfTb2SMw==} + '@ethersproject/bignumber@5.8.0': + resolution: {integrity: sha512-ZyaT24bHaSeJon2tGPKIiHszWjD/54Sz8t57Toch475lCLljC6MgPmxk7Gtzz+ddNN5LuHea9qhAe0x3D+uYPA==} - '@scure/bip39@1.1.1': - resolution: {integrity: sha512-t+wDck2rVkh65Hmv280fYdVdY25J9YeEUIgn2LG1WM6gxFkGzcksoDiUkWVpVp3Oex9xGC68JU2dSbUfwZ2jPg==} + '@ethersproject/bytes@5.8.0': + resolution: {integrity: sha512-vTkeohgJVCPVHu5c25XWaWQOZ4v+DkGoC42/TS2ond+PARCxTJvgTFUNDZovyQ/uAQ4EcpqqowKydcdmRKjg7A==} - '@scure/bip39@1.3.0': - resolution: {integrity: sha512-disdg7gHuTDZtY+ZdkmLpPCk7fxZSu3gBiEGuoC1XYxv9cGx3Z6cpTggCgW6odSOOIXCiDjuGejW+aJKCY/pIQ==} + '@ethersproject/constants@5.8.0': + resolution: {integrity: sha512-wigX4lrf5Vu+axVTIvNsuL6YrV4O5AXl5ubcURKMEME5TnWBouUh0CDTWxZ2GpnRn1kcCgE7l8O5+VbV9QTTcg==} - '@scure/bip39@1.5.4': - resolution: {integrity: sha512-TFM4ni0vKvCfBpohoh+/lY05i9gRbSwXWngAsF4CABQxoaOHijxuaZ2R6cStDQ5CHtHO9aGJTr4ksVJASRRyMA==} + '@ethersproject/contracts@5.8.0': + resolution: {integrity: sha512-0eFjGz9GtuAi6MZwhb4uvUM216F38xiuR0yYCjKJpNfSEy4HUM8hvqqBj9Jmm0IUz8l0xKEhWwLIhPgxNY0yvQ==} - '@scure/bip39@1.6.0': - resolution: {integrity: sha512-+lF0BbLiJNwVlev4eKelw1WWLaiKXw7sSl8T6FvBlWkdX+94aGJ4o8XjUdlyhTCjd8c+B3KT3JfS8P0bLRNU6A==} + '@ethersproject/hash@5.8.0': + resolution: {integrity: sha512-ac/lBcTbEWW/VGJij0CNSw/wPcw9bSRgCB0AIBz8CvED/jfvDoV9hsIIiWfvWmFEi8RcXtlNwp2jv6ozWOsooA==} - '@sentry/core@5.30.0': - resolution: {integrity: sha512-TmfrII8w1PQZSZgPpUESqjB+jC6MvZJZdLtE/0hZ+SrnKhW3x5WlYLvTXZpcWePYBku7rl2wn1RZu6uT0qCTeg==} - engines: {node: '>=6'} + '@ethersproject/hdnode@5.8.0': + resolution: {integrity: sha512-4bK1VF6E83/3/Im0ERnnUeWOY3P1BZml4ZD3wcH8Ys0/d1h1xaFt6Zc+Dh9zXf9TapGro0T4wvO71UTCp3/uoA==} - '@sentry/hub@5.30.0': - resolution: {integrity: sha512-2tYrGnzb1gKz2EkMDQcfLrDTvmGcQPuWxLnJKXJvYTQDGLlEvi2tWz1VIHjunmOvJrB5aIQLhm+dcMRwFZDCqQ==} - engines: {node: '>=6'} + '@ethersproject/json-wallets@5.8.0': + resolution: {integrity: sha512-HxblNck8FVUtNxS3VTEYJAcwiKYsBIF77W15HufqlBF9gGfhmYOJtYZp8fSDZtn9y5EaXTE87zDwzxRoTFk11w==} - '@sentry/minimal@5.30.0': - resolution: {integrity: sha512-BwWb/owZKtkDX+Sc4zCSTNcvZUq7YcH3uAVlmh/gtR9rmUvbzAA3ewLuB3myi4wWRAMEtny6+J/FN/x+2wn9Xw==} - engines: {node: '>=6'} + '@ethersproject/keccak256@5.8.0': + resolution: {integrity: sha512-A1pkKLZSz8pDaQ1ftutZoaN46I6+jvuqugx5KYNeQOPqq+JZ0Txm7dlWesCHB5cndJSu5vP2VKptKf7cksERng==} - '@sentry/node@5.30.0': - resolution: {integrity: sha512-Br5oyVBF0fZo6ZS9bxbJZG4ApAjRqAnqFFurMVJJdunNb80brh7a5Qva2kjhm+U6r9NJAB5OmDyPkA1Qnt+QVg==} - engines: {node: '>=6'} + '@ethersproject/logger@5.8.0': + resolution: {integrity: sha512-Qe6knGmY+zPPWTC+wQrpitodgBfH7XoceCGL5bJVejmH+yCS3R8jJm8iiWuvWbG76RUmyEG53oqv6GMVWqunjA==} - '@sentry/tracing@5.30.0': - resolution: {integrity: sha512-dUFowCr0AIMwiLD7Fs314Mdzcug+gBVo/+NCMyDw8tFxJkwWAKl7Qa2OZxLQ0ZHjakcj1hNKfCQJ9rhyfOl4Aw==} - engines: {node: '>=6'} + '@ethersproject/networks@5.8.0': + resolution: {integrity: sha512-egPJh3aPVAzbHwq8DD7Po53J4OUSsA1MjQp8Vf/OZPav5rlmWUaFLiq8cvQiGK0Z5K6LYzm29+VA/p4RL1FzNg==} - '@sentry/types@5.30.0': - resolution: {integrity: sha512-R8xOqlSTZ+htqrfteCWU5Nk0CDN5ApUTvrlvBuiH1DyP6czDZ4ktbZB0hAgBlVcK0U+qpD3ag3Tqqpa5Q67rPw==} - engines: {node: '>=6'} + '@ethersproject/pbkdf2@5.8.0': + resolution: {integrity: sha512-wuHiv97BrzCmfEaPbUFpMjlVg/IDkZThp9Ri88BpjRleg4iePJaj2SW8AIyE8cXn5V1tuAaMj6lzvsGJkGWskg==} - '@sentry/utils@5.30.0': - resolution: {integrity: sha512-zaYmoH0NWWtvnJjC9/CBseXMtKHm/tm40sz3YfJRxeQjyzRqNQPgivpd9R/oDJCYj999mzdW382p/qi2ypjLww==} - engines: {node: '>=6'} + '@ethersproject/properties@5.8.0': + resolution: {integrity: sha512-PYuiEoQ+FMaZZNGrStmN7+lWjlsoufGIHdww7454FIaGdbe/p5rnaCXTr5MtBYl3NkeoVhHZuyzChPeGeKIpQw==} - '@smithy/abort-controller@4.2.6': - resolution: {integrity: sha512-P7JD4J+wxHMpGxqIg6SHno2tPkZbBUBLbPpR5/T1DEUvw/mEaINBMaPFZNM7lA+ToSCZ36j6nMHa+5kej+fhGg==} - engines: {node: '>=18.0.0'} + '@ethersproject/providers@5.8.0': + resolution: {integrity: sha512-3Il3oTzEx3o6kzcg9ZzbE+oCZYyY+3Zh83sKkn4s1DZfTUjIegHnN2Cm0kbn9YFy45FDVcuCLLONhU7ny0SsCw==} - '@smithy/config-resolver@4.4.4': - resolution: {integrity: sha512-s3U5ChS21DwU54kMmZ0UJumoS5cg0+rGVZvN6f5Lp6EbAVi0ZyP+qDSHdewfmXKUgNK1j3z45JyzulkDukrjAA==} - engines: {node: '>=18.0.0'} + '@ethersproject/random@5.8.0': + resolution: {integrity: sha512-E4I5TDl7SVqyg4/kkA/qTfuLWAQGXmSOgYyO01So8hLfwgKvYK5snIlzxJMk72IFdG/7oh8yuSqY2KX7MMwg+A==} - '@smithy/core@3.19.0': - resolution: {integrity: sha512-Y9oHXpBcXQgYHOcAEmxjkDilUbSTkgKjoHYed3WaYUH8jngq8lPWDBSpjHblJ9uOgBdy5mh3pzebrScDdYr29w==} - engines: {node: '>=18.0.0'} + '@ethersproject/rlp@5.8.0': + resolution: {integrity: sha512-LqZgAznqDbiEunaUvykH2JAoXTT9NV0Atqk8rQN9nx9SEgThA/WMx5DnW8a9FOufo//6FZOCHZ+XiClzgbqV9Q==} - '@smithy/credential-provider-imds@4.2.6': - resolution: {integrity: sha512-xBmawExyTzOjbhzkZwg+vVm/khg28kG+rj2sbGlULjFd1jI70sv/cbpaR0Ev4Yfd6CpDUDRMe64cTqR//wAOyA==} - engines: {node: '>=18.0.0'} + '@ethersproject/sha2@5.8.0': + resolution: {integrity: sha512-dDOUrXr9wF/YFltgTBYS0tKslPEKr6AekjqDW2dbn1L1xmjGR+9GiKu4ajxovnrDbwxAKdHjW8jNcwfz8PAz4A==} - '@smithy/eventstream-codec@4.2.6': - resolution: {integrity: sha512-OZfsI+YRG26XZik/jKMMg37acnBSbUiK/8nETW3uM3mLj+0tMmFXdHQw1e5WEd/IHN8BGOh3te91SNDe2o4RHg==} - engines: {node: '>=18.0.0'} + '@ethersproject/signing-key@5.8.0': + resolution: {integrity: sha512-LrPW2ZxoigFi6U6aVkFN/fa9Yx/+4AtIUe4/HACTvKJdhm0eeb107EVCIQcrLZkxaSIgc/eCrX8Q1GtbH+9n3w==} - '@smithy/eventstream-serde-browser@4.2.6': - resolution: {integrity: sha512-6OiaAaEbLB6dEkRbQyNzFSJv5HDvly3Mc6q/qcPd2uS/g3szR8wAIkh7UndAFKfMypNSTuZ6eCBmgCLR5LacTg==} - engines: {node: '>=18.0.0'} + '@ethersproject/solidity@5.8.0': + resolution: {integrity: sha512-4CxFeCgmIWamOHwYN9d+QWGxye9qQLilpgTU0XhYs1OahkclF+ewO+3V1U0mvpiuQxm5EHHmv8f7ClVII8EHsA==} - '@smithy/eventstream-serde-config-resolver@4.3.6': - resolution: {integrity: sha512-xP5YXbOVRVN8A4pDnSUkEUsL9fYFU6VNhxo8tgr13YnMbf3Pn4xVr+hSyLVjS1Frfi1Uk03ET5Bwml4+0CeYEw==} - engines: {node: '>=18.0.0'} + '@ethersproject/strings@5.8.0': + resolution: {integrity: sha512-qWEAk0MAvl0LszjdfnZ2uC8xbR2wdv4cDabyHiBh3Cldq/T8dPH3V4BbBsAYJUeonwD+8afVXld274Ls+Y1xXg==} - '@smithy/eventstream-serde-node@4.2.6': - resolution: {integrity: sha512-jhH7nJuaOpnTFcuZpWK9dqb6Ge2yGi1okTo0W6wkJrfwAm2vwmO74tF1v07JmrSyHBcKLQATEexclJw9K1Vj7w==} - engines: {node: '>=18.0.0'} + '@ethersproject/transactions@5.8.0': + resolution: {integrity: sha512-UglxSDjByHG0TuU17bDfCemZ3AnKO2vYrL5/2n2oXvKzvb7Cz+W9gOWXKARjp2URVwcWlQlPOEQyAviKwT4AHg==} - '@smithy/eventstream-serde-universal@4.2.6': - resolution: {integrity: sha512-olIfZ230B64TvPD6b0tPvrEp2eB0FkyL3KvDlqF4RVmIc/kn3orzXnV6DTQdOOW5UU+M5zKY3/BU47X420/oPw==} - engines: {node: '>=18.0.0'} + '@ethersproject/units@5.8.0': + resolution: {integrity: sha512-lxq0CAnc5kMGIiWW4Mr041VT8IhNM+Pn5T3haO74XZWFulk7wH1Gv64HqE96hT4a7iiNMdOCFEBgaxWuk8ETKQ==} - '@smithy/fetch-http-handler@5.3.7': - resolution: {integrity: sha512-fcVap4QwqmzQwQK9QU3keeEpCzTjnP9NJ171vI7GnD7nbkAIcP9biZhDUx88uRH9BabSsQDS0unUps88uZvFIQ==} - engines: {node: '>=18.0.0'} + '@ethersproject/wallet@5.8.0': + resolution: {integrity: sha512-G+jnzmgg6UxurVKRKvw27h0kvG75YKXZKdlLYmAHeF32TGUzHkOFd7Zn6QHOTYRFWnfjtSSFjBowKo7vfrXzPA==} - '@smithy/hash-node@4.2.6': - resolution: {integrity: sha512-k3Dy9VNR37wfMh2/1RHkFf/e0rMyN0pjY0FdyY6ItJRjENYyVPRMwad6ZR1S9HFm6tTuIOd9pqKBmtJ4VHxvxg==} - engines: {node: '>=18.0.0'} + '@ethersproject/web@5.8.0': + resolution: {integrity: sha512-j7+Ksi/9KfGviws6Qtf9Q7KCqRhpwrYKQPs+JBA/rKVFF/yaWLHJEH3zfVP2plVu+eys0d2DlFmhoQJayFewcw==} - '@smithy/invalid-dependency@4.2.6': - resolution: {integrity: sha512-E4t/V/q2T46RY21fpfznd1iSLTvCXKNKo4zJ1QuEFN4SE9gKfu2vb6bgq35LpufkQ+SETWIC7ZAf2GGvTlBaMQ==} - engines: {node: '>=18.0.0'} + '@ethersproject/wordlists@5.8.0': + resolution: {integrity: sha512-2df9bbXicZws2Sb5S6ET493uJ0Z84Fjr3pC4tu/qlnZERibZCeUVuqdtt+7Tv9xxhUxHoIekIA7avrKUWHrezg==} - '@smithy/is-array-buffer@2.2.0': - resolution: {integrity: sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==} - engines: {node: '>=14.0.0'} + '@fastify/busboy@2.1.1': + resolution: {integrity: sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==} + engines: {node: '>=14'} - '@smithy/is-array-buffer@4.2.0': - resolution: {integrity: sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ==} - engines: {node: '>=18.0.0'} + '@gemini-wallet/core@0.3.2': + resolution: {integrity: sha512-Z4aHi3ECFf5oWYWM3F1rW83GJfB9OvhBYPTmb5q+VyK3uvzvS48lwo+jwh2eOoCRWEuT/crpb9Vwp2QaS5JqgQ==} + peerDependencies: + viem: '>=2.0.0' - '@smithy/middleware-content-length@4.2.6': - resolution: {integrity: sha512-0cjqjyfj+Gls30ntq45SsBtqF3dfJQCeqQPyGz58Pk8OgrAr5YiB7ZvDzjCA94p4r6DCI4qLm7FKobqBjf515w==} - engines: {node: '>=18.0.0'} + '@hapi/hoek@9.3.0': + resolution: {integrity: sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==} - '@smithy/middleware-endpoint@4.4.0': - resolution: {integrity: sha512-M6qWfUNny6NFNy8amrCGIb9TfOMUkHVtg9bHtEFGRgfH7A7AtPpn/fcrToGPjVDK1ECuMVvqGQOXcZxmu9K+7A==} - engines: {node: '>=18.0.0'} + '@hapi/topo@5.1.0': + resolution: {integrity: sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==} - '@smithy/middleware-retry@4.4.16': - resolution: {integrity: sha512-XPpNhNRzm3vhYm7YCsyw3AtmWggJbg1wNGAoqb7NBYr5XA5isMRv14jgbYyUV6IvbTBFZQdf2QpeW43LrRdStQ==} - engines: {node: '>=18.0.0'} + '@isaacs/balanced-match@4.0.1': + resolution: {integrity: sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==} + engines: {node: 20 || >=22} - '@smithy/middleware-serde@4.2.7': - resolution: {integrity: sha512-PFMVHVPgtFECeu4iZ+4SX6VOQT0+dIpm4jSPLLL6JLSkp9RohGqKBKD0cbiXdeIFS08Forp0UHI6kc0gIHenSA==} - engines: {node: '>=18.0.0'} + '@isaacs/brace-expansion@5.0.0': + resolution: {integrity: sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==} + engines: {node: 20 || >=22} - '@smithy/middleware-stack@4.2.6': - resolution: {integrity: sha512-JSbALU3G+JS4kyBZPqnJ3hxIYwOVRV7r9GNQMS6j5VsQDo5+Es5nddLfr9TQlxZLNHPvKSh+XSB0OuWGfSWFcA==} - engines: {node: '>=18.0.0'} + '@jest/schemas@29.6.3': + resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - '@smithy/node-config-provider@4.3.6': - resolution: {integrity: sha512-fYEyL59Qe82Ha1p97YQTMEQPJYmBS+ux76foqluaTVWoG9Px5J53w6NvXZNE3wP7lIicLDF7Vj1Em18XTX7fsA==} - engines: {node: '>=18.0.0'} + '@jest/types@29.6.3': + resolution: {integrity: sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - '@smithy/node-http-handler@4.4.6': - resolution: {integrity: sha512-Gsb9jf4ido5BhPfani4ggyrKDd3ZK+vTFWmUaZeFg5G3E5nhFmqiTzAIbHqmPs1sARuJawDiGMGR/nY+Gw6+aQ==} - engines: {node: '>=18.0.0'} + '@jridgewell/gen-mapping@0.3.13': + resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} - '@smithy/property-provider@4.2.6': - resolution: {integrity: sha512-a/tGSLPtaia2krbRdwR4xbZKO8lU67DjMk/jfY4QKt4PRlKML+2tL/gmAuhNdFDioO6wOq0sXkfnddNFH9mNUA==} - engines: {node: '>=18.0.0'} + '@jridgewell/remapping@2.3.5': + resolution: {integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==} - '@smithy/protocol-http@5.3.6': - resolution: {integrity: sha512-qLRZzP2+PqhE3OSwvY2jpBbP0WKTZ9opTsn+6IWYI0SKVpbG+imcfNxXPq9fj5XeaUTr7odpsNpK6dmoiM1gJQ==} - engines: {node: '>=18.0.0'} + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} - '@smithy/querystring-builder@4.2.6': - resolution: {integrity: sha512-MeM9fTAiD3HvoInK/aA8mgJaKQDvm8N0dKy6EiFaCfgpovQr4CaOkJC28XqlSRABM+sHdSQXbC8NZ0DShBMHqg==} - engines: {node: '>=18.0.0'} + '@jridgewell/source-map@0.3.11': + resolution: {integrity: sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==} - '@smithy/querystring-parser@4.2.6': - resolution: {integrity: sha512-YmWxl32SQRw/kIRccSOxzS/Ib8/b5/f9ex0r5PR40jRJg8X1wgM3KrR2In+8zvOGVhRSXgvyQpw9yOSlmfmSnA==} - engines: {node: '>=18.0.0'} + '@jridgewell/sourcemap-codec@1.5.5': + resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} - '@smithy/service-error-classification@4.2.6': - resolution: {integrity: sha512-Q73XBrzJlGTut2nf5RglSntHKgAG0+KiTJdO5QQblLfr4TdliGwIAha1iZIjwisc3rA5ulzqwwsYC6xrclxVQg==} - engines: {node: '>=18.0.0'} + '@jridgewell/trace-mapping@0.3.31': + resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} - '@smithy/shared-ini-file-loader@4.4.1': - resolution: {integrity: sha512-tph+oQYPbpN6NamF030hx1gb5YN2Plog+GLaRHpoEDwp8+ZPG26rIJvStG9hkWzN2HBn3HcWg0sHeB0tmkYzqA==} - engines: {node: '>=18.0.0'} + '@jridgewell/trace-mapping@0.3.9': + resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} - '@smithy/signature-v4@5.3.6': - resolution: {integrity: sha512-P1TXDHuQMadTMTOBv4oElZMURU4uyEhxhHfn+qOc2iofW9Rd4sZtBGx58Lzk112rIGVEYZT8eUMK4NftpewpRA==} - engines: {node: '>=18.0.0'} + '@jsonjoy.com/base64@1.1.2': + resolution: {integrity: sha512-q6XAnWQDIMA3+FTiOYajoYqySkO+JSat0ytXGSuRdq9uXE7o92gzuQwQM14xaCRlBLGq3v5miDGC4vkVTn54xA==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' - '@smithy/smithy-client@4.10.1': - resolution: {integrity: sha512-1ovWdxzYprhq+mWqiGZlt3kF69LJthuQcfY9BIyHx9MywTFKzFapluku1QXoaBB43GCsLDxNqS+1v30ure69AA==} - engines: {node: '>=18.0.0'} + '@jsonjoy.com/base64@17.65.0': + resolution: {integrity: sha512-Xrh7Fm/M0QAYpekSgmskdZYnFdSGnsxJ/tHaolA4bNwWdG9i65S8m83Meh7FOxyJyQAdo4d4J97NOomBLEfkDQ==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' - '@smithy/types@4.10.0': - resolution: {integrity: sha512-K9mY7V/f3Ul+/Gz4LJANZ3vJ/yiBIwCyxe0sPT4vNJK63Srvd+Yk1IzP0t+nE7XFSpIGtzR71yljtnqpUTYFlQ==} - engines: {node: '>=18.0.0'} + '@jsonjoy.com/buffers@1.2.1': + resolution: {integrity: sha512-12cdlDwX4RUM3QxmUbVJWqZ/mrK6dFQH4Zxq6+r1YXKXYBNgZXndx2qbCJwh3+WWkCSn67IjnlG3XYTvmvYtgA==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' - '@smithy/url-parser@4.2.6': - resolution: {integrity: sha512-tVoyzJ2vXp4R3/aeV4EQjBDmCuWxRa8eo3KybL7Xv4wEM16nObYh7H1sNfcuLWHAAAzb0RVyxUz1S3sGj4X+Tg==} - engines: {node: '>=18.0.0'} + '@jsonjoy.com/buffers@17.65.0': + resolution: {integrity: sha512-eBrIXd0/Ld3p9lpDDlMaMn6IEfWqtHMD+z61u0JrIiPzsV1r7m6xDZFRxJyvIFTEO+SWdYF9EiQbXZGd8BzPfA==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' - '@smithy/util-base64@4.3.0': - resolution: {integrity: sha512-GkXZ59JfyxsIwNTWFnjmFEI8kZpRNIBfxKjv09+nkAWPt/4aGaEWMM04m4sxgNVWkbt2MdSvE3KF/PfX4nFedQ==} - engines: {node: '>=18.0.0'} + '@jsonjoy.com/codegen@1.0.0': + resolution: {integrity: sha512-E8Oy+08cmCf0EK/NMxpaJZmOxPqM+6iSe2S4nlSBrPZOORoDJILxtbSUEDKQyTamm/BVAhIGllOBNU79/dwf0g==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' - '@smithy/util-body-length-browser@4.2.0': - resolution: {integrity: sha512-Fkoh/I76szMKJnBXWPdFkQJl2r9SjPt3cMzLdOB6eJ4Pnpas8hVoWPYemX/peO0yrrvldgCUVJqOAjUrOLjbxg==} - engines: {node: '>=18.0.0'} + '@jsonjoy.com/codegen@17.65.0': + resolution: {integrity: sha512-7MXcRYe7n3BG+fo3jicvjB0+6ypl2Y/bQp79Sp7KeSiiCgLqw4Oled6chVv07/xLVTdo3qa1CD0VCCnPaw+RGA==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' - '@smithy/util-body-length-node@4.2.1': - resolution: {integrity: sha512-h53dz/pISVrVrfxV1iqXlx5pRg3V2YWFcSQyPyXZRrZoZj4R4DeWRDo1a7dd3CPTcFi3kE+98tuNyD2axyZReA==} - engines: {node: '>=18.0.0'} + '@jsonjoy.com/fs-core@4.56.4': + resolution: {integrity: sha512-mgiAa7w0N0mlr7G3PUY/iRSYuJwyZmHBt+y7D9veiXfAqsIhEi9+FCu47tU+y/3KPqaTNJMsfgAGwUnLPnRdqA==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' - '@smithy/util-buffer-from@2.2.0': - resolution: {integrity: sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==} - engines: {node: '>=14.0.0'} + '@jsonjoy.com/fs-fsa@4.56.4': + resolution: {integrity: sha512-D6tHSr8xMiZnV9pQcX0ysoEg1kTsTFK6fRV+TX+1uFcEiNKJR7hooGBq8iKnkZCXRxY8S4nZJ+rErpVF1XJ4vw==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' - '@smithy/util-buffer-from@4.2.0': - resolution: {integrity: sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew==} - engines: {node: '>=18.0.0'} + '@jsonjoy.com/fs-node-builtins@4.56.4': + resolution: {integrity: sha512-/HMj267Ygg/fa3kHuZL+L7rVXvZ7HT2Bm7d8CpKs6l7QpT4mzTnN4f2/E0u+LsrrJVbT+R34/nsBr2dIZSYIgg==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' - '@smithy/util-config-provider@4.2.0': - resolution: {integrity: sha512-YEjpl6XJ36FTKmD+kRJJWYvrHeUvm5ykaUS5xK+6oXffQPHeEM4/nXlZPe+Wu0lsgRUcNZiliYNh/y7q9c2y6Q==} - engines: {node: '>=18.0.0'} + '@jsonjoy.com/fs-node-to-fsa@4.56.4': + resolution: {integrity: sha512-Wewg2JlMkFpUt2Z+RrhdxLrbG6o4XAZB9UdGbpcQS+acvwytmhEjUCCodD3kqY5wPSNpnIbD614VeTA/5jPzvg==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' - '@smithy/util-defaults-mode-browser@4.3.15': - resolution: {integrity: sha512-LiZQVAg/oO8kueX4c+oMls5njaD2cRLXRfcjlTYjhIqmwHnCwkQO5B3dMQH0c5PACILxGAQf6Mxsq7CjlDc76A==} - engines: {node: '>=18.0.0'} + '@jsonjoy.com/fs-node-utils@4.56.4': + resolution: {integrity: sha512-7yvPBX+YUPvoljJ5ELmHrK7sLYzEVdLnILoNXLtsztN4Ag8UbS7DteWRiW3BFAUIvI4kDBJ8OymdxwLLCkX+AQ==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' - '@smithy/util-defaults-mode-node@4.2.18': - resolution: {integrity: sha512-Kw2J+KzYm9C9Z9nY6+W0tEnoZOofstVCMTshli9jhQbQCy64rueGfKzPfuFBnVUqZD9JobxTh2DzHmPkp/Va/Q==} - engines: {node: '>=18.0.0'} + '@jsonjoy.com/fs-node@4.56.4': + resolution: {integrity: sha512-4G7KBypcWy2BGPnuDCmUQWHasbNZnEqcb3DLODuH22J8fre7YK8MiyciIohkUTFMqR9qem84LK22T1FmUwiTSQ==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' - '@smithy/util-endpoints@3.2.6': - resolution: {integrity: sha512-v60VNM2+mPvgHCBXEfMCYrQ0RepP6u6xvbAkMenfe4Mi872CqNkJzgcnQL837e8NdeDxBgrWQRTluKq5Lqdhfg==} - engines: {node: '>=18.0.0'} + '@jsonjoy.com/fs-print@4.56.4': + resolution: {integrity: sha512-GtTDri9Ot1l7XPe3ft+ViTqxFOqtKcM4RLyXEXWDvQEoqgmU/6bCNNjfSze9VlpfC8KfuUYAixuDLD1quzHdow==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' - '@smithy/util-hex-encoding@4.2.0': - resolution: {integrity: sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw==} - engines: {node: '>=18.0.0'} + '@jsonjoy.com/fs-snapshot@4.56.4': + resolution: {integrity: sha512-qQxl+GVp9gzT21/Ot8qa+pcNurpfTL/ruMODYmshpcTLXy6x06aP4/xdhBOJpBclhqbnQcMTVDCny98CtGvyzQ==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' - '@smithy/util-middleware@4.2.6': - resolution: {integrity: sha512-qrvXUkxBSAFomM3/OEMuDVwjh4wtqK8D2uDZPShzIqOylPst6gor2Cdp6+XrH4dyksAWq/bE2aSDYBTTnj0Rxg==} - engines: {node: '>=18.0.0'} + '@jsonjoy.com/json-pack@1.21.0': + resolution: {integrity: sha512-+AKG+R2cfZMShzrF2uQw34v3zbeDYUqnQ+jg7ORic3BGtfw9p/+N6RJbq/kkV8JmYZaINknaEQ2m0/f693ZPpg==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' - '@smithy/util-retry@4.2.6': - resolution: {integrity: sha512-x7CeDQLPQ9cb6xN7fRJEjlP9NyGW/YeXWc4j/RUhg4I+H60F0PEeRc2c/z3rm9zmsdiMFzpV/rT+4UHW6KM1SA==} - engines: {node: '>=18.0.0'} + '@jsonjoy.com/json-pack@17.65.0': + resolution: {integrity: sha512-e0SG/6qUCnVhHa0rjDJHgnXnbsacooHVqQHxspjvlYQSkHm+66wkHw6Gql+3u/WxI/b1VsOdUi0M+fOtkgKGdQ==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' - '@smithy/util-stream@4.5.7': - resolution: {integrity: sha512-Uuy4S5Aj4oF6k1z+i2OtIBJUns4mlg29Ph4S+CqjR+f4XXpSFVgTCYLzMszHJTicYDBxKFtwq2/QSEDSS5l02A==} - engines: {node: '>=18.0.0'} + '@jsonjoy.com/json-pointer@1.0.2': + resolution: {integrity: sha512-Fsn6wM2zlDzY1U+v4Nc8bo3bVqgfNTGcn6dMgs6FjrEnt4ZCe60o6ByKRjOGlI2gow0aE/Q41QOigdTqkyK5fg==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' - '@smithy/util-uri-escape@4.2.0': - resolution: {integrity: sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA==} - engines: {node: '>=18.0.0'} + '@jsonjoy.com/json-pointer@17.65.0': + resolution: {integrity: sha512-uhTe+XhlIZpWOxgPcnO+iSCDgKKBpwkDVTyYiXX9VayGV8HSFVJM67M6pUE71zdnXF1W0Da21AvnhlmdwYPpow==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' - '@smithy/util-utf8@2.3.0': - resolution: {integrity: sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==} - engines: {node: '>=14.0.0'} + '@jsonjoy.com/util@1.9.0': + resolution: {integrity: sha512-pLuQo+VPRnN8hfPqUTLTHk126wuYdXVxE6aDmjSeV4NCAgyxWbiOIeNJVtID3h1Vzpoi9m4jXezf73I6LgabgQ==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' - '@smithy/util-utf8@4.2.0': - resolution: {integrity: sha512-zBPfuzoI8xyBtR2P6WQj63Rz8i3AmfAaJLuNG8dWsfvPe8lO4aCPYLn879mEgHndZH1zQ2oXmG8O1GGzzaoZiw==} - engines: {node: '>=18.0.0'} + '@jsonjoy.com/util@17.65.0': + resolution: {integrity: sha512-cWiEHZccQORf96q2y6zU3wDeIVPeidmGqd9cNKJRYoVHTV0S1eHPy5JTbHpMnGfDvtvujQwQozOqgO9ABu6h0w==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' - '@smithy/util-waiter@4.2.6': - resolution: {integrity: sha512-xU9HwUSik9UUCJmm530yvBy0AwlQFICveKmqvaaTukKkXEAhyiBdHtSrhPrH3rH+uz0ykyaE3LdgsX86C6mDCQ==} - engines: {node: '>=18.0.0'} + '@leichtgewicht/ip-codec@2.0.5': + resolution: {integrity: sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==} - '@smithy/uuid@1.1.0': - resolution: {integrity: sha512-4aUIteuyxtBUhVdiQqcDhKFitwfd9hqoSDYY2KRXiWtgoWJ9Bmise+KfEPDiVHWeJepvF8xJO9/9+WDIciMFFw==} - engines: {node: '>=18.0.0'} + '@lit-labs/ssr-dom-shim@1.4.0': + resolution: {integrity: sha512-ficsEARKnmmW5njugNYKipTm4SFnbik7CXtoencDZzmzo/dQ+2Q0bgkzJuoJP20Aj0F+izzJjOqsnkd6F/o1bw==} - '@socket.io/component-emitter@3.1.2': - resolution: {integrity: sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==} + '@lit/reactive-element@2.1.1': + resolution: {integrity: sha512-N+dm5PAYdQ8e6UlywyyrgI2t++wFGXfHx+dSJ1oBrg6FAxUj40jId++EaRm80MKX5JnlH1sBsyZ5h0bcZKemCg==} - '@solana-program/system@0.8.1': - resolution: {integrity: sha512-71U9Mzdpw8HQtfgfJSL5xKZbLMRnza2Llsfk7gGnmg2waqK+o8MMH4YNma8xXS1UmOBptXIiNvoZ3p7cmOVktg==} - peerDependencies: - '@solana/kit': ^3.0 + '@mdx-js/mdx@3.1.1': + resolution: {integrity: sha512-f6ZO2ifpwAQIpzGWaBQT2TXxPv6z3RBzQKpVftEWN78Vl/YweF1uwussDx8ECAXVtr3Rs89fKyG9YlzUs9DyGQ==} - '@solana-program/token@0.6.0': - resolution: {integrity: sha512-omkZh4Tt9rre4wzWHNOhOEHyenXQku3xyc/UrKvShexA/Qlhza67q7uRwmwEDUs4QqoDBidSZPooOmepnA/jig==} + '@mdx-js/react@3.1.1': + resolution: {integrity: sha512-f++rKLQgUVYDAtECQ6fn/is15GkEH9+nZPM3MS0RcxVqoTfawHvDlSCH7JbMhAM6uJ32v3eXLvLmLvjGu7PTQw==} peerDependencies: - '@solana/kit': ^3.0 + '@types/react': '>=16' + react: '>=16' - '@solana/accounts@3.0.3': - resolution: {integrity: sha512-KqlePrlZaHXfu8YQTCxN204ZuVm9o68CCcUr6l27MG2cuRUtEM1Ta0iR8JFkRUAEfZJC4Cu0ZDjK/v49loXjZQ==} - engines: {node: '>=20.18.0'} - peerDependencies: - typescript: '>=5.3.3' + '@metamask/eth-json-rpc-provider@1.0.1': + resolution: {integrity: sha512-whiUMPlAOrVGmX8aKYVPvlKyG4CpQXiNNyt74vE1xb5sPvmx5oA7B/kOi/JdBvhGQq97U1/AVdXEdk2zkP8qyA==} + engines: {node: '>=14.0.0'} - '@solana/addresses@3.0.3': - resolution: {integrity: sha512-AuMwKhJI89ANqiuJ/fawcwxNKkSeHH9CApZd2xelQQLS7X8uxAOovpcmEgiObQuiVP944s9ScGUT62Bdul9qYg==} - engines: {node: '>=20.18.0'} - peerDependencies: - typescript: '>=5.3.3' + '@metamask/json-rpc-engine@7.3.3': + resolution: {integrity: sha512-dwZPq8wx9yV3IX2caLi9q9xZBw2XeIoYqdyihDDDpuHVCEiqadJLwqM3zy+uwf6F1QYQ65A8aOMQg1Uw7LMLNg==} + engines: {node: '>=16.0.0'} - '@solana/assertions@3.0.3': - resolution: {integrity: sha512-2qspxdbWp2y62dfCIlqeWQr4g+hE8FYSSwcaP6itwMwGRb8393yDGCJfI/znuzJh6m/XVWhMHIgFgsBwnevCmg==} - engines: {node: '>=20.18.0'} - peerDependencies: - typescript: '>=5.3.3' + '@metamask/json-rpc-engine@8.0.2': + resolution: {integrity: sha512-IoQPmql8q7ABLruW7i4EYVHWUbF74yrp63bRuXV5Zf9BQwcn5H9Ww1eLtROYvI1bUXwOiHZ6qT5CWTrDc/t/AA==} + engines: {node: '>=16.0.0'} - '@solana/buffer-layout@4.0.1': - resolution: {integrity: sha512-E1ImOIAD1tBZFRdjeM4/pzTiTApC0AOBGwyAMS4fwIodCWArzJ3DWdoh8cKxeFM2fElkxBh2Aqts1BPC373rHA==} - engines: {node: '>=5.10'} + '@metamask/json-rpc-middleware-stream@7.0.2': + resolution: {integrity: sha512-yUdzsJK04Ev98Ck4D7lmRNQ8FPioXYhEUZOMS01LXW8qTvPGiRVXmVltj2p4wrLkh0vW7u6nv0mNl5xzC5Qmfg==} + engines: {node: '>=16.0.0'} - '@solana/codecs-core@2.3.0': - resolution: {integrity: sha512-oG+VZzN6YhBHIoSKgS5ESM9VIGzhWjEHEGNPSibiDTxFhsFWxNaz8LbMDPjBUE69r9wmdGLkrQ+wVPbnJcZPvw==} - engines: {node: '>=20.18.0'} - peerDependencies: - typescript: '>=5.3.3' + '@metamask/object-multiplex@2.1.0': + resolution: {integrity: sha512-4vKIiv0DQxljcXwfpnbsXcfa5glMj5Zg9mqn4xpIWqkv6uJ2ma5/GtUfLFSxhlxnR8asRMv8dDmWya1Tc1sDFA==} + engines: {node: ^16.20 || ^18.16 || >=20} - '@solana/codecs-core@3.0.3': - resolution: {integrity: sha512-emKykJ3h1DmnDOY29Uv9eJXP8E/FHzvlUBJ6te+5EbKdFjj7vdlKYPfDxOI6iGdXTY+YC/ELtbNBh6QwF2uEDQ==} - engines: {node: '>=20.18.0'} - peerDependencies: - typescript: '>=5.3.3' + '@metamask/onboarding@1.0.1': + resolution: {integrity: sha512-FqHhAsCI+Vacx2qa5mAFcWNSrTcVGMNjzxVgaX8ECSny/BJ9/vgXP9V7WF/8vb9DltPeQkxr+Fnfmm6GHfmdTQ==} - '@solana/codecs-data-structures@3.0.3': - resolution: {integrity: sha512-R15cLp8riJvToXziW8lP6AMSwsztGhEnwgyGmll32Mo0Yjq+hduW2/fJrA/TJs6tA/OgTzMQjlxgk009EqZHCw==} - engines: {node: '>=20.18.0'} - peerDependencies: - typescript: '>=5.3.3' + '@metamask/providers@16.1.0': + resolution: {integrity: sha512-znVCvux30+3SaUwcUGaSf+pUckzT5ukPRpcBmy+muBLC0yaWnBcvDqGfcsw6CBIenUdFrVoAFa8B6jsuCY/a+g==} + engines: {node: ^18.18 || >=20} - '@solana/codecs-numbers@2.3.0': - resolution: {integrity: sha512-jFvvwKJKffvG7Iz9dmN51OGB7JBcy2CJ6Xf3NqD/VP90xak66m/Lg48T01u5IQ/hc15mChVHiBm+HHuOFDUrQg==} - engines: {node: '>=20.18.0'} - peerDependencies: - typescript: '>=5.3.3' + '@metamask/rpc-errors@6.4.0': + resolution: {integrity: sha512-1ugFO1UoirU2esS3juZanS/Fo8C8XYocCuBpfZI5N7ECtoG+zu0wF+uWZASik6CkO6w9n/Iebt4iI4pT0vptpg==} + engines: {node: '>=16.0.0'} - '@solana/codecs-numbers@3.0.3': - resolution: {integrity: sha512-pfXkH9J0glrM8qj6389GAn30+cJOxzXLR2FsPOHCUMXrqLhGjMMZAWhsQkpOQ37SGc/7EiQsT/gmyGC7gxHqJQ==} - engines: {node: '>=20.18.0'} - peerDependencies: - typescript: '>=5.3.3' + '@metamask/rpc-errors@7.0.2': + resolution: {integrity: sha512-YYYHsVYd46XwY2QZzpGeU4PSdRhHdxnzkB8piWGvJW2xbikZ3R+epAYEL4q/K8bh9JPTucsUdwRFnACor1aOYw==} + engines: {node: ^18.20 || ^20.17 || >=22} - '@solana/codecs-strings@3.0.3': - resolution: {integrity: sha512-VHBXnnTVtcQ1j+7Vrz+qSYo38no+jiHRdGnhFspRXEHNJbllzwKqgBE7YN3qoIXH+MKxgJUcwO5KHmdzf8Wn2A==} - engines: {node: '>=20.18.0'} - peerDependencies: - fastestsmallesttextencoderdecoder: ^1.0.22 - typescript: '>=5.3.3' + '@metamask/safe-event-emitter@2.0.0': + resolution: {integrity: sha512-/kSXhY692qiV1MXu6EeOZvg5nECLclxNXcKCxJ3cXQgYuRymRHpdx/t7JXfsK+JLjwA1e1c1/SBrlQYpusC29Q==} - '@solana/codecs@3.0.3': - resolution: {integrity: sha512-GOHwTlIQsCoJx9Ryr6cEf0FHKAQ7pY4aO4xgncAftrv0lveTQ1rPP2inQ1QT0gJllsIa8nwbfXAADs9nNJxQDA==} - engines: {node: '>=20.18.0'} - peerDependencies: - typescript: '>=5.3.3' + '@metamask/safe-event-emitter@3.1.2': + resolution: {integrity: sha512-5yb2gMI1BDm0JybZezeoX/3XhPDOtTbcFvpTXM9kxsoZjPZFh4XciqRbpD6N86HYZqWDhEaKUDuOyR0sQHEjMA==} + engines: {node: '>=12.0.0'} - '@solana/errors@2.3.0': - resolution: {integrity: sha512-66RI9MAbwYV0UtP7kGcTBVLxJgUxoZGm8Fbc0ah+lGiAw17Gugco6+9GrJCV83VyF2mDWyYnYM9qdI3yjgpnaQ==} - engines: {node: '>=20.18.0'} - hasBin: true - peerDependencies: - typescript: '>=5.3.3' + '@metamask/sdk-analytics@0.0.5': + resolution: {integrity: sha512-fDah+keS1RjSUlC8GmYXvx6Y26s3Ax1U9hGpWb6GSY5SAdmTSIqp2CvYy6yW0WgLhnYhW+6xERuD0eVqV63QIQ==} - '@solana/errors@3.0.3': - resolution: {integrity: sha512-1l84xJlHNva6io62PcYfUamwWlc0eM95nHgCrKX0g0cLoC6D6QHYPCEbEVkR+C5UtP9JDgyQM8MFiv+Ei5tO9Q==} - engines: {node: '>=20.18.0'} - hasBin: true + '@metamask/sdk-communication-layer@0.33.1': + resolution: {integrity: sha512-0bI9hkysxcfbZ/lk0T2+aKVo1j0ynQVTuB3sJ5ssPWlz+Z3VwveCkP1O7EVu1tsVVCb0YV5WxK9zmURu2FIiaA==} peerDependencies: - typescript: '>=5.3.3' + cross-fetch: ^4.0.0 + eciesjs: '*' + eventemitter2: ^6.4.9 + readable-stream: ^3.6.2 + socket.io-client: ^4.5.1 - '@solana/fast-stable-stringify@3.0.3': - resolution: {integrity: sha512-ED0pxB6lSEYvg+vOd5hcuQrgzEDnOrURFgp1ZOY+lQhJkQU6xo+P829NcJZQVP1rdU2/YQPAKJKEseyfe9VMIw==} - engines: {node: '>=20.18.0'} - peerDependencies: - typescript: '>=5.3.3' + '@metamask/sdk-install-modal-web@0.32.1': + resolution: {integrity: sha512-MGmAo6qSjf1tuYXhCu2EZLftq+DSt5Z7fsIKr2P+lDgdTPWgLfZB1tJKzNcwKKOdf6q9Qmmxn7lJuI/gq5LrKw==} - '@solana/functional@3.0.3': - resolution: {integrity: sha512-2qX1kKANn8995vOOh5S9AmF4ItGZcfbny0w28Eqy8AFh+GMnSDN4gqpmV2LvxBI9HibXZptGH3RVOMk82h1Mpw==} - engines: {node: '>=20.18.0'} - peerDependencies: - typescript: '>=5.3.3' + '@metamask/sdk@0.33.1': + resolution: {integrity: sha512-1mcOQVGr9rSrVcbKPNVzbZ8eCl1K0FATsYH3WJ/MH4WcZDWGECWrXJPNMZoEAkLxWiMe8jOQBumg2pmcDa9zpQ==} - '@solana/instruction-plans@3.0.3': - resolution: {integrity: sha512-eqoaPtWtmLTTpdvbt4BZF5H6FIlJtXi9H7qLOM1dLYonkOX2Ncezx5NDCZ9tMb2qxVMF4IocYsQnNSnMfjQF1w==} - engines: {node: '>=20.18.0'} - peerDependencies: - typescript: '>=5.3.3' + '@metamask/superstruct@3.2.1': + resolution: {integrity: sha512-fLgJnDOXFmuVlB38rUN5SmU7hAFQcCjrg3Vrxz67KTY7YHFnSNEKvX4avmEBdOI0yTCxZjwMCFEqsC8k2+Wd3g==} + engines: {node: '>=16.0.0'} - '@solana/instructions@3.0.3': - resolution: {integrity: sha512-4csIi8YUDb5j/J+gDzmYtOvq7ZWLbCxj4t0xKn+fPrBk/FD2pK29KVT3Fu7j4Lh1/ojunQUP9X4NHwUexY3PnA==} - engines: {node: '>=20.18.0'} - peerDependencies: - typescript: '>=5.3.3' + '@metamask/utils@11.9.0': + resolution: {integrity: sha512-wRnoSDD9jTWOge/+reFviJQANhS+uy8Y+OEwRanp5mQeGTjBFmK1r2cTOnei2UCZRV1crXHzeJVSFEoDDcgRbA==} + engines: {node: ^18.18 || ^20.14 || >=22} - '@solana/keys@3.0.3': - resolution: {integrity: sha512-tp8oK9tMadtSIc4vF4aXXWkPd4oU5XPW8nf28NgrGDWGt25fUHIydKjkf2hPtMt9i1WfRyQZ33B5P3dnsNqcPQ==} - engines: {node: '>=20.18.0'} - peerDependencies: - typescript: '>=5.3.3' + '@metamask/utils@5.0.2': + resolution: {integrity: sha512-yfmE79bRQtnMzarnKfX7AEJBwFTxvTyw3nBQlu/5rmGXrjAeAMltoGxO62TFurxrQAFMNa/fEjIHNvungZp0+g==} + engines: {node: '>=14.0.0'} - '@solana/kit@3.0.3': - resolution: {integrity: sha512-CEEhCDmkvztd1zbgADsEQhmj9GyWOOGeW1hZD+gtwbBSF5YN1uofS/pex5MIh/VIqKRj+A2UnYWI1V+9+q/lyQ==} - engines: {node: '>=20.18.0'} - peerDependencies: - typescript: '>=5.3.3' + '@metamask/utils@8.5.0': + resolution: {integrity: sha512-I6bkduevXb72TIM9q2LRO63JSsF9EXduh3sBr9oybNX2hNNpr/j1tEjXrsG0Uabm4MJ1xkGAQEMwifvKZIkyxQ==} + engines: {node: '>=16.0.0'} - '@solana/nominal-types@3.0.3': - resolution: {integrity: sha512-aZavCiexeUAoMHRQg4s1AHkH3wscbOb70diyfjhwZVgFz1uUsFez7csPp9tNFkNolnadVb2gky7yBk3IImQJ6A==} - engines: {node: '>=20.18.0'} - peerDependencies: - typescript: '>=5.3.3' + '@metamask/utils@9.3.0': + resolution: {integrity: sha512-w8CVbdkDrVXFJbfBSlDfafDR6BAkpDmv1bC1UJVCoVny5tW2RKAdn9i68Xf7asYT4TnUhl/hN4zfUiKQq9II4g==} + engines: {node: '>=16.0.0'} - '@solana/options@3.0.3': - resolution: {integrity: sha512-jarsmnQ63RN0JPC5j9sgUat07NrL9PC71XU7pUItd6LOHtu4+wJMio3l5mT0DHVfkfbFLL6iI6+QmXSVhTNF3g==} - engines: {node: '>=20.18.0'} - peerDependencies: - typescript: '>=5.3.3' + '@noble/ciphers@1.2.1': + resolution: {integrity: sha512-rONPWMC7PeExE077uLE4oqWrZ1IvAfz3oH9LibVAcVCopJiA9R62uavnbEzdkVmJYI6M6Zgkbeb07+tWjlq2XA==} + engines: {node: ^14.21.3 || >=16} - '@solana/programs@3.0.3': - resolution: {integrity: sha512-JZlVE3/AeSNDuH3aEzCZoDu8GTXkMpGXxf93zXLzbxfxhiQ/kHrReN4XE/JWZ/uGWbaFZGR5B3UtdN2QsoZL7w==} - engines: {node: '>=20.18.0'} - peerDependencies: - typescript: '>=5.3.3' + '@noble/ciphers@1.3.0': + resolution: {integrity: sha512-2I0gnIVPtfnMw9ee9h1dJG7tp81+8Ob3OJb3Mv37rx5L40/b0i7djjCVvGOVqc9AEIQyvyu1i6ypKdFw8R8gQw==} + engines: {node: ^14.21.3 || >=16} - '@solana/promises@3.0.3': - resolution: {integrity: sha512-K+UflGBVxj30XQMHTylHHZJdKH5QG3oj5k2s42GrZ/Wbu72oapVJySMBgpK45+p90t8/LEqV6rRPyTXlet9J+Q==} - engines: {node: '>=20.18.0'} - peerDependencies: - typescript: '>=5.3.3' + '@noble/curves@1.2.0': + resolution: {integrity: sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==} - '@solana/rpc-api@3.0.3': - resolution: {integrity: sha512-Yym9/Ama62OY69rAZgbOCAy1QlqaWAyb0VlqFuwSaZV1pkFCCFSwWEJEsiN1n8pb2ZP+RtwNvmYixvWizx9yvA==} - engines: {node: '>=20.18.0'} - peerDependencies: - typescript: '>=5.3.3' + '@noble/curves@1.4.2': + resolution: {integrity: sha512-TavHr8qycMChk8UwMld0ZDRvatedkzWfH8IiaeGCfymOP5i0hSCozz9vHOL0nkwk7HRMlFnAiKpS2jrUmSybcw==} - '@solana/rpc-parsed-types@3.0.3': - resolution: {integrity: sha512-/koM05IM2fU91kYDQxXil3VBNlOfcP+gXE0js1sdGz8KonGuLsF61CiKB5xt6u1KEXhRyDdXYLjf63JarL4Ozg==} - engines: {node: '>=20.18.0'} - peerDependencies: - typescript: '>=5.3.3' + '@noble/curves@1.8.0': + resolution: {integrity: sha512-j84kjAbzEnQHaSIhRPUmB3/eVXu2k3dKPl2LOrR8fSOIL+89U+7lV117EWHtq/GHM3ReGHM46iRBdZfpc4HRUQ==} + engines: {node: ^14.21.3 || >=16} - '@solana/rpc-spec-types@3.0.3': - resolution: {integrity: sha512-A6Jt8SRRetnN3CeGAvGJxigA9zYRslGgWcSjueAZGvPX+MesFxEUjSWZCfl+FogVFvwkqfkgQZQbPAGZQFJQ6Q==} - engines: {node: '>=20.18.0'} - peerDependencies: - typescript: '>=5.3.3' + '@noble/curves@1.8.1': + resolution: {integrity: sha512-warwspo+UYUPep0Q+vtdVB4Ugn8GGQj8iyB3gnRWsztmUHTI3S1nhdiWNsPUGL0vud7JlRRk1XEu7Lq1KGTnMQ==} + engines: {node: ^14.21.3 || >=16} - '@solana/rpc-spec@3.0.3': - resolution: {integrity: sha512-MZn5/8BebB6MQ4Gstw6zyfWsFAZYAyLzMK+AUf/rSfT8tPmWiJ/mcxnxqOXvFup/l6D67U8pyGpIoFqwCeZqqA==} - engines: {node: '>=20.18.0'} - peerDependencies: - typescript: '>=5.3.3' + '@noble/curves@1.8.2': + resolution: {integrity: sha512-vnI7V6lFNe0tLAuJMu+2sX+FcL14TaCWy1qiczg1VwRmPrpQCdq5ESXQMqUc2tluRNf6irBXrWbl1mGN8uaU/g==} + engines: {node: ^14.21.3 || >=16} - '@solana/rpc-subscriptions-api@3.0.3': - resolution: {integrity: sha512-MGgVK3PUS15qsjuhimpzGZrKD/CTTvS0mAlQ0Jw84zsr1RJVdQJK/F0igu07BVd172eTZL8d90NoAQ3dahW5pA==} - engines: {node: '>=20.18.0'} - peerDependencies: - typescript: '>=5.3.3' + '@noble/curves@1.9.1': + resolution: {integrity: sha512-k11yZxZg+t+gWvBbIswW0yoJlu8cHOC7dhunwOzoWH/mXGBiYyR4YY6hAEK/3EUs4UpB8la1RfdRpeGsFHkWsA==} + engines: {node: ^14.21.3 || >=16} - '@solana/rpc-subscriptions-channel-websocket@3.0.3': - resolution: {integrity: sha512-zUzUlb8Cwnw+SHlsLrSqyBRtOJKGc+FvSNJo/vWAkLShoV0wUDMPv7VvhTngJx3B/3ANfrOZ4i08i9QfYPAvpQ==} - engines: {node: '>=20.18.0'} - peerDependencies: - typescript: '>=5.3.3' - ws: ^8.18.0 + '@noble/curves@1.9.7': + resolution: {integrity: sha512-gbKGcRUYIjA3/zCCNaWDciTMFI0dCkvou3TL8Zmy5Nc7sJ47a0jtOeZoTaMxkuqRo9cRhjOdZJXegxYE5FN/xw==} + engines: {node: ^14.21.3 || >=16} - '@solana/rpc-subscriptions-spec@3.0.3': - resolution: {integrity: sha512-9KpQ32OBJWS85mn6q3gkM0AjQe1LKYlMU7gpJRrla/lvXxNLhI95tz5K6StctpUreVmRWTVkNamHE69uUQyY8A==} - engines: {node: '>=20.18.0'} - peerDependencies: - typescript: '>=5.3.3' + '@noble/curves@2.0.1': + resolution: {integrity: sha512-vs1Az2OOTBiP4q0pwjW5aF0xp9n4MxVrmkFBxc6EKZc6ddYx5gaZiAsZoq0uRRXWbi3AT/sBqn05eRPtn1JCPw==} + engines: {node: '>= 20.19.0'} - '@solana/rpc-subscriptions@3.0.3': - resolution: {integrity: sha512-LRvz6NaqvtsYFd32KwZ+rwYQ9XCs+DWjV8BvBLsJpt9/NWSuHf/7Sy/vvP6qtKxut692H/TMvHnC4iulg0WmiQ==} - engines: {node: '>=20.18.0'} - peerDependencies: - typescript: '>=5.3.3' + '@noble/hashes@1.2.0': + resolution: {integrity: sha512-FZfhjEDbT5GRswV3C6uvLPHMiVD6lQBmpoX5+eSiPaMTXte/IKqI5dykDxzZB/WBeK/CDuQRBWarPdi3FNY2zQ==} - '@solana/rpc-transformers@3.0.3': - resolution: {integrity: sha512-lzdaZM/dG3s19Tsk4mkJA5JBoS1eX9DnD7z62gkDwrwJDkDBzkAJT9aLcsYFfTmwTfIp6uU2UPgGYc97i1wezw==} - engines: {node: '>=20.18.0'} - peerDependencies: - typescript: '>=5.3.3' + '@noble/hashes@1.3.2': + resolution: {integrity: sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==} + engines: {node: '>= 16'} - '@solana/rpc-transport-http@3.0.3': - resolution: {integrity: sha512-bIXFwr2LR5A97Z46dI661MJPbHnPfcShBjFzOS/8Rnr8P4ho3j/9EUtjDrsqoxGJT3SLWj5OlyXAlaDAvVTOUQ==} - engines: {node: '>=20.18.0'} - peerDependencies: - typescript: '>=5.3.3' + '@noble/hashes@1.4.0': + resolution: {integrity: sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==} + engines: {node: '>= 16'} - '@solana/rpc-types@3.0.3': - resolution: {integrity: sha512-petWQ5xSny9UfmC3Qp2owyhNU0w9SyBww4+v7tSVyXMcCC9v6j/XsqTeimH1S0qQUllnv0/FY83ohFaxofmZ6Q==} - engines: {node: '>=20.18.0'} - peerDependencies: - typescript: '>=5.3.3' + '@noble/hashes@1.7.0': + resolution: {integrity: sha512-HXydb0DgzTpDPwbVeDGCG1gIu7X6+AuU6Zl6av/E/KG8LMsvPntvq+w17CHRpKBmN6Ybdrt1eP3k4cj8DJa78w==} + engines: {node: ^14.21.3 || >=16} - '@solana/rpc@3.0.3': - resolution: {integrity: sha512-3oukAaLK78GegkKcm6iNmRnO4mFeNz+BMvA8T56oizoBNKiRVEq/6DFzVX/LkmZ+wvD601pAB3uCdrTPcC0YKQ==} - engines: {node: '>=20.18.0'} - peerDependencies: - typescript: '>=5.3.3' + '@noble/hashes@1.7.1': + resolution: {integrity: sha512-B8XBPsn4vT/KJAGqDzbwztd+6Yte3P4V7iafm24bxgDe/mlRuK6xmWPuCNrKt2vDafZ8MfJLlchDG/vYafQEjQ==} + engines: {node: ^14.21.3 || >=16} - '@solana/signers@3.0.3': - resolution: {integrity: sha512-UwCd/uPYTZiwd283JKVyOWLLN5sIgMBqGDyUmNU3vo9hcmXKv5ZGm/9TvwMY2z35sXWuIOcj7etxJ8OoWc/ObQ==} - engines: {node: '>=20.18.0'} - peerDependencies: - typescript: '>=5.3.3' + '@noble/hashes@1.7.2': + resolution: {integrity: sha512-biZ0NUSxyjLLqo6KxEJ1b+C2NAx0wtDoFvCaXHGgUkeHzf3Xc1xKumFKREuT7f7DARNZ/slvYUwFG6B0f2b6hQ==} + engines: {node: ^14.21.3 || >=16} - '@solana/subscribable@3.0.3': - resolution: {integrity: sha512-FJ27LKGHLQ5GGttPvTOLQDLrrOZEgvaJhB7yYaHAhPk25+p+erBaQpjePhfkMyUbL1FQbxn1SUJmS6jUuaPjlQ==} - engines: {node: '>=20.18.0'} - peerDependencies: - typescript: '>=5.3.3' + '@noble/hashes@1.8.0': + resolution: {integrity: sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==} + engines: {node: ^14.21.3 || >=16} - '@solana/sysvars@3.0.3': - resolution: {integrity: sha512-GnHew+QeKCs2f9ow+20swEJMH4mDfJA/QhtPgOPTYQx/z69J4IieYJ7fZenSHnA//lJ45fVdNdmy1trypvPLBQ==} - engines: {node: '>=20.18.0'} - peerDependencies: - typescript: '>=5.3.3' + '@noble/hashes@2.0.1': + resolution: {integrity: sha512-XlOlEbQcE9fmuXxrVTXCTlG2nlRXa9Rj3rr5Ue/+tX+nmkgbX720YHh0VR3hBF9xDvwnb8D2shVGOwNx+ulArw==} + engines: {node: '>= 20.19.0'} - '@solana/transaction-confirmation@3.0.3': - resolution: {integrity: sha512-dXx0OLtR95LMuARgi2dDQlL1QYmk56DOou5q9wKymmeV3JTvfDExeWXnOgjRBBq/dEfj4ugN1aZuTaS18UirFw==} - engines: {node: '>=20.18.0'} - peerDependencies: - typescript: '>=5.3.3' + '@noble/post-quantum@0.5.4': + resolution: {integrity: sha512-leww0zzIirrvwaYMPI9fj6aRIlA/c6Y0/lifQQ1YOOyHEr0MNH3yYpjXeiVG+tWdPps4XxGclFWX2INPO3Yo5w==} + engines: {node: '>= 20.19.0'} - '@solana/transaction-messages@3.0.3': - resolution: {integrity: sha512-s+6NWRnBhnnjFWV4x2tzBzoWa6e5LiIxIvJlWwVQBFkc8fMGY04w7jkFh0PM08t/QFKeXBEWkyBDa/TFYdkWug==} - engines: {node: '>=20.18.0'} - peerDependencies: - typescript: '>=5.3.3' + '@noble/secp256k1@1.7.1': + resolution: {integrity: sha512-hOUk6AyBFmqVrv7k5WAw/LpszxVbj9gGN4JRkIX52fdFAj1UA61KXmZDvqVEm+pOyec3+fIeZB02LYa/pWOArw==} - '@solana/transactions@3.0.3': - resolution: {integrity: sha512-iMX+n9j4ON7H1nKlWEbMqMOpKYC6yVGxKKmWHT1KdLRG7v+03I4DnDeFoI+Zmw56FA+7Bbne8jwwX60Q1vk/MQ==} - engines: {node: '>=20.18.0'} - peerDependencies: - typescript: '>=5.3.3' + '@noble/secp256k1@2.3.0': + resolution: {integrity: sha512-0TQed2gcBbIrh7Ccyw+y/uZQvbJwm7Ao4scBUxqpBCcsOlZG0O4KGfjtNAy/li4W8n1xt3dxrwJ0beZ2h2G6Kw==} - '@solana/web3.js@1.98.4': - resolution: {integrity: sha512-vv9lfnvjUsRiq//+j5pBdXig0IQdtzA0BRZ3bXEP4KaIyF1CcaydWqgyzQgfZMNIsWNWmG+AUHwPy4AHOD6gpw==} + '@nodelib/fs.scandir@2.1.5': + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} - '@solidity-parser/parser@0.14.5': - resolution: {integrity: sha512-6dKnHZn7fg/iQATVEzqyUOyEidbn05q7YA2mQ9hC0MMXhhV3/JrsxmFSYZAcr7j1yUP700LLhTruvJ3MiQmjJg==} + '@nodelib/fs.stat@2.0.5': + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} - '@solidity-parser/parser@0.20.2': - resolution: {integrity: sha512-rbu0bzwNvMcwAjH86hiEAcOeRI2EeK8zCkHDrFykh/Al8mvJeFmjy3UrE7GYQjNwOgbGUUtCn5/k8CB8zIu7QA==} + '@nodelib/fs.walk@1.2.8': + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} - '@swc/helpers@0.5.17': - resolution: {integrity: sha512-5IKx/Y13RsYd+sauPb2x+U/xZikHjolzfuDgTAl/Tdf3Q8rslRvC19NKDLgAJQ6wsqADk10ntlv08nPFw/gO/A==} + '@nomicfoundation/edr-darwin-arm64@0.12.0-next.17': + resolution: {integrity: sha512-gI9/9ysLeAid0+VSTBeutxOJ0/Rrh00niGkGL9+4lR577igDY+v55XGN0oBMST49ILS0f12J6ZY90LG8sxPXmQ==} + engines: {node: '>= 20'} - '@tanstack/query-core@5.90.12': - resolution: {integrity: sha512-T1/8t5DhV/SisWjDnaiU2drl6ySvsHj1bHBCWNXd+/T+Hh1cf6JodyEYMd5sgwm+b/mETT4EV3H+zCVczCU5hg==} + '@nomicfoundation/edr-darwin-x64@0.12.0-next.17': + resolution: {integrity: sha512-zSZtwf584RkIyb8awELDt7ctskogH0p4pmqOC4vhykc8ODOv2XLuG1IgeE4WgYhWGZOufbCtgLfpJQrWqN6mmw==} + engines: {node: '>= 20'} - '@tanstack/react-query@5.90.12': - resolution: {integrity: sha512-graRZspg7EoEaw0a8faiUASCyJrqjKPdqJ9EwuDRUF9mEYJ1YPczI9H+/agJ0mOJkPCJDk0lsz5QTrLZ/jQ2rg==} - peerDependencies: - react: ^18 || ^19 + '@nomicfoundation/edr-linux-arm64-gnu@0.12.0-next.17': + resolution: {integrity: sha512-WjdfgV6B7gT5Q0NXtSIWyeK8gzaJX5HK6/jclYVHarWuEtS1LFgePYgMjK8rmm7IRTkM9RsE/PCuQEP1nrSsuA==} + engines: {node: '>= 20'} - '@tsconfig/node10@1.0.12': - resolution: {integrity: sha512-UCYBaeFvM11aU2y3YPZ//O5Rhj+xKyzy7mvcIoAjASbigy8mHMryP5cK7dgjlz2hWxh1g5pLw084E0a/wlUSFQ==} + '@nomicfoundation/edr-linux-arm64-musl@0.12.0-next.17': + resolution: {integrity: sha512-26rObKhhCDb9JkZbToyr7JVZo4tSVAFvzoJSJVmvpOl0LOHrfFsgVQu2n/8cNkwMAqulPubKL2E0jdnmEoZjWA==} + engines: {node: '>= 20'} - '@tsconfig/node12@1.0.11': - resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==} + '@nomicfoundation/edr-linux-x64-gnu@0.12.0-next.17': + resolution: {integrity: sha512-dPkHScIf/CU6h6k3k4HNUnQyQcVSLKanviHCAcs5HkviiJPxvVtOMMvtNBxoIvKZRxGFxf2eutcqQW4ZV1wRQQ==} + engines: {node: '>= 20'} - '@tsconfig/node14@1.0.3': - resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==} + '@nomicfoundation/edr-linux-x64-musl@0.12.0-next.17': + resolution: {integrity: sha512-5Ixe/bpyWZxC3AjIb8EomAOK44ajemBVx/lZRHZiWSBlwQpbSWriYAtKjKcReQQPwuYVjnFpAD2AtuCvseIjHw==} + engines: {node: '>= 20'} - '@tsconfig/node16@1.0.4': - resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==} + '@nomicfoundation/edr-win32-x64-msvc@0.12.0-next.17': + resolution: {integrity: sha512-29YlvdgofSdXG1mUzIuH4kMXu1lmVc1hvYWUGWEH59L+LaakdhfJ/Wu5izeclKkrTh729Amtk/Hk1m29kFOO8A==} + engines: {node: '>= 20'} - '@typechain/ethers-v6@0.5.1': - resolution: {integrity: sha512-F+GklO8jBWlsaVV+9oHaPh5NJdd6rAKN4tklGfInX1Q7h0xPgVLP39Jl3eCulPB5qexI71ZFHwbljx4ZXNfouA==} + '@nomicfoundation/edr@0.12.0-next.17': + resolution: {integrity: sha512-Y8Kwqd5JpBmI/Kst6NJ/bZ81FeJea9J6WEwoSRTZnEvwfqW9dk9PI8zJs2UJpOACL1fXEPvN+doETbxT9EhwXA==} + engines: {node: '>= 20'} + + '@nomicfoundation/hardhat-chai-matchers@2.1.0': + resolution: {integrity: sha512-GPhBNafh1fCnVD9Y7BYvoLnblnvfcq3j8YDbO1gGe/1nOFWzGmV7gFu5DkwFXF+IpYsS+t96o9qc/mPu3V3Vfw==} peerDependencies: - ethers: 6.x - typechain: ^8.3.2 - typescript: '>=4.7.0' + '@nomicfoundation/hardhat-ethers': ^3.1.0 + chai: ^4.2.0 + ethers: ^6.14.0 + hardhat: ^2.26.0 - '@typechain/hardhat@9.1.0': - resolution: {integrity: sha512-mtaUlzLlkqTlfPwB3FORdejqBskSnh+Jl8AIJGjXNAQfRQ4ofHADPl1+oU7Z3pAJzmZbUXII8MhOLQltcHgKnA==} + '@nomicfoundation/hardhat-ethers@3.1.3': + resolution: {integrity: sha512-208JcDeVIl+7Wu3MhFUUtiA8TJ7r2Rn3Wr+lSx9PfsDTKkbsAsWPY6N6wQ4mtzDv0/pB9nIbJhkjoHe1EsgNsA==} peerDependencies: - '@typechain/ethers-v6': ^0.5.1 - ethers: ^6.1.0 - hardhat: ^2.9.9 - typechain: ^8.3.2 + ethers: ^6.14.0 + hardhat: ^2.28.0 - '@types/babel__core@7.20.5': - resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} + '@nomicfoundation/hardhat-ignition-ethers@0.15.17': + resolution: {integrity: sha512-io6Wrp1dUsJ94xEI3pw6qkPfhc9TFA+e6/+o16yQ8pvBTFMjgK5x8wIHKrrIHr9L3bkuTMtmDjyN4doqO2IqFQ==} + peerDependencies: + '@nomicfoundation/hardhat-ethers': ^3.1.0 + '@nomicfoundation/hardhat-ignition': ^0.15.16 + '@nomicfoundation/ignition-core': ^0.15.15 + ethers: ^6.14.0 + hardhat: ^2.26.0 - '@types/babel__generator@7.27.0': - resolution: {integrity: sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==} + '@nomicfoundation/hardhat-ignition@0.15.16': + resolution: {integrity: sha512-T0JTnuib7QcpsWkHCPLT7Z6F483EjTdcdjb1e00jqS9zTGCPqinPB66LLtR/duDLdvgoiCVS6K8WxTQkA/xR1Q==} + peerDependencies: + '@nomicfoundation/hardhat-verify': ^2.1.0 + hardhat: ^2.26.0 - '@types/babel__template@7.4.4': - resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==} + '@nomicfoundation/hardhat-network-helpers@1.1.2': + resolution: {integrity: sha512-p7HaUVDbLj7ikFivQVNhnfMHUBgiHYMwQWvGn9AriieuopGOELIrwj2KjyM2a6z70zai5YKO264Vwz+3UFJZPQ==} + peerDependencies: + hardhat: ^2.26.0 - '@types/babel__traverse@7.28.0': - resolution: {integrity: sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==} + '@nomicfoundation/hardhat-toolbox@5.0.0': + resolution: {integrity: sha512-FnUtUC5PsakCbwiVNsqlXVIWG5JIb5CEZoSXbJUsEBun22Bivx2jhF1/q9iQbzuaGpJKFQyOhemPB2+XlEE6pQ==} + peerDependencies: + '@nomicfoundation/hardhat-chai-matchers': ^2.0.0 + '@nomicfoundation/hardhat-ethers': ^3.0.0 + '@nomicfoundation/hardhat-ignition-ethers': ^0.15.0 + '@nomicfoundation/hardhat-network-helpers': ^1.0.0 + '@nomicfoundation/hardhat-verify': ^2.0.0 + '@typechain/ethers-v6': ^0.5.0 + '@typechain/hardhat': ^9.0.0 + '@types/chai': ^4.2.0 + '@types/mocha': '>=9.1.0' + '@types/node': '>=18.0.0' + chai: ^4.2.0 + ethers: ^6.4.0 + hardhat: ^2.11.0 + hardhat-gas-reporter: ^1.0.8 + solidity-coverage: ^0.8.1 + ts-node: '>=8.0.0' + typechain: ^8.3.0 + typescript: '>=4.5.0' - '@types/bn.js@5.2.0': - resolution: {integrity: sha512-DLbJ1BPqxvQhIGbeu8VbUC1DiAiahHtAYvA0ZEAa4P31F7IaArc8z3C3BRQdWX4mtLQuABG4yzp76ZrS02Ui1Q==} + '@nomicfoundation/hardhat-verify@2.1.3': + resolution: {integrity: sha512-danbGjPp2WBhLkJdQy9/ARM3WQIK+7vwzE0urNem1qZJjh9f54Kf5f1xuQv8DvqewUAkuPxVt/7q4Grz5WjqSg==} + peerDependencies: + hardhat: ^2.26.0 - '@types/chai-as-promised@7.1.8': - resolution: {integrity: sha512-ThlRVIJhr69FLlh6IctTXFkmhtP3NpMZ2QGq69StYLyKZFp/HOp1VdKZj7RvfNWYYcJ1xlbLGLLWj1UvP5u/Gw==} + '@nomicfoundation/ignition-core@0.15.15': + resolution: {integrity: sha512-JdKFxYknTfOYtFXMN6iFJ1vALJPednuB+9p9OwGIRdoI6HYSh4ZBzyRURgyXtHFyaJ/SF9lBpsYV9/1zEpcYwg==} - '@types/chai@4.3.20': - resolution: {integrity: sha512-/pC9HAB5I/xMlc5FP77qjCnI16ChlJfW0tGa0IUcFn38VJrTV6DeZ60NU5KZBtaOZqjdpwTWohz5HU1RrhiYxQ==} + '@nomicfoundation/ignition-ui@0.15.13': + resolution: {integrity: sha512-HbTszdN1iDHCkUS9hLeooqnLEW2U45FaqFwFEYT8nIno2prFZhG+n68JEERjmfFCB5u0WgbuJwk3CgLoqtSL7Q==} - '@types/chai@5.2.3': - resolution: {integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==} + '@nomicfoundation/slang@0.18.3': + resolution: {integrity: sha512-YqAWgckqbHM0/CZxi9Nlf4hjk9wUNLC9ngWCWBiqMxPIZmzsVKYuChdlrfeBPQyvQQBoOhbx+7C1005kLVQDZQ==} - '@types/concat-stream@1.6.1': - resolution: {integrity: sha512-eHE4cQPoj6ngxBZMvVf6Hw7Mh4jMW4U9lpGmS5GBPB9RYxlFg+CHaVN7ErNY4W9XfLIEn20b4VDYaIrbq0q4uA==} + '@nomicfoundation/solidity-analyzer-darwin-arm64@0.1.2': + resolution: {integrity: sha512-JaqcWPDZENCvm++lFFGjrDd8mxtf+CtLd2MiXvMNTBD33dContTZ9TWETwNFwg7JTJT5Q9HEecH7FA+HTSsIUw==} + engines: {node: '>= 12'} - '@types/connect@3.4.38': - resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==} + '@nomicfoundation/solidity-analyzer-darwin-x64@0.1.2': + resolution: {integrity: sha512-fZNmVztrSXC03e9RONBT+CiksSeYcxI1wlzqyr0L7hsQlK1fzV+f04g2JtQ1c/Fe74ZwdV6aQBdd6Uwl1052sw==} + engines: {node: '>= 12'} - '@types/debug@4.1.12': - resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==} + '@nomicfoundation/solidity-analyzer-linux-arm64-gnu@0.1.2': + resolution: {integrity: sha512-3d54oc+9ZVBuB6nbp8wHylk4xh0N0Gc+bk+/uJae+rUgbOBwQSfuGIbAZt1wBXs5REkSmynEGcqx6DutoK0tPA==} + engines: {node: '>= 12'} - '@types/deep-eql@4.0.2': - resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==} + '@nomicfoundation/solidity-analyzer-linux-arm64-musl@0.1.2': + resolution: {integrity: sha512-iDJfR2qf55vgsg7BtJa7iPiFAsYf2d0Tv/0B+vhtnI16+wfQeTbP7teookbGvAo0eJo7aLLm0xfS/GTkvHIucA==} + engines: {node: '>= 12'} - '@types/estree@1.0.8': - resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} + '@nomicfoundation/solidity-analyzer-linux-x64-gnu@0.1.2': + resolution: {integrity: sha512-9dlHMAt5/2cpWyuJ9fQNOUXFB/vgSFORg1jpjX1Mh9hJ/MfZXlDdHQ+DpFCs32Zk5pxRBb07yGvSHk9/fezL+g==} + engines: {node: '>= 12'} - '@types/form-data@0.0.33': - resolution: {integrity: sha512-8BSvG1kGm83cyJITQMZSulnl6QV8jqAGreJsc5tPu1Jq0vTSOiY/k24Wx82JRpWwZSqrala6sd5rWi6aNXvqcw==} + '@nomicfoundation/solidity-analyzer-linux-x64-musl@0.1.2': + resolution: {integrity: sha512-GzzVeeJob3lfrSlDKQw2bRJ8rBf6mEYaWY+gW0JnTDHINA0s2gPR4km5RLIj1xeZZOYz4zRw+AEeYgLRqB2NXg==} + engines: {node: '>= 12'} - '@types/glob@7.2.0': - resolution: {integrity: sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==} + '@nomicfoundation/solidity-analyzer-win32-x64-msvc@0.1.2': + resolution: {integrity: sha512-Fdjli4DCcFHb4Zgsz0uEJXZ2K7VEO+w5KVv7HmT7WO10iODdU9csC2az4jrhEsRtiR9Gfd74FlG0NYlw1BMdyA==} + engines: {node: '>= 12'} - '@types/lodash@4.17.21': - resolution: {integrity: sha512-FOvQ0YPD5NOfPgMzJihoT+Za5pdkDJWcbpuj1DjaKZIr/gxodQjY/uWEFlTNqW2ugXHUiL8lRQgw63dzKHZdeQ==} + '@nomicfoundation/solidity-analyzer@0.1.2': + resolution: {integrity: sha512-q4n32/FNKIhQ3zQGGw5CvPF6GTvDCpYwIf7bEY/dZTZbgfDsHyjJwURxUJf3VQuuJj+fDIFl4+KkBVbw4Ef6jA==} + engines: {node: '>= 12'} - '@types/minimatch@6.0.0': - resolution: {integrity: sha512-zmPitbQ8+6zNutpwgcQuLcsEpn/Cj54Kbn7L5pX0Os5kdWplB7xPgEh/g+SWOB/qmows2gpuCaPyduq8ZZRnxA==} - deprecated: This is a stub types definition. minimatch provides its own type definitions, so you do not need this installed. + '@openzeppelin/community-contracts@https://codeload.github.com/OpenZeppelin/openzeppelin-community-contracts/tar.gz/a12b30ca7affe3320777378eddf2d0cebae8c5b2': + resolution: {tarball: https://codeload.github.com/OpenZeppelin/openzeppelin-community-contracts/tar.gz/a12b30ca7affe3320777378eddf2d0cebae8c5b2} + version: 0.0.1 - '@types/mocha@10.0.10': - resolution: {integrity: sha512-xPyYSz1cMPnJQhl0CLMH68j3gprKZaTjG3s5Vi+fDgx+uhG9NOXwbVt52eFS8ECyXhyKcjDLCBEqBExKuiZb7Q==} + '@openzeppelin/contracts-upgradeable@5.4.0': + resolution: {integrity: sha512-STJKyDzUcYuB35Zub1JpWW58JxvrFFVgQ+Ykdr8A9PGXgtq/obF5uoh07k2XmFyPxfnZdPdBdhkJ/n2YxJ87HQ==} + peerDependencies: + '@openzeppelin/contracts': 5.4.0 - '@types/ms@2.1.0': - resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==} + '@openzeppelin/contracts@3.4.2-solc-0.7': + resolution: {integrity: sha512-W6QmqgkADuFcTLzHL8vVoNBtkwjvQRpYIAom7KiUNoLKghyx3FgH0GBjt8NRvigV1ZmMOBllvE1By1C+bi8WpA==} - '@types/node@10.17.60': - resolution: {integrity: sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==} + '@openzeppelin/contracts@5.4.0': + resolution: {integrity: sha512-eCYgWnLg6WO+X52I16TZt8uEjbtdkgLC0SUX/xnAksjjrQI4Xfn4iBRoI5j55dmlOhDv1Y7BoR3cU7e3WWhC6A==} - '@types/node@12.20.55': - resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==} + '@openzeppelin/defender-sdk-base-client@2.7.0': + resolution: {integrity: sha512-J5IpvbFfdIJM4IadBcXfhCXVdX2yEpaZtRR1ecq87d8CdkmmEpniYfef/yVlG98yekvu125LaIRg0yXQOt9Bdg==} - '@types/node@20.19.27': - resolution: {integrity: sha512-N2clP5pJhB2YnZJ3PIHFk5RkygRX5WO/5f0WC08tp0wd+sv0rsJk3MqWn3CbNmT2J505a5336jaQj4ph1AdMug==} + '@openzeppelin/defender-sdk-deploy-client@2.7.0': + resolution: {integrity: sha512-YOHZmnHmM1y6uSqXWGfk2/5/ae4zZJE6xG92yFEAIOy8vqh1dxznWMsoCcAXRXTCWc8RdCDpFdMfEy4SBTyYtg==} - '@types/node@22.7.5': - resolution: {integrity: sha512-jML7s2NAzMWc//QSJ1a3prpk78cOPchGvXJsC3C6R6PSMoooztvRVQEz89gmBTBY1SPMaqo5teB4uNHPdetShQ==} + '@openzeppelin/defender-sdk-network-client@2.7.0': + resolution: {integrity: sha512-4CYWPa9+kSjojE5KS7kRmP161qsBATdp97TCrzyDdGoVahj0GyqgafRL9AAjm0eHZOM1c7EIYEpbvYRtFi8vyA==} - '@types/node@8.10.66': - resolution: {integrity: sha512-tktOkFUA4kXx2hhhrB8bIFb5TbwzS4uOhKEmwiD+NoiL0qtP2OQ9mFldbgD4dV1djrlBYP6eBuQZiWjuHUpqFw==} - - '@types/pbkdf2@3.1.2': - resolution: {integrity: sha512-uRwJqmiXmh9++aSu1VNEn3iIxWOhd8AHXNSdlaLfdAAdSTY9jYVeGWnzejM3dvrkbqE3/hyQkQQ29IFATEGlew==} - - '@types/prettier@2.7.3': - resolution: {integrity: sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA==} - - '@types/prop-types@15.7.15': - resolution: {integrity: sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==} - - '@types/qs@6.14.0': - resolution: {integrity: sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ==} - - '@types/react-dom@18.3.7': - resolution: {integrity: sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ==} + '@openzeppelin/hardhat-upgrades@3.9.1': + resolution: {integrity: sha512-pSDjlOnIpP+PqaJVe144dK6VVKZw2v6YQusyt0OOLiCsl+WUzfo4D0kylax7zjrOxqy41EK2ipQeIF4T+cCn2A==} + hasBin: true peerDependencies: - '@types/react': ^18.0.0 + '@nomicfoundation/hardhat-ethers': ^3.0.6 + '@nomicfoundation/hardhat-verify': ^2.0.14 + ethers: ^6.6.0 + hardhat: ^2.24.1 + peerDependenciesMeta: + '@nomicfoundation/hardhat-verify': + optional: true - '@types/react@18.3.27': - resolution: {integrity: sha512-cisd7gxkzjBKU2GgdYrTdtQx1SORymWyaAFhaxQPK9bYO9ot3Y5OikQRvY0VYQtvwjeQnizCINJAenh/V7MK2w==} + '@openzeppelin/upgrades-core@1.44.2': + resolution: {integrity: sha512-m6iorjyhPK9ow5/trNs7qsBC/SOzJCO51pvvAF2W9nOiZ1t0RtCd+rlRmRmlWTv4M33V0wzIUeamJ2BPbzgUXA==} + hasBin: true - '@types/secp256k1@4.0.7': - resolution: {integrity: sha512-Rcvjl6vARGAKRO6jHeKMatGrvOMGrR/AR11N1x2LqintPCyDZ7NBhrh238Z2VZc7aM7KIwnFpFQ7fnfK4H/9Qw==} + '@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' - '@types/trusted-types@2.0.7': - resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==} + '@peculiar/asn1-cms@2.6.0': + resolution: {integrity: sha512-2uZqP+ggSncESeUF/9Su8rWqGclEfEiz1SyU02WX5fUONFfkjzS2Z/F1Li0ofSmf4JqYXIOdCAZqIXAIBAT1OA==} - '@types/uuid@8.3.4': - resolution: {integrity: sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw==} + '@peculiar/asn1-csr@2.6.0': + resolution: {integrity: sha512-BeWIu5VpTIhfRysfEp73SGbwjjoLL/JWXhJ/9mo4vXnz3tRGm+NGm3KNcRzQ9VMVqwYS2RHlolz21svzRXIHPQ==} - '@types/ws@7.4.7': - resolution: {integrity: sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww==} + '@peculiar/asn1-ecc@2.6.0': + resolution: {integrity: sha512-FF3LMGq6SfAOwUG2sKpPXblibn6XnEIKa+SryvUl5Pik+WR9rmRA3OCiwz8R3lVXnYnyRkSZsSLdml8H3UiOcw==} - '@types/ws@8.18.1': - resolution: {integrity: sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==} + '@peculiar/asn1-pfx@2.6.0': + resolution: {integrity: sha512-rtUvtf+tyKGgokHHmZzeUojRZJYPxoD/jaN1+VAB4kKR7tXrnDCA/RAWXAIhMJJC+7W27IIRGe9djvxKgsldCQ==} - '@uniswap/lib@4.0.1-alpha': - resolution: {integrity: sha512-f6UIliwBbRsgVLxIaBANF6w09tYqc6Y/qXdsrbEmXHyFA7ILiKrIwRFXe1yOg8M3cksgVsO9N7yuL2DdCGQKBA==} - engines: {node: '>=10'} + '@peculiar/asn1-pkcs8@2.6.0': + resolution: {integrity: sha512-KyQ4D8G/NrS7Fw3XCJrngxmjwO/3htnA0lL9gDICvEQ+GJ+EPFqldcJQTwPIdvx98Tua+WjkdKHSC0/Km7T+lA==} - '@uniswap/v2-core@1.0.1': - resolution: {integrity: sha512-MtybtkUPSyysqLY2U210NBDeCHX+ltHt3oADGdjqoThZaFRDKwM6k1Nb3F0A3hk5hwuQvytFWhrWHOEq6nVJ8Q==} - engines: {node: '>=10'} + '@peculiar/asn1-pkcs9@2.6.0': + resolution: {integrity: sha512-b78OQ6OciW0aqZxdzliXGYHASeCvvw5caqidbpQRYW2mBtXIX2WhofNXTEe7NyxTb0P6J62kAAWLwn0HuMF1Fw==} - '@uniswap/v3-core@1.0.1': - resolution: {integrity: sha512-7pVk4hEm00j9tc71Y9+ssYpO6ytkeI0y7WE9P6UcmNzhxPePwyAxImuhVsTqWK9YFvzgtvzJHi64pBl4jUzKMQ==} - engines: {node: '>=10'} + '@peculiar/asn1-rsa@2.6.0': + resolution: {integrity: sha512-Nu4C19tsrTsCp9fDrH+sdcOKoVfdfoQQ7S3VqjJU6vedR7tY3RLkQ5oguOIB3zFW33USDUuYZnPEQYySlgha4w==} - '@uniswap/v3-periphery@1.4.4': - resolution: {integrity: sha512-S4+m+wh8HbWSO3DKk4LwUCPZJTpCugIsHrWR86m/OrUyvSqGDTXKFfc2sMuGXCZrD1ZqO3rhQsKgdWg3Hbb2Kw==} - engines: {node: '>=10'} + '@peculiar/asn1-schema@2.6.0': + resolution: {integrity: sha512-xNLYLBFTBKkCzEZIw842BxytQQATQv+lDTCEMZ8C196iJcJJMBUZxrhSTxLaohMyKK8QlzRNTRkUmanucnDSqg==} - '@vanilla-extract/css@1.17.3': - resolution: {integrity: sha512-jHivr1UPoJTX5Uel4AZSOwrCf4mO42LcdmnhJtUxZaRWhW4FviFbIfs0moAWWld7GOT+2XnuVZjjA/K32uUnMQ==} + '@peculiar/asn1-x509-attr@2.6.0': + resolution: {integrity: sha512-MuIAXFX3/dc8gmoZBkwJWxUWOSvG4MMDntXhrOZpJVMkYX+MYc/rUAU2uJOved9iJEoiUx7//3D8oG83a78UJA==} - '@vanilla-extract/dynamic@2.1.4': - resolution: {integrity: sha512-7+Ot7VlP3cIzhJnTsY/kBtNs21s0YD7WI1rKJJKYP56BkbDxi/wrQUWMGEczKPUDkJuFcvbye+E2ub1u/mHH9w==} + '@peculiar/asn1-x509@2.6.0': + resolution: {integrity: sha512-uzYbPEpoQiBoTq0/+jZtpM6Gq6zADBx+JNFP3yqRgziWBxQ/Dt/HcuvRfm9zJTPdRcBqPNdaRHTVwpyiq6iNMA==} - '@vanilla-extract/private@1.0.9': - resolution: {integrity: sha512-gT2jbfZuaaCLrAxwXbRgIhGhcXbRZCG3v4TTUnjw0EJ7ArdBRxkq4msNJkbuRkCgfIK5ATmprB5t9ljvLeFDEA==} + '@peculiar/x509@1.14.3': + resolution: {integrity: sha512-C2Xj8FZ0uHWeCXXqX5B4/gVFQmtSkiuOolzAgutjTfseNOHT3pUjljDZsTSxXFGgio54bCzVFqmEOUrIVk8RDA==} + engines: {node: '>=20.0.0'} - '@vanilla-extract/sprinkles@1.6.4': - resolution: {integrity: sha512-lW3MuIcdIeHKX81DzhTnw68YJdL1ial05exiuvTLJMdHXQLKcVB93AncLPajMM6mUhaVVx5ALZzNHMTrq/U9Hg==} - peerDependencies: - '@vanilla-extract/css': ^1.0.0 + '@pnpm/config.env-replace@1.1.0': + resolution: {integrity: sha512-htyl8TWnKL7K/ESFa1oW2UB5lVDxuF5DpM7tBi6Hu2LNL3mWkIzNLG6N4zoCUP1lCKNxWy/3iu8mS8MvToGd6w==} + engines: {node: '>=12.22.0'} - '@vitejs/plugin-react@4.7.0': - resolution: {integrity: sha512-gUu9hwfWvvEDBBmgtAowQCojwZmJ5mcLn3aufeCsitijs3+f2NsrPtlAWIR6OPiqljl96GVCUbLe0HyqIpVaoA==} - engines: {node: ^14.18.0 || >=16.0.0} - peerDependencies: - vite: ^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 + '@pnpm/network.ca-file@1.0.2': + resolution: {integrity: sha512-YcPQ8a0jwYU9bTdJDpXjMi7Brhkr1mXsXrUJvjqM2mQDgkRiz8jFaQGOdaLxgjtUfQgZhKy/O3cG/YwmgKaxLA==} + engines: {node: '>=12.22.0'} - '@vitest/expect@3.2.4': - resolution: {integrity: sha512-Io0yyORnB6sikFlt8QW5K7slY4OjqNX9jmJQ02QDda8lyM6B5oNgVWoSoKPac8/kgnCUzuHQKrSLtu/uOqqrig==} + '@pnpm/npm-conf@3.0.2': + resolution: {integrity: sha512-h104Kh26rR8tm+a3Qkc5S4VLYint3FE48as7+/5oCEcKR2idC/pF1G6AhIXKI+eHPJa/3J9i5z0Al47IeGHPkA==} + engines: {node: '>=12'} - '@vitest/mocker@3.2.4': - resolution: {integrity: sha512-46ryTE9RZO/rfDd7pEqFl7etuyzekzEhUbTW3BvmeO/BcCMEgq59BKhek3dXDWgAj4oMK6OZi+vRr1wPW6qjEQ==} + '@polka/url@1.0.0-next.29': + resolution: {integrity: sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==} + + '@rainbow-me/rainbowkit@2.2.10': + resolution: {integrity: sha512-8+E4die1A2ovN9t3lWxWnwqTGEdFqThXDQRj+E4eDKuUKyymYD+66Gzm6S9yfg8E95c6hmGlavGUfYPtl1EagA==} + engines: {node: '>=12.4'} peerDependencies: - msw: ^2.4.9 - vite: ^5.0.0 || ^6.0.0 || ^7.0.0-0 - peerDependenciesMeta: - msw: - optional: true - vite: - optional: true + '@tanstack/react-query': '>=5.0.0' + react: '>=18' + react-dom: '>=18' + viem: 2.x + wagmi: ^2.9.0 - '@vitest/pretty-format@3.2.4': - resolution: {integrity: sha512-IVNZik8IVRJRTr9fxlitMKeJeXFFFN0JaB9PHPGQ8NKQbGpfjlTx9zO4RefN8gp7eqjNy8nyK3NZmBzOPeIxtA==} + '@reown/appkit-common@1.7.8': + resolution: {integrity: sha512-ridIhc/x6JOp7KbDdwGKY4zwf8/iK8EYBl+HtWrruutSLwZyVi5P8WaZa+8iajL6LcDcDF7LoyLwMTym7SRuwQ==} - '@vitest/runner@3.2.4': - resolution: {integrity: sha512-oukfKT9Mk41LreEW09vt45f8wx7DordoWUZMYdY/cyAk7w5TWkTRCNZYF7sX7n2wB7jyGAl74OxgwhPgKaqDMQ==} + '@reown/appkit-controllers@1.7.8': + resolution: {integrity: sha512-IdXlJlivrlj6m63VsGLsjtPHHsTWvKGVzWIP1fXZHVqmK+rZCBDjCi9j267Rb9/nYRGHWBtlFQhO8dK35WfeDA==} - '@vitest/snapshot@3.2.4': - resolution: {integrity: sha512-dEYtS7qQP2CjU27QBC5oUOxLE/v5eLkGqPE0ZKEIDGMs4vKWe7IjgLOeauHsR0D5YuuycGRO5oSRXnwnmA78fQ==} + '@reown/appkit-pay@1.7.8': + resolution: {integrity: sha512-OSGQ+QJkXx0FEEjlpQqIhT8zGJKOoHzVnyy/0QFrl3WrQTjCzg0L6+i91Ad5Iy1zb6V5JjqtfIFpRVRWN4M3pw==} - '@vitest/spy@3.2.4': - resolution: {integrity: sha512-vAfasCOe6AIK70iP5UD11Ac4siNUNJ9i/9PZ3NKx07sG6sUxeag1LWdNrMWeKKYBLlzuK+Gn65Yd5nyL6ds+nw==} + '@reown/appkit-polyfills@1.7.8': + resolution: {integrity: sha512-W/kq786dcHHAuJ3IV2prRLEgD/2iOey4ueMHf1sIFjhhCGMynMkhsOhQMUH0tzodPqUgAC494z4bpIDYjwWXaA==} - '@vitest/utils@3.2.4': - resolution: {integrity: sha512-fB2V0JFrQSMsCo9HiSq3Ezpdv4iYaXRG1Sx8edX3MwxfyNn83mKiGzOcH+Fkxt4MHxr3y42fQi1oeAInqgX2QA==} + '@reown/appkit-scaffold-ui@1.7.8': + resolution: {integrity: sha512-RCeHhAwOrIgcvHwYlNWMcIDibdI91waaoEYBGw71inE0kDB8uZbE7tE6DAXJmDkvl0qPh+DqlC4QbJLF1FVYdQ==} - '@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 + '@reown/appkit-ui@1.7.8': + resolution: {integrity: sha512-1hjCKjf6FLMFzrulhl0Y9Vb9Fu4royE+SXCPSWh4VhZhWqlzUFc7kutnZKx8XZFVQH4pbBvY62SpRC93gqoHow==} - '@wagmi/core@2.22.1': - resolution: {integrity: sha512-cG/xwQWsBEcKgRTkQVhH29cbpbs/TdcUJVFXCyri3ZknxhMyGv0YEjTcrNpRgt2SaswL1KrvslSNYKKo+5YEAg==} + '@reown/appkit-utils@1.7.8': + resolution: {integrity: sha512-8X7UvmE8GiaoitCwNoB86pttHgQtzy4ryHZM9kQpvjQ0ULpiER44t1qpVLXNM4X35O0v18W0Dk60DnYRMH2WRw==} peerDependencies: - '@tanstack/query-core': '>=5.0.0' - typescript: '>=5.0.4' - viem: 2.x - peerDependenciesMeta: - '@tanstack/query-core': - optional: true - typescript: - optional: true + valtio: 1.13.2 - '@walletconnect/core@2.21.0': - resolution: {integrity: sha512-o6R7Ua4myxR8aRUAJ1z3gT9nM+jd2B2mfamu6arzy1Cc6vi10fIwFWb6vg3bC8xJ6o9H3n/cN5TOW3aA9Y1XVw==} - engines: {node: '>=18'} + '@reown/appkit-wallet@1.7.8': + resolution: {integrity: sha512-kspz32EwHIOT/eg/ZQbFPxgXq0B/olDOj3YMu7gvLEFz4xyOFd/wgzxxAXkp5LbG4Cp++s/elh79rVNmVFdB9A==} - '@walletconnect/core@2.21.1': - resolution: {integrity: sha512-Tp4MHJYcdWD846PH//2r+Mu4wz1/ZU/fr9av1UWFiaYQ2t2TPLDiZxjLw54AAEpMqlEHemwCgiRiAmjR1NDdTQ==} - engines: {node: '>=18'} + '@reown/appkit@1.7.8': + resolution: {integrity: sha512-51kTleozhA618T1UvMghkhKfaPcc9JlKwLJ5uV+riHyvSoWPKPRIa5A6M1Wano5puNyW0s3fwywhyqTHSilkaA==} - '@walletconnect/environment@1.0.1': - resolution: {integrity: sha512-T426LLZtHj8e8rYnKfzsw1aG6+M0BT1ZxayMdv/p8yM0MU+eJDISqNY3/bccxRr4LrF9csq02Rhqt08Ibl0VRg==} + '@rolldown/pluginutils@1.0.0-beta.27': + resolution: {integrity: sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA==} - '@walletconnect/ethereum-provider@2.21.1': - resolution: {integrity: sha512-SSlIG6QEVxClgl1s0LMk4xr2wg4eT3Zn/Hb81IocyqNSGfXpjtawWxKxiC5/9Z95f1INyBD6MctJbL/R1oBwIw==} + '@rollup/rollup-android-arm-eabi@4.53.5': + resolution: {integrity: sha512-iDGS/h7D8t7tvZ1t6+WPK04KD0MwzLZrG0se1hzBjSi5fyxlsiggoJHwh18PCFNn7tG43OWb6pdZ6Y+rMlmyNQ==} + cpu: [arm] + os: [android] - '@walletconnect/events@1.0.1': - resolution: {integrity: sha512-NPTqaoi0oPBVNuLv7qPaJazmGHs5JGyO8eEAk5VGKmJzDR7AHzD4k6ilox5kxk1iwiOnFopBOOMLs86Oa76HpQ==} + '@rollup/rollup-android-arm64@4.53.5': + resolution: {integrity: sha512-wrSAViWvZHBMMlWk6EJhvg8/rjxzyEhEdgfMMjREHEq11EtJ6IP6yfcCH57YAEca2Oe3FNCE9DSTgU70EIGmVw==} + cpu: [arm64] + os: [android] - '@walletconnect/heartbeat@1.2.2': - resolution: {integrity: sha512-uASiRmC5MwhuRuf05vq4AT48Pq8RMi876zV8rr8cV969uTOzWdB/k+Lj5yI2PBtB1bGQisGen7MM1GcZlQTBXw==} + '@rollup/rollup-darwin-arm64@4.53.5': + resolution: {integrity: sha512-S87zZPBmRO6u1YXQLwpveZm4JfPpAa6oHBX7/ghSiGH3rz/KDgAu1rKdGutV+WUI6tKDMbaBJomhnT30Y2t4VQ==} + cpu: [arm64] + os: [darwin] - '@walletconnect/jsonrpc-http-connection@1.0.8': - resolution: {integrity: sha512-+B7cRuaxijLeFDJUq5hAzNyef3e3tBDIxyaCNmFtjwnod5AGis3RToNqzFU33vpVcxFhofkpE7Cx+5MYejbMGw==} + '@rollup/rollup-darwin-x64@4.53.5': + resolution: {integrity: sha512-YTbnsAaHo6VrAczISxgpTva8EkfQus0VPEVJCEaboHtZRIb6h6j0BNxRBOwnDciFTZLDPW5r+ZBmhL/+YpTZgA==} + cpu: [x64] + os: [darwin] - '@walletconnect/jsonrpc-provider@1.0.14': - resolution: {integrity: sha512-rtsNY1XqHvWj0EtITNeuf8PHMvlCLiS3EjQL+WOkxEOA4KPxsohFnBDeyPYiNm4ZvkQdLnece36opYidmtbmow==} + '@rollup/rollup-freebsd-arm64@4.53.5': + resolution: {integrity: sha512-1T8eY2J8rKJWzaznV7zedfdhD1BqVs1iqILhmHDq/bqCUZsrMt+j8VCTHhP0vdfbHK3e1IQ7VYx3jlKqwlf+vw==} + cpu: [arm64] + os: [freebsd] - '@walletconnect/jsonrpc-types@1.0.4': - resolution: {integrity: sha512-P6679fG/M+wuWg9TY8mh6xFSdYnFyFjwFelxyISxMDrlbXokorEVXYOxiqEbrU3x1BmBoCAJJ+vtEaEoMlpCBQ==} + '@rollup/rollup-freebsd-x64@4.53.5': + resolution: {integrity: sha512-sHTiuXyBJApxRn+VFMaw1U+Qsz4kcNlxQ742snICYPrY+DDL8/ZbaC4DVIB7vgZmp3jiDaKA0WpBdP0aqPJoBQ==} + cpu: [x64] + os: [freebsd] - '@walletconnect/jsonrpc-utils@1.0.8': - resolution: {integrity: sha512-vdeb03bD8VzJUL6ZtzRYsFMq1eZQcM3EAzT0a3st59dyLfJ0wq+tKMpmGH7HlB7waD858UWgfIcudbPFsbzVdw==} + '@rollup/rollup-linux-arm-gnueabihf@4.53.5': + resolution: {integrity: sha512-dV3T9MyAf0w8zPVLVBptVlzaXxka6xg1f16VAQmjg+4KMSTWDvhimI/Y6mp8oHwNrmnmVl9XxJ/w/mO4uIQONA==} + cpu: [arm] + os: [linux] - '@walletconnect/jsonrpc-ws-connection@1.0.16': - resolution: {integrity: sha512-G81JmsMqh5nJheE1mPst1W0WfVv0SG3N7JggwLLGnI7iuDZJq8cRJvQwLGKHn5H1WTW7DEPCo00zz5w62AbL3Q==} + '@rollup/rollup-linux-arm-musleabihf@4.53.5': + resolution: {integrity: sha512-wIGYC1x/hyjP+KAu9+ewDI+fi5XSNiUi9Bvg6KGAh2TsNMA3tSEs+Sh6jJ/r4BV/bx/CyWu2ue9kDnIdRyafcQ==} + cpu: [arm] + os: [linux] - '@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 + '@rollup/rollup-linux-arm64-gnu@4.53.5': + resolution: {integrity: sha512-Y+qVA0D9d0y2FRNiG9oM3Hut/DgODZbU9I8pLLPwAsU0tUKZ49cyV1tzmB/qRbSzGvY8lpgGkJuMyuhH7Ma+Vg==} + cpu: [arm64] + os: [linux] - '@walletconnect/logger@2.1.2': - resolution: {integrity: sha512-aAb28I3S6pYXZHQm5ESB+V6rDqIYfsnHaQyzFbwUUBFY4H0OXx/YtTl8lvhUNhMMfb9UxbwEBS253TlXUYJWSw==} + '@rollup/rollup-linux-arm64-musl@4.53.5': + resolution: {integrity: sha512-juaC4bEgJsyFVfqhtGLz8mbopaWD+WeSOYr5E16y+1of6KQjc0BpwZLuxkClqY1i8sco+MdyoXPNiCkQou09+g==} + cpu: [arm64] + os: [linux] - '@walletconnect/relay-api@1.0.11': - resolution: {integrity: sha512-tLPErkze/HmC9aCmdZOhtVmYZq1wKfWTJtygQHoWtgg722Jd4homo54Cs4ak2RUFUZIGO2RsOpIcWipaua5D5Q==} + '@rollup/rollup-linux-loong64-gnu@4.53.5': + resolution: {integrity: sha512-rIEC0hZ17A42iXtHX+EPJVL/CakHo+tT7W0pbzdAGuWOt2jxDFh7A/lRhsNHBcqL4T36+UiAgwO8pbmn3dE8wA==} + cpu: [loong64] + os: [linux] - '@walletconnect/relay-auth@1.1.0': - resolution: {integrity: sha512-qFw+a9uRz26jRCDgL7Q5TA9qYIgcNY8jpJzI1zAWNZ8i7mQjaijRnWFKsCHAU9CyGjvt6RKrRXyFtFOpWTVmCQ==} + '@rollup/rollup-linux-ppc64-gnu@4.53.5': + resolution: {integrity: sha512-T7l409NhUE552RcAOcmJHj3xyZ2h7vMWzcwQI0hvn5tqHh3oSoclf9WgTl+0QqffWFG8MEVZZP1/OBglKZx52Q==} + cpu: [ppc64] + os: [linux] - '@walletconnect/safe-json@1.0.2': - resolution: {integrity: sha512-Ogb7I27kZ3LPC3ibn8ldyUr5544t3/STow9+lzz7Sfo808YD7SBWk7SAsdBFlYgP2zDRy2hS3sKRcuSRM0OTmA==} + '@rollup/rollup-linux-riscv64-gnu@4.53.5': + resolution: {integrity: sha512-7OK5/GhxbnrMcxIFoYfhV/TkknarkYC1hqUw1wU2xUN3TVRLNT5FmBv4KkheSG2xZ6IEbRAhTooTV2+R5Tk0lQ==} + cpu: [riscv64] + os: [linux] - '@walletconnect/sign-client@2.21.0': - resolution: {integrity: sha512-z7h+PeLa5Au2R591d/8ZlziE0stJvdzP9jNFzFolf2RG/OiXulgFKum8PrIyXy+Rg2q95U9nRVUF9fWcn78yBA==} + '@rollup/rollup-linux-riscv64-musl@4.53.5': + resolution: {integrity: sha512-GwuDBE/PsXaTa76lO5eLJTyr2k8QkPipAyOrs4V/KJufHCZBJ495VCGJol35grx9xryk4V+2zd3Ri+3v7NPh+w==} + cpu: [riscv64] + os: [linux] - '@walletconnect/sign-client@2.21.1': - resolution: {integrity: sha512-QaXzmPsMnKGV6tc4UcdnQVNOz4zyXgarvdIQibJ4L3EmLat73r5ZVl4c0cCOcoaV7rgM9Wbphgu5E/7jNcd3Zg==} + '@rollup/rollup-linux-s390x-gnu@4.53.5': + resolution: {integrity: sha512-IAE1Ziyr1qNfnmiQLHBURAD+eh/zH1pIeJjeShleII7Vj8kyEm2PF77o+lf3WTHDpNJcu4IXJxNO0Zluro8bOw==} + cpu: [s390x] + os: [linux] - '@walletconnect/time@1.0.2': - resolution: {integrity: sha512-uzdd9woDcJ1AaBZRhqy5rNC9laqWGErfc4dxA9a87mPdKOgWMD85mcFo9dIYIts/Jwocfwn07EC6EzclKubk/g==} + '@rollup/rollup-linux-x64-gnu@4.53.5': + resolution: {integrity: sha512-Pg6E+oP7GvZ4XwgRJBuSXZjcqpIW3yCBhK4BcsANvb47qMvAbCjR6E+1a/U2WXz1JJxp9/4Dno3/iSJLcm5auw==} + cpu: [x64] + os: [linux] - '@walletconnect/types@2.21.0': - resolution: {integrity: sha512-ll+9upzqt95ZBWcfkOszXZkfnpbJJ2CmxMfGgE5GmhdxxxCcO5bGhXkI+x8OpiS555RJ/v/sXJYMSOLkmu4fFw==} + '@rollup/rollup-linux-x64-musl@4.53.5': + resolution: {integrity: sha512-txGtluxDKTxaMDzUduGP0wdfng24y1rygUMnmlUJ88fzCCULCLn7oE5kb2+tRB+MWq1QDZT6ObT5RrR8HFRKqg==} + cpu: [x64] + os: [linux] - '@walletconnect/types@2.21.1': - resolution: {integrity: sha512-UeefNadqP6IyfwWC1Yi7ux+ljbP2R66PLfDrDm8izmvlPmYlqRerJWJvYO4t0Vvr9wrG4Ko7E0c4M7FaPKT/sQ==} + '@rollup/rollup-openharmony-arm64@4.53.5': + resolution: {integrity: sha512-3DFiLPnTxiOQV993fMc+KO8zXHTcIjgaInrqlG8zDp1TlhYl6WgrOHuJkJQ6M8zHEcntSJsUp1XFZSY8C1DYbg==} + cpu: [arm64] + os: [openharmony] - '@walletconnect/universal-provider@2.21.0': - resolution: {integrity: sha512-mtUQvewt+X0VBQay/xOJBvxsB3Xsm1lTwFjZ6WUwSOTR1X+FNb71hSApnV5kbsdDIpYPXeQUbGt2se1n5E5UBg==} + '@rollup/rollup-win32-arm64-msvc@4.53.5': + resolution: {integrity: sha512-nggc/wPpNTgjGg75hu+Q/3i32R00Lq1B6N1DO7MCU340MRKL3WZJMjA9U4K4gzy3dkZPXm9E1Nc81FItBVGRlA==} + cpu: [arm64] + os: [win32] - '@walletconnect/universal-provider@2.21.1': - resolution: {integrity: sha512-Wjx9G8gUHVMnYfxtasC9poGm8QMiPCpXpbbLFT+iPoQskDDly8BwueWnqKs4Mx2SdIAWAwuXeZ5ojk5qQOxJJg==} + '@rollup/rollup-win32-ia32-msvc@4.53.5': + resolution: {integrity: sha512-U/54pTbdQpPLBdEzCT6NBCFAfSZMvmjr0twhnD9f4EIvlm9wy3jjQ38yQj1AGznrNO65EWQMgm/QUjuIVrYF9w==} + cpu: [ia32] + os: [win32] - '@walletconnect/utils@2.21.0': - resolution: {integrity: sha512-zfHLiUoBrQ8rP57HTPXW7rQMnYxYI4gT9yTACxVW6LhIFROTF6/ytm5SKNoIvi4a5nX5dfXG4D9XwQUCu8Ilig==} + '@rollup/rollup-win32-x64-gnu@4.53.5': + resolution: {integrity: sha512-2NqKgZSuLH9SXBBV2dWNRCZmocgSOx8OJSdpRaEcRlIfX8YrKxUT6z0F1NpvDVhOsl190UFTRh2F2WDWWCYp3A==} + cpu: [x64] + os: [win32] - '@walletconnect/utils@2.21.1': - resolution: {integrity: sha512-VPZvTcrNQCkbGOjFRbC24mm/pzbRMUq2DSQoiHlhh0X1U7ZhuIrzVtAoKsrzu6rqjz0EEtGxCr3K1TGRqDG4NA==} + '@rollup/rollup-win32-x64-msvc@4.53.5': + resolution: {integrity: sha512-JRpZUhCfhZ4keB5v0fe02gQJy05GqboPOaxvjugW04RLSYYoB/9t2lx2u/tMs/Na/1NXfY8QYjgRljRpN+MjTQ==} + cpu: [x64] + os: [win32] - '@walletconnect/window-getters@1.0.1': - resolution: {integrity: sha512-vHp+HqzGxORPAN8gY03qnbTMnhqIwjeRJNOMOAzePRg4xVEEE2WvYsI9G2NMjOknA8hnuYbU3/hwLcKbjhc8+Q==} + '@safe-global/api-kit@4.0.1': + resolution: {integrity: sha512-pNtDLgMHlCSr4Hwwe6jsnvMheAu2SZCTqjYlnNe4cKH2pSKINVRTiILoeJ0wOpixrMCH4NlgJ+9N3QruRNcCpQ==} - '@walletconnect/window-metadata@1.0.1': - resolution: {integrity: sha512-9koTqyGrM2cqFRW517BPY/iEtUDx2r1+Pwwu5m7sJ7ka79wi3EyqhqcICk/yDmv6jAS1rjKgTKXlEhanYjijcA==} + '@safe-global/protocol-kit@6.1.2': + resolution: {integrity: sha512-cTpPdUAS2AMfGCkD1T601rQNjT0rtMQLA2TH7L/C+iFPAC6WrrDFop2B9lzeHjczlnVzrRpfFe4cL1bLrJ9NZw==} - abbrev@1.0.9: - resolution: {integrity: sha512-LEyx4aLEC3x6T0UguF6YILf+ntvmOaWsVfENmIW0E9H09vKlLDGelMjjSm0jkDHALj8A8quZ/HapKNigzwge+Q==} + '@safe-global/safe-apps-provider@0.18.6': + resolution: {integrity: sha512-4LhMmjPWlIO8TTDC2AwLk44XKXaK6hfBTWyljDm0HQ6TWlOEijVWNrt2s3OCVMSxlXAcEzYfqyu1daHZooTC2Q==} - 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 + '@safe-global/safe-apps-sdk@9.1.0': + resolution: {integrity: sha512-N5p/ulfnnA2Pi2M3YeWjULeWbjo7ei22JwU/IXnhoHzKq3pYCN6ynL9mJBOlvDVv892EgLPCWCOwQk/uBT2v0Q==} - 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 + '@safe-global/safe-deployments@1.37.49': + resolution: {integrity: sha512-132QgqMY1/HktXqmda/uPp5b+73UXTgKRB00Xgc1kduFqceSw/ZyF1Q9jJjbND9q91hhapnXhYKWN2/HiWkRcg==} - abitype@1.2.3: - resolution: {integrity: sha512-Ofer5QUnuUdTFsBRwARMoWKOH1ND5ehwYhJ3OJ/BQO+StkwQjHw0XyVh4vDttzHB7QOFhPHa/o413PJ82gU/Tg==} - peerDependencies: - typescript: '>=5.0.4' - zod: ^3.22.0 || ^4.0.0 - peerDependenciesMeta: - typescript: - optional: true - zod: - optional: true + '@safe-global/safe-gateway-typescript-sdk@3.23.1': + resolution: {integrity: sha512-6ORQfwtEJYpalCeVO21L4XXGSdbEMfyp2hEv6cP82afKXSwvse6d3sdelgaPWUxHIsFRkWvHDdzh8IyyKHZKxw==} + engines: {node: '>=16'} - acorn-walk@8.3.4: - resolution: {integrity: sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==} - engines: {node: '>=0.4.0'} + '@safe-global/safe-modules-deployments@2.2.21': + resolution: {integrity: sha512-fveOlRv0ccwsuaZjP1u7ZbXrwCyqMTYYiqETOGo8NdzTaceRUyR9TNzagSWovOSuHPVyUGJ9lnsxizikt/+PiQ==} - acorn@8.15.0: - resolution: {integrity: sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==} - engines: {node: '>=0.4.0'} - hasBin: true + '@safe-global/types-kit@3.0.0': + resolution: {integrity: sha512-AZWIlR5MguDPdGiOj7BB4JQPY2afqmWQww1mu8m8Oi16HHBW99G01kFOu4NEHBwEU1cgwWOMY19hsI5KyL4W2w==} - adm-zip@0.4.16: - resolution: {integrity: sha512-TFi4HBKSGfIKsK5YCkKaaFG2m4PEDyViZmEwof3MTIgzimHLto6muaHVpbrljdIvIrFZzEq/p4nafOeLcYegrg==} - engines: {node: '>=0.3.0'} + '@scure/base@1.1.9': + resolution: {integrity: sha512-8YKhl8GHiNI/pU2VMaofa2Tor7PJRAjwQLBBuilkJ9L5+13yVbC7JO/wS7piioAvPSwR3JKM1IJ/u4xQzbcXKg==} - aes-js@3.0.0: - resolution: {integrity: sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw==} + '@scure/base@1.2.6': + resolution: {integrity: sha512-g/nm5FgUa//MCj1gV09zTJTaM6KBAHqLN907YVQqf7zC49+DcO4B1so4ZX07Ef10Twr6nuqYEH9GEggFXA4Fmg==} - aes-js@4.0.0-beta.5: - resolution: {integrity: sha512-G965FqalsNyrPqgEGON7nIx1e/OVENSgiEIzyC63haUMuvNnwIgIjMs52hlTCKhkBny7A2ORNlfY9Zu+jmGk1Q==} + '@scure/bip32@1.1.5': + resolution: {integrity: sha512-XyNh1rB0SkEqd3tXcXMi+Xe1fvg+kUIcoRIEujP1Jgv7DqW2r9lg3Ah0NkFaCs9sTkQAQA8kw7xiRXzENi9Rtw==} - agent-base@6.0.2: - resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} - engines: {node: '>= 6.0.0'} + '@scure/bip32@1.4.0': + resolution: {integrity: sha512-sVUpc0Vq3tXCkDGYVWGIZTRfnvu8LoTDaev7vbwh0omSvVORONr960MQWdKqJDCReIEmTj3PAr73O3aoxz7OPg==} - agentkeepalive@4.6.0: - resolution: {integrity: sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ==} - engines: {node: '>= 8.0.0'} + '@scure/bip32@1.6.2': + resolution: {integrity: sha512-t96EPDMbtGgtb7onKKqxRLfE5g05k7uHnHRM2xdE6BP/ZmxaLtPek4J4KfVn/90IQNrU1IOAqMgiDtUdtbe3nw==} - aggregate-error@3.1.0: - resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==} - engines: {node: '>=8'} + '@scure/bip32@1.7.0': + resolution: {integrity: sha512-E4FFX/N3f4B80AKWp5dP6ow+flD1LQZo/w8UnLGYZO674jS6YnYeepycOOksv+vLPSpgN35wgKgy+ybfTb2SMw==} - ajv@8.17.1: - resolution: {integrity: sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==} + '@scure/bip39@1.1.1': + resolution: {integrity: sha512-t+wDck2rVkh65Hmv280fYdVdY25J9YeEUIgn2LG1WM6gxFkGzcksoDiUkWVpVp3Oex9xGC68JU2dSbUfwZ2jPg==} - amazon-cognito-identity-js@6.3.16: - resolution: {integrity: sha512-HPGSBGD6Q36t99puWh0LnptxO/4icnk2kqIQ9cTJ2tFQo5NMUnWQIgtrTAk8nm+caqUbjDzXzG56GBjI2tS6jQ==} + '@scure/bip39@1.3.0': + resolution: {integrity: sha512-disdg7gHuTDZtY+ZdkmLpPCk7fxZSu3gBiEGuoC1XYxv9cGx3Z6cpTggCgW6odSOOIXCiDjuGejW+aJKCY/pIQ==} - amdefine@1.0.1: - resolution: {integrity: sha512-S2Hw0TtNkMJhIabBwIojKL9YHO5T0n5eNqWJ7Lrlel/zDbftQpxpapi8tZs3X1HWa+u+QeydGmzzNU0m09+Rcg==} - engines: {node: '>=0.4.2'} + '@scure/bip39@1.5.4': + resolution: {integrity: sha512-TFM4ni0vKvCfBpohoh+/lY05i9gRbSwXWngAsF4CABQxoaOHijxuaZ2R6cStDQ5CHtHO9aGJTr4ksVJASRRyMA==} - ansi-align@3.0.1: - resolution: {integrity: sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==} + '@scure/bip39@1.6.0': + resolution: {integrity: sha512-+lF0BbLiJNwVlev4eKelw1WWLaiKXw7sSl8T6FvBlWkdX+94aGJ4o8XjUdlyhTCjd8c+B3KT3JfS8P0bLRNU6A==} - ansi-colors@4.1.3: - resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} + '@sentry/core@5.30.0': + resolution: {integrity: sha512-TmfrII8w1PQZSZgPpUESqjB+jC6MvZJZdLtE/0hZ+SrnKhW3x5WlYLvTXZpcWePYBku7rl2wn1RZu6uT0qCTeg==} engines: {node: '>=6'} - ansi-escapes@4.3.2: - resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} - engines: {node: '>=8'} + '@sentry/hub@5.30.0': + resolution: {integrity: sha512-2tYrGnzb1gKz2EkMDQcfLrDTvmGcQPuWxLnJKXJvYTQDGLlEvi2tWz1VIHjunmOvJrB5aIQLhm+dcMRwFZDCqQ==} + engines: {node: '>=6'} - ansi-regex@3.0.1: - resolution: {integrity: sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==} - engines: {node: '>=4'} + '@sentry/minimal@5.30.0': + resolution: {integrity: sha512-BwWb/owZKtkDX+Sc4zCSTNcvZUq7YcH3uAVlmh/gtR9rmUvbzAA3ewLuB3myi4wWRAMEtny6+J/FN/x+2wn9Xw==} + engines: {node: '>=6'} - ansi-regex@5.0.1: - resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} - engines: {node: '>=8'} + '@sentry/node@5.30.0': + resolution: {integrity: sha512-Br5oyVBF0fZo6ZS9bxbJZG4ApAjRqAnqFFurMVJJdunNb80brh7a5Qva2kjhm+U6r9NJAB5OmDyPkA1Qnt+QVg==} + engines: {node: '>=6'} - ansi-styles@3.2.1: - resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} - engines: {node: '>=4'} + '@sentry/tracing@5.30.0': + resolution: {integrity: sha512-dUFowCr0AIMwiLD7Fs314Mdzcug+gBVo/+NCMyDw8tFxJkwWAKl7Qa2OZxLQ0ZHjakcj1hNKfCQJ9rhyfOl4Aw==} + engines: {node: '>=6'} - ansi-styles@4.3.0: - resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} - engines: {node: '>=8'} + '@sentry/types@5.30.0': + resolution: {integrity: sha512-R8xOqlSTZ+htqrfteCWU5Nk0CDN5ApUTvrlvBuiH1DyP6czDZ4ktbZB0hAgBlVcK0U+qpD3ag3Tqqpa5Q67rPw==} + engines: {node: '>=6'} - antlr4ts@0.5.0-alpha.4: - resolution: {integrity: sha512-WPQDt1B74OfPv/IMS2ekXAKkTZIHl88uMetg6q3OTqgFxZ/dxDXI0EWLyZid/1Pe6hTftyg5N7gel5wNAGxXyQ==} + '@sentry/utils@5.30.0': + resolution: {integrity: sha512-zaYmoH0NWWtvnJjC9/CBseXMtKHm/tm40sz3YfJRxeQjyzRqNQPgivpd9R/oDJCYj999mzdW382p/qi2ypjLww==} + engines: {node: '>=6'} - any-promise@1.3.0: - resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} + '@sideway/address@4.1.5': + resolution: {integrity: sha512-IqO/DUQHUkPeixNQ8n0JA6102hT9CmaljNTPmQ1u8MEhBo/R4Q8eKLN/vGZxuebwOroDB4cbpjheD4+/sKFK4Q==} - anymatch@3.1.3: - resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} - engines: {node: '>= 8'} + '@sideway/formula@3.0.1': + resolution: {integrity: sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg==} - arg@4.1.3: - resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} + '@sideway/pinpoint@2.0.0': + resolution: {integrity: sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==} - arg@5.0.2: - resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==} + '@sinclair/typebox@0.27.8': + resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} - argparse@1.0.10: - resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} + '@sindresorhus/is@4.6.0': + resolution: {integrity: sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==} + engines: {node: '>=10'} - argparse@2.0.1: - resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + '@sindresorhus/is@5.6.0': + resolution: {integrity: sha512-TV7t8GKYaJWsn00tFDqBw8+Uqmr8A0fRU1tvTQhyZzGv0sJCGRQL3JGMI3ucuKo3XIZdUP+Lx7/gh2t3lewy7g==} + engines: {node: '>=14.16'} - array-back@3.1.0: - resolution: {integrity: sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==} - engines: {node: '>=6'} + '@slorber/react-helmet-async@1.3.0': + resolution: {integrity: sha512-e9/OK8VhwUSc67diWI8Rb3I0YgI9/SBQtnhe9aEuK6MhZm7ntZZimXgwXnd8W96YTmSOb9M4d8LwhRZyhWr/1A==} + peerDependencies: + react: ^16.6.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^16.6.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - array-back@4.0.2: - resolution: {integrity: sha512-NbdMezxqf94cnNfWLL7V/im0Ub+Anbb0IoZhvzie8+4HJ4nMQuzHuy49FkGYCJK2yAloZ3meiB6AVMClbrI1vg==} - engines: {node: '>=8'} + '@slorber/remark-comment@1.0.0': + resolution: {integrity: sha512-RCE24n7jsOj1M0UPvIQCHTe7fI0sFL4S2nwKVWwHyVr/wI/H8GosgsJGyhnsZoGFnD/P2hLf1mSbrrgSLN93NA==} - array-union@2.1.0: - resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} - engines: {node: '>=8'} + '@smithy/abort-controller@4.2.6': + resolution: {integrity: sha512-P7JD4J+wxHMpGxqIg6SHno2tPkZbBUBLbPpR5/T1DEUvw/mEaINBMaPFZNM7lA+ToSCZ36j6nMHa+5kej+fhGg==} + engines: {node: '>=18.0.0'} - array-uniq@1.0.3: - resolution: {integrity: sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==} - engines: {node: '>=0.10.0'} + '@smithy/config-resolver@4.4.4': + resolution: {integrity: sha512-s3U5ChS21DwU54kMmZ0UJumoS5cg0+rGVZvN6f5Lp6EbAVi0ZyP+qDSHdewfmXKUgNK1j3z45JyzulkDukrjAA==} + engines: {node: '>=18.0.0'} - asap@2.0.6: - resolution: {integrity: sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==} + '@smithy/core@3.19.0': + resolution: {integrity: sha512-Y9oHXpBcXQgYHOcAEmxjkDilUbSTkgKjoHYed3WaYUH8jngq8lPWDBSpjHblJ9uOgBdy5mh3pzebrScDdYr29w==} + engines: {node: '>=18.0.0'} - asn1js@3.0.7: - resolution: {integrity: sha512-uLvq6KJu04qoQM6gvBfKFjlh6Gl0vOKQuR5cJMDHQkmwfMOQeN3F3SHCv9SNYSL+CRoHvOGFfllDlVz03GQjvQ==} - engines: {node: '>=12.0.0'} + '@smithy/credential-provider-imds@4.2.6': + resolution: {integrity: sha512-xBmawExyTzOjbhzkZwg+vVm/khg28kG+rj2sbGlULjFd1jI70sv/cbpaR0Ev4Yfd6CpDUDRMe64cTqR//wAOyA==} + engines: {node: '>=18.0.0'} - assertion-error@1.1.0: - resolution: {integrity: sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==} + '@smithy/eventstream-codec@4.2.6': + resolution: {integrity: sha512-OZfsI+YRG26XZik/jKMMg37acnBSbUiK/8nETW3uM3mLj+0tMmFXdHQw1e5WEd/IHN8BGOh3te91SNDe2o4RHg==} + engines: {node: '>=18.0.0'} - assertion-error@2.0.1: - resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} - engines: {node: '>=12'} + '@smithy/eventstream-serde-browser@4.2.6': + resolution: {integrity: sha512-6OiaAaEbLB6dEkRbQyNzFSJv5HDvly3Mc6q/qcPd2uS/g3szR8wAIkh7UndAFKfMypNSTuZ6eCBmgCLR5LacTg==} + engines: {node: '>=18.0.0'} - astral-regex@2.0.0: - resolution: {integrity: sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==} - engines: {node: '>=8'} + '@smithy/eventstream-serde-config-resolver@4.3.6': + resolution: {integrity: sha512-xP5YXbOVRVN8A4pDnSUkEUsL9fYFU6VNhxo8tgr13YnMbf3Pn4xVr+hSyLVjS1Frfi1Uk03ET5Bwml4+0CeYEw==} + engines: {node: '>=18.0.0'} - async-mutex@0.2.6: - resolution: {integrity: sha512-Hs4R+4SPgamu6rSGW8C7cV9gaWUKEHykfzCCvIRuaVv636Ju10ZdeUbvb4TBEW0INuq2DHZqXbK4Nd3yG4RaRw==} + '@smithy/eventstream-serde-node@4.2.6': + resolution: {integrity: sha512-jhH7nJuaOpnTFcuZpWK9dqb6Ge2yGi1okTo0W6wkJrfwAm2vwmO74tF1v07JmrSyHBcKLQATEexclJw9K1Vj7w==} + engines: {node: '>=18.0.0'} - async-retry@1.3.3: - resolution: {integrity: sha512-wfr/jstw9xNi/0teMHrRW7dsz3Lt5ARhYNZ2ewpadnhaIp5mbALhOAP+EAdsC7t4Z6wqsDVv9+W6gm1Dk9mEyw==} + '@smithy/eventstream-serde-universal@4.2.6': + resolution: {integrity: sha512-olIfZ230B64TvPD6b0tPvrEp2eB0FkyL3KvDlqF4RVmIc/kn3orzXnV6DTQdOOW5UU+M5zKY3/BU47X420/oPw==} + engines: {node: '>=18.0.0'} - async@1.5.2: - resolution: {integrity: sha512-nSVgobk4rv61R9PUSDtYt7mPVB2olxNR5RWJcAsH676/ef11bUZwvu7+RGYrYauVdDPcO519v68wRhXQtxsV9w==} + '@smithy/fetch-http-handler@5.3.7': + resolution: {integrity: sha512-fcVap4QwqmzQwQK9QU3keeEpCzTjnP9NJ171vI7GnD7nbkAIcP9biZhDUx88uRH9BabSsQDS0unUps88uZvFIQ==} + engines: {node: '>=18.0.0'} - asynckit@0.4.0: - resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + '@smithy/hash-node@4.2.6': + resolution: {integrity: sha512-k3Dy9VNR37wfMh2/1RHkFf/e0rMyN0pjY0FdyY6ItJRjENYyVPRMwad6ZR1S9HFm6tTuIOd9pqKBmtJ4VHxvxg==} + engines: {node: '>=18.0.0'} - at-least-node@1.0.0: - resolution: {integrity: sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==} - engines: {node: '>= 4.0.0'} + '@smithy/invalid-dependency@4.2.6': + resolution: {integrity: sha512-E4t/V/q2T46RY21fpfznd1iSLTvCXKNKo4zJ1QuEFN4SE9gKfu2vb6bgq35LpufkQ+SETWIC7ZAf2GGvTlBaMQ==} + engines: {node: '>=18.0.0'} - atomic-sleep@1.0.0: - resolution: {integrity: sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==} - engines: {node: '>=8.0.0'} + '@smithy/is-array-buffer@2.2.0': + resolution: {integrity: sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==} + engines: {node: '>=14.0.0'} - autoprefixer@10.4.23: - resolution: {integrity: sha512-YYTXSFulfwytnjAPlw8QHncHJmlvFKtczb8InXaAx9Q0LbfDnfEYDE55omerIJKihhmU61Ft+cAOSzQVaBUmeA==} - engines: {node: ^10 || ^12 || >=14} - hasBin: true - peerDependencies: - postcss: ^8.1.0 + '@smithy/is-array-buffer@4.2.0': + resolution: {integrity: sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ==} + engines: {node: '>=18.0.0'} - available-typed-arrays@1.0.7: - resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} - engines: {node: '>= 0.4'} + '@smithy/middleware-content-length@4.2.6': + resolution: {integrity: sha512-0cjqjyfj+Gls30ntq45SsBtqF3dfJQCeqQPyGz58Pk8OgrAr5YiB7ZvDzjCA94p4r6DCI4qLm7FKobqBjf515w==} + engines: {node: '>=18.0.0'} - axios-retry@4.5.0: - resolution: {integrity: sha512-aR99oXhpEDGo0UuAlYcn2iGRds30k366Zfa05XWScR9QaQD4JYiP3/1Qt1u7YlefUOK+cn0CcwoL1oefavQUlQ==} - peerDependencies: - axios: 0.x || 1.x + '@smithy/middleware-endpoint@4.4.0': + resolution: {integrity: sha512-M6qWfUNny6NFNy8amrCGIb9TfOMUkHVtg9bHtEFGRgfH7A7AtPpn/fcrToGPjVDK1ECuMVvqGQOXcZxmu9K+7A==} + engines: {node: '>=18.0.0'} - axios@1.13.2: - resolution: {integrity: sha512-VPk9ebNqPcy5lRGuSlKx752IlDatOjT9paPlm8A7yOuW2Fbvp4X3JznJtT4f0GzGLLiWE9W8onz51SqLYwzGaA==} + '@smithy/middleware-retry@4.4.16': + resolution: {integrity: sha512-XPpNhNRzm3vhYm7YCsyw3AtmWggJbg1wNGAoqb7NBYr5XA5isMRv14jgbYyUV6IvbTBFZQdf2QpeW43LrRdStQ==} + engines: {node: '>=18.0.0'} - balanced-match@1.0.2: - resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + '@smithy/middleware-serde@4.2.7': + resolution: {integrity: sha512-PFMVHVPgtFECeu4iZ+4SX6VOQT0+dIpm4jSPLLL6JLSkp9RohGqKBKD0cbiXdeIFS08Forp0UHI6kc0gIHenSA==} + engines: {node: '>=18.0.0'} - base-x@3.0.11: - resolution: {integrity: sha512-xz7wQ8xDhdyP7tQxwdteLYeFfS68tSMNCZ/Y37WJ4bhGfKPpqEIlmIyueQHqOyoPhE6xNUqjzRr8ra0eF9VRvA==} + '@smithy/middleware-stack@4.2.6': + resolution: {integrity: sha512-JSbALU3G+JS4kyBZPqnJ3hxIYwOVRV7r9GNQMS6j5VsQDo5+Es5nddLfr9TQlxZLNHPvKSh+XSB0OuWGfSWFcA==} + engines: {node: '>=18.0.0'} - base-x@5.0.1: - resolution: {integrity: sha512-M7uio8Zt++eg3jPj+rHMfCC+IuygQHHCOU+IYsVtik6FWjuYpVt/+MRKcgsAMHh8mMFAwnB+Bs+mTrFiXjMzKg==} + '@smithy/node-config-provider@4.3.6': + resolution: {integrity: sha512-fYEyL59Qe82Ha1p97YQTMEQPJYmBS+ux76foqluaTVWoG9Px5J53w6NvXZNE3wP7lIicLDF7Vj1Em18XTX7fsA==} + engines: {node: '>=18.0.0'} - base64-js@1.5.1: - resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + '@smithy/node-http-handler@4.4.6': + resolution: {integrity: sha512-Gsb9jf4ido5BhPfani4ggyrKDd3ZK+vTFWmUaZeFg5G3E5nhFmqiTzAIbHqmPs1sARuJawDiGMGR/nY+Gw6+aQ==} + engines: {node: '>=18.0.0'} - base64-sol@1.0.1: - resolution: {integrity: sha512-ld3cCNMeXt4uJXmLZBHFGMvVpK9KsLVEhPpFRXnvSVAqABKbuNZg/+dsq3NuM+wxFLb/UrVkz7m1ciWmkMfTbg==} + '@smithy/property-provider@4.2.6': + resolution: {integrity: sha512-a/tGSLPtaia2krbRdwR4xbZKO8lU67DjMk/jfY4QKt4PRlKML+2tL/gmAuhNdFDioO6wOq0sXkfnddNFH9mNUA==} + engines: {node: '>=18.0.0'} - baseline-browser-mapping@2.9.10: - resolution: {integrity: sha512-2VIKvDx8Z1a9rTB2eCkdPE5nSe28XnA+qivGnWHoB40hMMt/h1hSz0960Zqsn6ZyxWXUie0EBdElKv8may20AA==} - hasBin: true + '@smithy/protocol-http@5.3.6': + resolution: {integrity: sha512-qLRZzP2+PqhE3OSwvY2jpBbP0WKTZ9opTsn+6IWYI0SKVpbG+imcfNxXPq9fj5XeaUTr7odpsNpK6dmoiM1gJQ==} + engines: {node: '>=18.0.0'} - bech32@1.1.4: - resolution: {integrity: sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==} + '@smithy/querystring-builder@4.2.6': + resolution: {integrity: sha512-MeM9fTAiD3HvoInK/aA8mgJaKQDvm8N0dKy6EiFaCfgpovQr4CaOkJC28XqlSRABM+sHdSQXbC8NZ0DShBMHqg==} + engines: {node: '>=18.0.0'} - big.js@6.2.2: - resolution: {integrity: sha512-y/ie+Faknx7sZA5MfGA2xKlu0GDv8RWrXGsmlteyJQ2lvoKv9GBK/fpRMc2qlSoBAgNxrixICFCBefIq8WCQpQ==} + '@smithy/querystring-parser@4.2.6': + resolution: {integrity: sha512-YmWxl32SQRw/kIRccSOxzS/Ib8/b5/f9ex0r5PR40jRJg8X1wgM3KrR2In+8zvOGVhRSXgvyQpw9yOSlmfmSnA==} + engines: {node: '>=18.0.0'} - bignumber.js@9.3.1: - resolution: {integrity: sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ==} + '@smithy/service-error-classification@4.2.6': + resolution: {integrity: sha512-Q73XBrzJlGTut2nf5RglSntHKgAG0+KiTJdO5QQblLfr4TdliGwIAha1iZIjwisc3rA5ulzqwwsYC6xrclxVQg==} + engines: {node: '>=18.0.0'} - binary-extensions@2.3.0: - resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} - engines: {node: '>=8'} + '@smithy/shared-ini-file-loader@4.4.1': + resolution: {integrity: sha512-tph+oQYPbpN6NamF030hx1gb5YN2Plog+GLaRHpoEDwp8+ZPG26rIJvStG9hkWzN2HBn3HcWg0sHeB0tmkYzqA==} + engines: {node: '>=18.0.0'} - blakejs@1.2.1: - resolution: {integrity: sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ==} + '@smithy/signature-v4@5.3.6': + resolution: {integrity: sha512-P1TXDHuQMadTMTOBv4oElZMURU4uyEhxhHfn+qOc2iofW9Rd4sZtBGx58Lzk112rIGVEYZT8eUMK4NftpewpRA==} + engines: {node: '>=18.0.0'} - bn.js@4.11.6: - resolution: {integrity: sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA==} + '@smithy/smithy-client@4.10.1': + resolution: {integrity: sha512-1ovWdxzYprhq+mWqiGZlt3kF69LJthuQcfY9BIyHx9MywTFKzFapluku1QXoaBB43GCsLDxNqS+1v30ure69AA==} + engines: {node: '>=18.0.0'} - bn.js@4.12.2: - resolution: {integrity: sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw==} + '@smithy/types@4.10.0': + resolution: {integrity: sha512-K9mY7V/f3Ul+/Gz4LJANZ3vJ/yiBIwCyxe0sPT4vNJK63Srvd+Yk1IzP0t+nE7XFSpIGtzR71yljtnqpUTYFlQ==} + engines: {node: '>=18.0.0'} - bn.js@5.2.2: - resolution: {integrity: sha512-v2YAxEmKaBLahNwE1mjp4WON6huMNeuDvagFZW+ASCuA/ku0bXR9hSMw0XpiqMoA3+rmnyck/tPRSFQkoC9Cuw==} + '@smithy/url-parser@4.2.6': + resolution: {integrity: sha512-tVoyzJ2vXp4R3/aeV4EQjBDmCuWxRa8eo3KybL7Xv4wEM16nObYh7H1sNfcuLWHAAAzb0RVyxUz1S3sGj4X+Tg==} + engines: {node: '>=18.0.0'} - borsh@0.7.0: - resolution: {integrity: sha512-CLCsZGIBCFnPtkNnieW/a8wmreDmfUtjU2m9yHrzPXIlNbqVs0AQrSatSG6vdNYUqdc83tkQi2eHfF98ubzQLA==} + '@smithy/util-base64@4.3.0': + resolution: {integrity: sha512-GkXZ59JfyxsIwNTWFnjmFEI8kZpRNIBfxKjv09+nkAWPt/4aGaEWMM04m4sxgNVWkbt2MdSvE3KF/PfX4nFedQ==} + engines: {node: '>=18.0.0'} - bowser@2.13.1: - resolution: {integrity: sha512-OHawaAbjwx6rqICCKgSG0SAnT05bzd7ppyKLVUITZpANBaaMFBAsaNkto3LoQ31tyFP5kNujE8Cdx85G9VzOkw==} + '@smithy/util-body-length-browser@4.2.0': + resolution: {integrity: sha512-Fkoh/I76szMKJnBXWPdFkQJl2r9SjPt3cMzLdOB6eJ4Pnpas8hVoWPYemX/peO0yrrvldgCUVJqOAjUrOLjbxg==} + engines: {node: '>=18.0.0'} - boxen@5.1.2: - resolution: {integrity: sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ==} - engines: {node: '>=10'} + '@smithy/util-body-length-node@4.2.1': + resolution: {integrity: sha512-h53dz/pISVrVrfxV1iqXlx5pRg3V2YWFcSQyPyXZRrZoZj4R4DeWRDo1a7dd3CPTcFi3kE+98tuNyD2axyZReA==} + engines: {node: '>=18.0.0'} - brace-expansion@1.1.12: - resolution: {integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==} + '@smithy/util-buffer-from@2.2.0': + resolution: {integrity: sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==} + engines: {node: '>=14.0.0'} - brace-expansion@2.0.2: - resolution: {integrity: sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==} + '@smithy/util-buffer-from@4.2.0': + resolution: {integrity: sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew==} + engines: {node: '>=18.0.0'} - braces@3.0.3: - resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} - engines: {node: '>=8'} + '@smithy/util-config-provider@4.2.0': + resolution: {integrity: sha512-YEjpl6XJ36FTKmD+kRJJWYvrHeUvm5ykaUS5xK+6oXffQPHeEM4/nXlZPe+Wu0lsgRUcNZiliYNh/y7q9c2y6Q==} + engines: {node: '>=18.0.0'} - brorand@1.1.0: - resolution: {integrity: sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==} + '@smithy/util-defaults-mode-browser@4.3.15': + resolution: {integrity: sha512-LiZQVAg/oO8kueX4c+oMls5njaD2cRLXRfcjlTYjhIqmwHnCwkQO5B3dMQH0c5PACILxGAQf6Mxsq7CjlDc76A==} + engines: {node: '>=18.0.0'} - browser-stdout@1.3.1: - resolution: {integrity: sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==} + '@smithy/util-defaults-mode-node@4.2.18': + resolution: {integrity: sha512-Kw2J+KzYm9C9Z9nY6+W0tEnoZOofstVCMTshli9jhQbQCy64rueGfKzPfuFBnVUqZD9JobxTh2DzHmPkp/Va/Q==} + engines: {node: '>=18.0.0'} - browserify-aes@1.2.0: - resolution: {integrity: sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==} + '@smithy/util-endpoints@3.2.6': + resolution: {integrity: sha512-v60VNM2+mPvgHCBXEfMCYrQ0RepP6u6xvbAkMenfe4Mi872CqNkJzgcnQL837e8NdeDxBgrWQRTluKq5Lqdhfg==} + engines: {node: '>=18.0.0'} - browserslist@4.28.1: - resolution: {integrity: sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==} - engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} - hasBin: true + '@smithy/util-hex-encoding@4.2.0': + resolution: {integrity: sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw==} + engines: {node: '>=18.0.0'} - bs58@4.0.1: - resolution: {integrity: sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==} + '@smithy/util-middleware@4.2.6': + resolution: {integrity: sha512-qrvXUkxBSAFomM3/OEMuDVwjh4wtqK8D2uDZPShzIqOylPst6gor2Cdp6+XrH4dyksAWq/bE2aSDYBTTnj0Rxg==} + engines: {node: '>=18.0.0'} - bs58@6.0.0: - resolution: {integrity: sha512-PD0wEnEYg6ijszw/u8s+iI3H17cTymlrwkKhDhPZq+Sokl3AU4htyBFTjAeNAlCCmg0f53g6ih3jATyCKftTfw==} + '@smithy/util-retry@4.2.6': + resolution: {integrity: sha512-x7CeDQLPQ9cb6xN7fRJEjlP9NyGW/YeXWc4j/RUhg4I+H60F0PEeRc2c/z3rm9zmsdiMFzpV/rT+4UHW6KM1SA==} + engines: {node: '>=18.0.0'} - bs58check@2.1.2: - resolution: {integrity: sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==} + '@smithy/util-stream@4.5.7': + resolution: {integrity: sha512-Uuy4S5Aj4oF6k1z+i2OtIBJUns4mlg29Ph4S+CqjR+f4XXpSFVgTCYLzMszHJTicYDBxKFtwq2/QSEDSS5l02A==} + engines: {node: '>=18.0.0'} - buffer-from@1.1.2: - resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + '@smithy/util-uri-escape@4.2.0': + resolution: {integrity: sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA==} + engines: {node: '>=18.0.0'} - buffer-xor@1.0.3: - resolution: {integrity: sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==} + '@smithy/util-utf8@2.3.0': + resolution: {integrity: sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==} + engines: {node: '>=14.0.0'} - buffer@4.9.2: - resolution: {integrity: sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==} + '@smithy/util-utf8@4.2.0': + resolution: {integrity: sha512-zBPfuzoI8xyBtR2P6WQj63Rz8i3AmfAaJLuNG8dWsfvPe8lO4aCPYLn879mEgHndZH1zQ2oXmG8O1GGzzaoZiw==} + engines: {node: '>=18.0.0'} - buffer@6.0.3: - resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} + '@smithy/util-waiter@4.2.6': + resolution: {integrity: sha512-xU9HwUSik9UUCJmm530yvBy0AwlQFICveKmqvaaTukKkXEAhyiBdHtSrhPrH3rH+uz0ykyaE3LdgsX86C6mDCQ==} + engines: {node: '>=18.0.0'} - bufferutil@4.0.9: - resolution: {integrity: sha512-WDtdLmJvAuNNPzByAYpRo2rF1Mmradw6gvWsQKf63476DDXmomT9zUiGypLcG4ibIM67vhAj8jJRdbmEws2Aqw==} - engines: {node: '>=6.14.2'} + '@smithy/uuid@1.1.0': + resolution: {integrity: sha512-4aUIteuyxtBUhVdiQqcDhKFitwfd9hqoSDYY2KRXiWtgoWJ9Bmise+KfEPDiVHWeJepvF8xJO9/9+WDIciMFFw==} + engines: {node: '>=18.0.0'} - bytes@3.1.2: - resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} - engines: {node: '>= 0.8'} + '@socket.io/component-emitter@3.1.2': + resolution: {integrity: sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==} - cac@6.7.14: - resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} - engines: {node: '>=8'} + '@solana-program/system@0.8.1': + resolution: {integrity: sha512-71U9Mzdpw8HQtfgfJSL5xKZbLMRnza2Llsfk7gGnmg2waqK+o8MMH4YNma8xXS1UmOBptXIiNvoZ3p7cmOVktg==} + peerDependencies: + '@solana/kit': ^3.0 - call-bind-apply-helpers@1.0.2: - resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} - engines: {node: '>= 0.4'} + '@solana-program/token@0.6.0': + resolution: {integrity: sha512-omkZh4Tt9rre4wzWHNOhOEHyenXQku3xyc/UrKvShexA/Qlhza67q7uRwmwEDUs4QqoDBidSZPooOmepnA/jig==} + peerDependencies: + '@solana/kit': ^3.0 - call-bind@1.0.8: - resolution: {integrity: sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==} - engines: {node: '>= 0.4'} + '@solana/accounts@3.0.3': + resolution: {integrity: sha512-KqlePrlZaHXfu8YQTCxN204ZuVm9o68CCcUr6l27MG2cuRUtEM1Ta0iR8JFkRUAEfZJC4Cu0ZDjK/v49loXjZQ==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' - call-bound@1.0.4: - resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} - engines: {node: '>= 0.4'} + '@solana/addresses@3.0.3': + resolution: {integrity: sha512-AuMwKhJI89ANqiuJ/fawcwxNKkSeHH9CApZd2xelQQLS7X8uxAOovpcmEgiObQuiVP944s9ScGUT62Bdul9qYg==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' - camelcase-css@2.0.1: - resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==} - engines: {node: '>= 6'} + '@solana/assertions@3.0.3': + resolution: {integrity: sha512-2qspxdbWp2y62dfCIlqeWQr4g+hE8FYSSwcaP6itwMwGRb8393yDGCJfI/znuzJh6m/XVWhMHIgFgsBwnevCmg==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' - camelcase@5.3.1: - resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==} - engines: {node: '>=6'} - - camelcase@6.3.0: - resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} - engines: {node: '>=10'} + '@solana/buffer-layout@4.0.1': + resolution: {integrity: sha512-E1ImOIAD1tBZFRdjeM4/pzTiTApC0AOBGwyAMS4fwIodCWArzJ3DWdoh8cKxeFM2fElkxBh2Aqts1BPC373rHA==} + engines: {node: '>=5.10'} - caniuse-lite@1.0.30001760: - resolution: {integrity: sha512-7AAMPcueWELt1p3mi13HR/LHH0TJLT11cnwDJEs3xA4+CK/PLKeO9Kl1oru24htkyUKtkGCvAx4ohB0Ttry8Dw==} + '@solana/codecs-core@2.3.0': + resolution: {integrity: sha512-oG+VZzN6YhBHIoSKgS5ESM9VIGzhWjEHEGNPSibiDTxFhsFWxNaz8LbMDPjBUE69r9wmdGLkrQ+wVPbnJcZPvw==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' - caseless@0.12.0: - resolution: {integrity: sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==} + '@solana/codecs-core@3.0.3': + resolution: {integrity: sha512-emKykJ3h1DmnDOY29Uv9eJXP8E/FHzvlUBJ6te+5EbKdFjj7vdlKYPfDxOI6iGdXTY+YC/ELtbNBh6QwF2uEDQ==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' - cbor@10.0.11: - resolution: {integrity: sha512-vIwORDd/WyB8Nc23o2zNN5RrtFGlR6Fca61TtjkUXueI3Jf2DOZDl1zsshvBntZ3wZHBM9ztjnkXSmzQDaq3WA==} - engines: {node: '>=20'} + '@solana/codecs-data-structures@3.0.3': + resolution: {integrity: sha512-R15cLp8riJvToXziW8lP6AMSwsztGhEnwgyGmll32Mo0Yjq+hduW2/fJrA/TJs6tA/OgTzMQjlxgk009EqZHCw==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' - cbor@8.1.0: - resolution: {integrity: sha512-DwGjNW9omn6EwP70aXsn7FQJx5kO12tX0bZkaTjzdVFM6/7nhA4t0EENocKGx6D2Bch9PE2KzCUf5SceBdeijg==} - engines: {node: '>=12.19'} + '@solana/codecs-numbers@2.3.0': + resolution: {integrity: sha512-jFvvwKJKffvG7Iz9dmN51OGB7JBcy2CJ6Xf3NqD/VP90xak66m/Lg48T01u5IQ/hc15mChVHiBm+HHuOFDUrQg==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' - cbor@9.0.2: - resolution: {integrity: sha512-JPypkxsB10s9QOWwa6zwPzqE1Md3vqpPc+cai4sAecuCsRyAtAl/pMyhPlMbT/xtPnm2dznJZYRLui57qiRhaQ==} - engines: {node: '>=16'} + '@solana/codecs-numbers@3.0.3': + resolution: {integrity: sha512-pfXkH9J0glrM8qj6389GAn30+cJOxzXLR2FsPOHCUMXrqLhGjMMZAWhsQkpOQ37SGc/7EiQsT/gmyGC7gxHqJQ==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' - chai-as-promised@7.1.2: - resolution: {integrity: sha512-aBDHZxRzYnUYuIAIPBH2s511DjlKPzXNlXSGFC8CwmroWQLfrW0LtE1nK3MAwwNhJPa9raEjNCmRoFpG0Hurdw==} + '@solana/codecs-strings@3.0.3': + resolution: {integrity: sha512-VHBXnnTVtcQ1j+7Vrz+qSYo38no+jiHRdGnhFspRXEHNJbllzwKqgBE7YN3qoIXH+MKxgJUcwO5KHmdzf8Wn2A==} + engines: {node: '>=20.18.0'} peerDependencies: - chai: '>= 2.1.2 < 6' + fastestsmallesttextencoderdecoder: ^1.0.22 + typescript: '>=5.3.3' - chai@4.5.0: - resolution: {integrity: sha512-RITGBfijLkBddZvnn8jdqoTypxvqbOLYQkGGxXzeFjVHvudaPw0HNFD9x928/eUwYWd2dPCugVqspGALTZZQKw==} - engines: {node: '>=4'} + '@solana/codecs@3.0.3': + resolution: {integrity: sha512-GOHwTlIQsCoJx9Ryr6cEf0FHKAQ7pY4aO4xgncAftrv0lveTQ1rPP2inQ1QT0gJllsIa8nwbfXAADs9nNJxQDA==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' - chai@5.3.3: - resolution: {integrity: sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==} - engines: {node: '>=18'} + '@solana/errors@2.3.0': + resolution: {integrity: sha512-66RI9MAbwYV0UtP7kGcTBVLxJgUxoZGm8Fbc0ah+lGiAw17Gugco6+9GrJCV83VyF2mDWyYnYM9qdI3yjgpnaQ==} + engines: {node: '>=20.18.0'} + hasBin: true + peerDependencies: + typescript: '>=5.3.3' - chalk@2.4.2: - resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} - engines: {node: '>=4'} + '@solana/errors@3.0.3': + resolution: {integrity: sha512-1l84xJlHNva6io62PcYfUamwWlc0eM95nHgCrKX0g0cLoC6D6QHYPCEbEVkR+C5UtP9JDgyQM8MFiv+Ei5tO9Q==} + engines: {node: '>=20.18.0'} + hasBin: true + peerDependencies: + typescript: '>=5.3.3' - chalk@4.1.2: - resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} - engines: {node: '>=10'} + '@solana/fast-stable-stringify@3.0.3': + resolution: {integrity: sha512-ED0pxB6lSEYvg+vOd5hcuQrgzEDnOrURFgp1ZOY+lQhJkQU6xo+P829NcJZQVP1rdU2/YQPAKJKEseyfe9VMIw==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' - chalk@5.6.2: - resolution: {integrity: sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==} - engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + '@solana/functional@3.0.3': + resolution: {integrity: sha512-2qX1kKANn8995vOOh5S9AmF4ItGZcfbny0w28Eqy8AFh+GMnSDN4gqpmV2LvxBI9HibXZptGH3RVOMk82h1Mpw==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' - charenc@0.0.2: - resolution: {integrity: sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==} + '@solana/instruction-plans@3.0.3': + resolution: {integrity: sha512-eqoaPtWtmLTTpdvbt4BZF5H6FIlJtXi9H7qLOM1dLYonkOX2Ncezx5NDCZ9tMb2qxVMF4IocYsQnNSnMfjQF1w==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' - check-error@1.0.3: - resolution: {integrity: sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==} + '@solana/instructions@3.0.3': + resolution: {integrity: sha512-4csIi8YUDb5j/J+gDzmYtOvq7ZWLbCxj4t0xKn+fPrBk/FD2pK29KVT3Fu7j4Lh1/ojunQUP9X4NHwUexY3PnA==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' - check-error@2.1.1: - resolution: {integrity: sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==} - engines: {node: '>= 16'} + '@solana/keys@3.0.3': + resolution: {integrity: sha512-tp8oK9tMadtSIc4vF4aXXWkPd4oU5XPW8nf28NgrGDWGt25fUHIydKjkf2hPtMt9i1WfRyQZ33B5P3dnsNqcPQ==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' - chokidar@3.6.0: - resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} - engines: {node: '>= 8.10.0'} + '@solana/kit@3.0.3': + resolution: {integrity: sha512-CEEhCDmkvztd1zbgADsEQhmj9GyWOOGeW1hZD+gtwbBSF5YN1uofS/pex5MIh/VIqKRj+A2UnYWI1V+9+q/lyQ==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' - chokidar@4.0.3: - resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} - engines: {node: '>= 14.16.0'} + '@solana/nominal-types@3.0.3': + resolution: {integrity: sha512-aZavCiexeUAoMHRQg4s1AHkH3wscbOb70diyfjhwZVgFz1uUsFez7csPp9tNFkNolnadVb2gky7yBk3IImQJ6A==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' - ci-info@2.0.0: - resolution: {integrity: sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==} + '@solana/options@3.0.3': + resolution: {integrity: sha512-jarsmnQ63RN0JPC5j9sgUat07NrL9PC71XU7pUItd6LOHtu4+wJMio3l5mT0DHVfkfbFLL6iI6+QmXSVhTNF3g==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' - cipher-base@1.0.7: - resolution: {integrity: sha512-Mz9QMT5fJe7bKI7MH31UilT5cEK5EHHRCccw/YRFsRY47AuNgaV6HY3rscp0/I4Q+tTW/5zoqpSeRRI54TkDWA==} - engines: {node: '>= 0.10'} + '@solana/programs@3.0.3': + resolution: {integrity: sha512-JZlVE3/AeSNDuH3aEzCZoDu8GTXkMpGXxf93zXLzbxfxhiQ/kHrReN4XE/JWZ/uGWbaFZGR5B3UtdN2QsoZL7w==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' - clean-stack@2.2.0: - resolution: {integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==} - engines: {node: '>=6'} + '@solana/promises@3.0.3': + resolution: {integrity: sha512-K+UflGBVxj30XQMHTylHHZJdKH5QG3oj5k2s42GrZ/Wbu72oapVJySMBgpK45+p90t8/LEqV6rRPyTXlet9J+Q==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' - cli-boxes@2.2.1: - resolution: {integrity: sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==} - engines: {node: '>=6'} + '@solana/rpc-api@3.0.3': + resolution: {integrity: sha512-Yym9/Ama62OY69rAZgbOCAy1QlqaWAyb0VlqFuwSaZV1pkFCCFSwWEJEsiN1n8pb2ZP+RtwNvmYixvWizx9yvA==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' - cli-table3@0.5.1: - resolution: {integrity: sha512-7Qg2Jrep1S/+Q3EceiZtQcDPWxhAvBw+ERf1162v4sikJrvojMHFqXt8QIVha8UlH9rgU0BeWPytZ9/TzYqlUw==} - engines: {node: '>=6'} + '@solana/rpc-parsed-types@3.0.3': + resolution: {integrity: sha512-/koM05IM2fU91kYDQxXil3VBNlOfcP+gXE0js1sdGz8KonGuLsF61CiKB5xt6u1KEXhRyDdXYLjf63JarL4Ozg==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' - cliui@6.0.0: - resolution: {integrity: sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==} + '@solana/rpc-spec-types@3.0.3': + resolution: {integrity: sha512-A6Jt8SRRetnN3CeGAvGJxigA9zYRslGgWcSjueAZGvPX+MesFxEUjSWZCfl+FogVFvwkqfkgQZQbPAGZQFJQ6Q==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' - cliui@7.0.4: - resolution: {integrity: sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==} + '@solana/rpc-spec@3.0.3': + resolution: {integrity: sha512-MZn5/8BebB6MQ4Gstw6zyfWsFAZYAyLzMK+AUf/rSfT8tPmWiJ/mcxnxqOXvFup/l6D67U8pyGpIoFqwCeZqqA==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' - clsx@1.2.1: - resolution: {integrity: sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==} - engines: {node: '>=6'} + '@solana/rpc-subscriptions-api@3.0.3': + resolution: {integrity: sha512-MGgVK3PUS15qsjuhimpzGZrKD/CTTvS0mAlQ0Jw84zsr1RJVdQJK/F0igu07BVd172eTZL8d90NoAQ3dahW5pA==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' - clsx@2.1.1: - resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} - engines: {node: '>=6'} + '@solana/rpc-subscriptions-channel-websocket@3.0.3': + resolution: {integrity: sha512-zUzUlb8Cwnw+SHlsLrSqyBRtOJKGc+FvSNJo/vWAkLShoV0wUDMPv7VvhTngJx3B/3ANfrOZ4i08i9QfYPAvpQ==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + ws: ^8.18.0 - color-convert@1.9.3: - resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} + '@solana/rpc-subscriptions-spec@3.0.3': + resolution: {integrity: sha512-9KpQ32OBJWS85mn6q3gkM0AjQe1LKYlMU7gpJRrla/lvXxNLhI95tz5K6StctpUreVmRWTVkNamHE69uUQyY8A==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' - color-convert@2.0.1: - resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} - engines: {node: '>=7.0.0'} + '@solana/rpc-subscriptions@3.0.3': + resolution: {integrity: sha512-LRvz6NaqvtsYFd32KwZ+rwYQ9XCs+DWjV8BvBLsJpt9/NWSuHf/7Sy/vvP6qtKxut692H/TMvHnC4iulg0WmiQ==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' - color-name@1.1.3: - resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} + '@solana/rpc-transformers@3.0.3': + resolution: {integrity: sha512-lzdaZM/dG3s19Tsk4mkJA5JBoS1eX9DnD7z62gkDwrwJDkDBzkAJT9aLcsYFfTmwTfIp6uU2UPgGYc97i1wezw==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' - color-name@1.1.4: - resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + '@solana/rpc-transport-http@3.0.3': + resolution: {integrity: sha512-bIXFwr2LR5A97Z46dI661MJPbHnPfcShBjFzOS/8Rnr8P4ho3j/9EUtjDrsqoxGJT3SLWj5OlyXAlaDAvVTOUQ==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' - colors@1.4.0: - resolution: {integrity: sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==} - engines: {node: '>=0.1.90'} + '@solana/rpc-types@3.0.3': + resolution: {integrity: sha512-petWQ5xSny9UfmC3Qp2owyhNU0w9SyBww4+v7tSVyXMcCC9v6j/XsqTeimH1S0qQUllnv0/FY83ohFaxofmZ6Q==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' - combined-stream@1.0.8: - resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} - engines: {node: '>= 0.8'} + '@solana/rpc@3.0.3': + resolution: {integrity: sha512-3oukAaLK78GegkKcm6iNmRnO4mFeNz+BMvA8T56oizoBNKiRVEq/6DFzVX/LkmZ+wvD601pAB3uCdrTPcC0YKQ==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' - command-exists@1.2.9: - resolution: {integrity: sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w==} + '@solana/signers@3.0.3': + resolution: {integrity: sha512-UwCd/uPYTZiwd283JKVyOWLLN5sIgMBqGDyUmNU3vo9hcmXKv5ZGm/9TvwMY2z35sXWuIOcj7etxJ8OoWc/ObQ==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' - command-line-args@5.2.1: - resolution: {integrity: sha512-H4UfQhZyakIjC74I9d34fGYDwk3XpSr17QhEd0Q3I9Xq1CETHo4Hcuo87WyWHpAF1aSLjLRf5lD9ZGX2qStUvg==} - engines: {node: '>=4.0.0'} + '@solana/subscribable@3.0.3': + resolution: {integrity: sha512-FJ27LKGHLQ5GGttPvTOLQDLrrOZEgvaJhB7yYaHAhPk25+p+erBaQpjePhfkMyUbL1FQbxn1SUJmS6jUuaPjlQ==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' - command-line-usage@6.1.3: - resolution: {integrity: sha512-sH5ZSPr+7UStsloltmDh7Ce5fb8XPlHyoPzTpyyMuYCtervL65+ubVZ6Q61cFtFl62UyJlc8/JwERRbAFPUqgw==} - engines: {node: '>=8.0.0'} + '@solana/sysvars@3.0.3': + resolution: {integrity: sha512-GnHew+QeKCs2f9ow+20swEJMH4mDfJA/QhtPgOPTYQx/z69J4IieYJ7fZenSHnA//lJ45fVdNdmy1trypvPLBQ==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' - commander@14.0.0: - resolution: {integrity: sha512-2uM9rYjPvyq39NwLRqaiLtWHyDC1FvryJDa2ATTVims5YAS4PupsEQsDvP14FqhFr0P49CYDugi59xaxJlTXRA==} - engines: {node: '>=20'} + '@solana/transaction-confirmation@3.0.3': + resolution: {integrity: sha512-dXx0OLtR95LMuARgi2dDQlL1QYmk56DOou5q9wKymmeV3JTvfDExeWXnOgjRBBq/dEfj4ugN1aZuTaS18UirFw==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' - commander@14.0.2: - resolution: {integrity: sha512-TywoWNNRbhoD0BXs1P3ZEScW8W5iKrnbithIl0YH+uCmBd0QpPOA8yc82DS3BIE5Ma6FnBVUsJ7wVUDz4dvOWQ==} - engines: {node: '>=20'} + '@solana/transaction-messages@3.0.3': + resolution: {integrity: sha512-s+6NWRnBhnnjFWV4x2tzBzoWa6e5LiIxIvJlWwVQBFkc8fMGY04w7jkFh0PM08t/QFKeXBEWkyBDa/TFYdkWug==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' - commander@2.20.3: - resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} + '@solana/transactions@3.0.3': + resolution: {integrity: sha512-iMX+n9j4ON7H1nKlWEbMqMOpKYC6yVGxKKmWHT1KdLRG7v+03I4DnDeFoI+Zmw56FA+7Bbne8jwwX60Q1vk/MQ==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' - commander@4.1.1: - resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} - engines: {node: '>= 6'} + '@solana/web3.js@1.98.4': + resolution: {integrity: sha512-vv9lfnvjUsRiq//+j5pBdXig0IQdtzA0BRZ3bXEP4KaIyF1CcaydWqgyzQgfZMNIsWNWmG+AUHwPy4AHOD6gpw==} - commander@8.3.0: - resolution: {integrity: sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==} - engines: {node: '>= 12'} + '@solidity-parser/parser@0.14.5': + resolution: {integrity: sha512-6dKnHZn7fg/iQATVEzqyUOyEidbn05q7YA2mQ9hC0MMXhhV3/JrsxmFSYZAcr7j1yUP700LLhTruvJ3MiQmjJg==} - compare-versions@6.1.1: - resolution: {integrity: sha512-4hm4VPpIecmlg59CHXnRDnqGplJFrbLG4aFEl5vl6cK1u76ws3LLvX7ikFnTDl5vo39sjWD6AaDPYodJp/NNHg==} + '@solidity-parser/parser@0.20.2': + resolution: {integrity: sha512-rbu0bzwNvMcwAjH86hiEAcOeRI2EeK8zCkHDrFykh/Al8mvJeFmjy3UrE7GYQjNwOgbGUUtCn5/k8CB8zIu7QA==} - concat-map@0.0.1: - resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + '@svgr/babel-plugin-add-jsx-attribute@8.0.0': + resolution: {integrity: sha512-b9MIk7yhdS1pMCZM8VeNfUlSKVRhsHZNMl5O9SfaX0l0t5wjdgu4IDzGB8bpnGBBOjGST3rRFVsaaEtI4W6f7g==} + engines: {node: '>=14'} + peerDependencies: + '@babel/core': ^7.0.0-0 - concat-stream@1.6.2: - resolution: {integrity: sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==} - engines: {'0': node >= 0.8} + '@svgr/babel-plugin-remove-jsx-attribute@8.0.0': + resolution: {integrity: sha512-BcCkm/STipKvbCl6b7QFrMh/vx00vIP63k2eM66MfHJzPr6O2U0jYEViXkHJWqXqQYjdeA9cuCl5KWmlwjDvbA==} + engines: {node: '>=14'} + peerDependencies: + '@babel/core': ^7.0.0-0 - convert-source-map@2.0.0: - resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + '@svgr/babel-plugin-remove-jsx-empty-expression@8.0.0': + resolution: {integrity: sha512-5BcGCBfBxB5+XSDSWnhTThfI9jcO5f0Ai2V24gZpG+wXF14BzwxxdDb4g6trdOux0rhibGs385BeFMSmxtS3uA==} + engines: {node: '>=14'} + peerDependencies: + '@babel/core': ^7.0.0-0 - cookie-es@1.2.2: - resolution: {integrity: sha512-+W7VmiVINB+ywl1HGXJXmrqkOhpKrIiVZV6tQuV54ZyQC7MMuBt81Vc336GMLoHBq5hV/F9eXgt5Mnx0Rha5Fg==} + '@svgr/babel-plugin-replace-jsx-attribute-value@8.0.0': + resolution: {integrity: sha512-KVQ+PtIjb1BuYT3ht8M5KbzWBhdAjjUPdlMtpuw/VjT8coTrItWX6Qafl9+ji831JaJcu6PJNKCV0bp01lBNzQ==} + engines: {node: '>=14'} + peerDependencies: + '@babel/core': ^7.0.0-0 - cookie@0.4.2: - resolution: {integrity: sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==} - engines: {node: '>= 0.6'} + '@svgr/babel-plugin-svg-dynamic-title@8.0.0': + resolution: {integrity: sha512-omNiKqwjNmOQJ2v6ge4SErBbkooV2aAWwaPFs2vUY7p7GhVkzRkJ00kILXQvRhA6miHnNpXv7MRnnSjdRjK8og==} + engines: {node: '>=14'} + peerDependencies: + '@babel/core': ^7.0.0-0 - core-util-is@1.0.3: - resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} + '@svgr/babel-plugin-svg-em-dimensions@8.0.0': + resolution: {integrity: sha512-mURHYnu6Iw3UBTbhGwE/vsngtCIbHE43xCRK7kCw4t01xyGqb2Pd+WXekRRoFOBIY29ZoOhUCTEweDMdrjfi9g==} + engines: {node: '>=14'} + peerDependencies: + '@babel/core': ^7.0.0-0 - crc-32@1.2.2: - resolution: {integrity: sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==} - engines: {node: '>=0.8'} - hasBin: true + '@svgr/babel-plugin-transform-react-native-svg@8.1.0': + resolution: {integrity: sha512-Tx8T58CHo+7nwJ+EhUwx3LfdNSG9R2OKfaIXXs5soiy5HtgoAEkDay9LIimLOcG8dJQH1wPZp/cnAv6S9CrR1Q==} + engines: {node: '>=14'} + peerDependencies: + '@babel/core': ^7.0.0-0 - create-hash@1.2.0: - resolution: {integrity: sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==} + '@svgr/babel-plugin-transform-svg-component@8.0.0': + resolution: {integrity: sha512-DFx8xa3cZXTdb/k3kfPeaixecQLgKh5NVBMwD0AQxOzcZawK4oo1Jh9LbrcACUivsCA7TLG8eeWgrDXjTMhRmw==} + engines: {node: '>=12'} + peerDependencies: + '@babel/core': ^7.0.0-0 - create-hmac@1.1.7: - resolution: {integrity: sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==} + '@svgr/babel-preset@8.1.0': + resolution: {integrity: sha512-7EYDbHE7MxHpv4sxvnVPngw5fuR6pw79SkcrILHJ/iMpuKySNCl5W1qcwPEpU+LgyRXOaAFgH0KhwD18wwg6ug==} + engines: {node: '>=14'} + peerDependencies: + '@babel/core': ^7.0.0-0 - create-require@1.1.1: - resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} + '@svgr/core@8.1.0': + resolution: {integrity: sha512-8QqtOQT5ACVlmsvKOJNEaWmRPmcojMOzCz4Hs2BGG/toAp/K38LcsMRyLp349glq5AzJbCEeimEoxaX6v/fLrA==} + engines: {node: '>=14'} - cross-fetch@3.2.0: - resolution: {integrity: sha512-Q+xVJLoGOeIMXZmbUK4HYk+69cQH6LudR0Vu/pRm2YlU/hDV9CiS0gKUMaWY5f2NeUH9C1nV3bsTlCo0FsTV1Q==} + '@svgr/hast-util-to-babel-ast@8.0.0': + resolution: {integrity: sha512-EbDKwO9GpfWP4jN9sGdYwPBU0kdomaPIL2Eu4YwmgP+sJeXT+L7bMwJUBnhzfH8Q2qMBqZ4fJwpCyYsAN3mt2Q==} + engines: {node: '>=14'} - cross-fetch@4.1.0: - resolution: {integrity: sha512-uKm5PU+MHTootlWEY+mZ4vvXoCn4fLQxT9dSc1sXVMSFkINTJVN8cAQROpwcKm8bJ/c7rgZVIBWzH5T78sNZZw==} + '@svgr/plugin-jsx@8.1.0': + resolution: {integrity: sha512-0xiIyBsLlr8quN+WyuxooNW9RJ0Dpr8uOnH/xrCVO8GLUcwHISwj1AG0k+LFzteTkAA0GbX0kj9q6Dk70PTiPA==} + engines: {node: '>=14'} + peerDependencies: + '@svgr/core': '*' - crossws@0.3.5: - resolution: {integrity: sha512-ojKiDvcmByhwa8YYqbQI/hg7MEU0NC03+pSdEq4ZUnZR9xXpwk7E43SMNGkn+JxJGPFtNvQ48+vV2p+P1ml5PA==} + '@svgr/plugin-svgo@8.1.0': + resolution: {integrity: sha512-Ywtl837OGO9pTLIN/onoWLmDQ4zFUycI1g76vuKGEz6evR/ZTJlJuz3G/fIkb6OVBJ2g0o6CGJzaEjfmEo3AHA==} + engines: {node: '>=14'} + peerDependencies: + '@svgr/core': '*' - crypt@0.0.2: - resolution: {integrity: sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==} + '@svgr/webpack@8.1.0': + resolution: {integrity: sha512-LnhVjMWyMQV9ZmeEy26maJk+8HTIbd59cH4F2MJ439k9DqejRisfFNGAPvRYlKETuh9LrImlS8aKsBgKjMA8WA==} + engines: {node: '>=14'} - css-what@6.2.2: - resolution: {integrity: sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==} - engines: {node: '>= 6'} + '@swc/helpers@0.5.17': + resolution: {integrity: sha512-5IKx/Y13RsYd+sauPb2x+U/xZikHjolzfuDgTAl/Tdf3Q8rslRvC19NKDLgAJQ6wsqADk10ntlv08nPFw/gO/A==} - cssesc@3.0.0: - resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} - engines: {node: '>=4'} - hasBin: true + '@szmarczak/http-timer@5.0.1': + resolution: {integrity: sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==} + engines: {node: '>=14.16'} - csstype@3.2.3: - resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} + '@tanstack/query-core@5.90.12': + resolution: {integrity: sha512-T1/8t5DhV/SisWjDnaiU2drl6ySvsHj1bHBCWNXd+/T+Hh1cf6JodyEYMd5sgwm+b/mETT4EV3H+zCVczCU5hg==} - cuer@0.0.3: - resolution: {integrity: sha512-f/UNxRMRCYtfLEGECAViByA3JNflZImOk11G9hwSd+44jvzrc99J35u5l+fbdQ2+ZG441GvOpaeGYBmWquZsbQ==} + '@tanstack/react-query@5.90.12': + resolution: {integrity: sha512-graRZspg7EoEaw0a8faiUASCyJrqjKPdqJ9EwuDRUF9mEYJ1YPczI9H+/agJ0mOJkPCJDk0lsz5QTrLZ/jQ2rg==} peerDependencies: - react: '>=18' - react-dom: '>=18' - typescript: '>=5.4.0' - peerDependenciesMeta: - typescript: - optional: true + react: ^18 || ^19 - date-fns@2.30.0: - resolution: {integrity: sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==} - engines: {node: '>=0.11'} + '@trysound/sax@0.2.0': + resolution: {integrity: sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==} + engines: {node: '>=10.13.0'} - dayjs@1.11.13: - resolution: {integrity: sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==} + '@tsconfig/node10@1.0.12': + resolution: {integrity: sha512-UCYBaeFvM11aU2y3YPZ//O5Rhj+xKyzy7mvcIoAjASbigy8mHMryP5cK7dgjlz2hWxh1g5pLw084E0a/wlUSFQ==} - death@1.1.0: - resolution: {integrity: sha512-vsV6S4KVHvTGxbEcij7hkWRv0It+sGGWVOM67dQde/o5Xjnr+KmLjxWJii2uEObIrt1CcM9w0Yaovx+iOlIL+w==} + '@tsconfig/node12@1.0.11': + resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==} - debug@4.3.4: - resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} - engines: {node: '>=6.0'} + '@tsconfig/node14@1.0.3': + resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==} + + '@tsconfig/node16@1.0.4': + resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==} + + '@typechain/ethers-v6@0.5.1': + resolution: {integrity: sha512-F+GklO8jBWlsaVV+9oHaPh5NJdd6rAKN4tklGfInX1Q7h0xPgVLP39Jl3eCulPB5qexI71ZFHwbljx4ZXNfouA==} peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true + ethers: 6.x + typechain: ^8.3.2 + typescript: '>=4.7.0' - debug@4.4.3: - resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} - engines: {node: '>=6.0'} + '@typechain/hardhat@9.1.0': + resolution: {integrity: sha512-mtaUlzLlkqTlfPwB3FORdejqBskSnh+Jl8AIJGjXNAQfRQ4ofHADPl1+oU7Z3pAJzmZbUXII8MhOLQltcHgKnA==} peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true + '@typechain/ethers-v6': ^0.5.1 + ethers: ^6.1.0 + hardhat: ^2.9.9 + typechain: ^8.3.2 - decamelize@1.2.0: - resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==} - engines: {node: '>=0.10.0'} + '@types/babel__core@7.20.5': + resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} - decamelize@4.0.0: - resolution: {integrity: sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==} - engines: {node: '>=10'} + '@types/babel__generator@7.27.0': + resolution: {integrity: sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==} - decode-uri-component@0.2.2: - resolution: {integrity: sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==} - engines: {node: '>=0.10'} + '@types/babel__template@7.4.4': + resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==} - dedent@1.7.1: - resolution: {integrity: sha512-9JmrhGZpOlEgOLdQgSm0zxFaYoQon408V1v49aqTWuXENVlnCuY9JBZcXZiCsZQWDjTm5Qf/nIvAy77mXDAjEg==} - peerDependencies: - babel-plugin-macros: ^3.1.0 - peerDependenciesMeta: - babel-plugin-macros: - optional: true + '@types/babel__traverse@7.28.0': + resolution: {integrity: sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==} - deep-eql@4.1.4: - resolution: {integrity: sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg==} - engines: {node: '>=6'} + '@types/bn.js@5.2.0': + resolution: {integrity: sha512-DLbJ1BPqxvQhIGbeu8VbUC1DiAiahHtAYvA0ZEAa4P31F7IaArc8z3C3BRQdWX4mtLQuABG4yzp76ZrS02Ui1Q==} - deep-eql@5.0.2: - resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==} - engines: {node: '>=6'} + '@types/body-parser@1.19.6': + resolution: {integrity: sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==} - deep-extend@0.6.0: - resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==} - engines: {node: '>=4.0.0'} + '@types/bonjour@3.5.13': + resolution: {integrity: sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ==} - deep-is@0.1.4: - resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + '@types/chai-as-promised@7.1.8': + resolution: {integrity: sha512-ThlRVIJhr69FLlh6IctTXFkmhtP3NpMZ2QGq69StYLyKZFp/HOp1VdKZj7RvfNWYYcJ1xlbLGLLWj1UvP5u/Gw==} - deep-object-diff@1.1.9: - resolution: {integrity: sha512-Rn+RuwkmkDwCi2/oXOFS9Gsr5lJZu/yTGpK7wAaAIE75CC+LCGEZHpY6VQJa/RoJcrmaA/docWJZvYohlNkWPA==} + '@types/chai@4.3.20': + resolution: {integrity: sha512-/pC9HAB5I/xMlc5FP77qjCnI16ChlJfW0tGa0IUcFn38VJrTV6DeZ60NU5KZBtaOZqjdpwTWohz5HU1RrhiYxQ==} - deepmerge@4.3.1: - resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} - engines: {node: '>=0.10.0'} + '@types/chai@5.2.3': + resolution: {integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==} - define-data-property@1.1.4: - resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} - engines: {node: '>= 0.4'} + '@types/concat-stream@1.6.1': + resolution: {integrity: sha512-eHE4cQPoj6ngxBZMvVf6Hw7Mh4jMW4U9lpGmS5GBPB9RYxlFg+CHaVN7ErNY4W9XfLIEn20b4VDYaIrbq0q4uA==} - defu@6.1.4: - resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==} + '@types/connect-history-api-fallback@1.5.4': + resolution: {integrity: sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw==} - delay@5.0.0: - resolution: {integrity: sha512-ReEBKkIfe4ya47wlPYf/gu5ib6yUG0/Aez0JQZQz94kiWtRQvZIQbTiehsnwHvLSWJnQdhVeqYue7Id1dKr0qw==} - engines: {node: '>=10'} + '@types/connect@3.4.38': + resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==} - delayed-stream@1.0.0: - resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} - engines: {node: '>=0.4.0'} + '@types/debug@4.1.12': + resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==} - depd@2.0.0: - resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} - engines: {node: '>= 0.8'} + '@types/deep-eql@4.0.2': + resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==} - 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==} + '@types/eslint-scope@3.7.7': + resolution: {integrity: sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==} - detect-node-es@1.1.0: - resolution: {integrity: sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==} + '@types/eslint@9.6.1': + resolution: {integrity: sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==} - dexie@4.2.1: - resolution: {integrity: sha512-Ckej0NS6jxQ4Po3OrSQBFddayRhTCic2DoCAG5zacOfOVB9P2Q5Xc5uL/nVa7ZVs+HdMnvUPzLFCB/JwpB6Csg==} + '@types/estree-jsx@1.0.5': + resolution: {integrity: sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==} - didyoumean@1.2.2: - resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==} + '@types/estree@1.0.8': + resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} - diff@4.0.2: - resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} - engines: {node: '>=0.3.1'} + '@types/express-serve-static-core@4.19.8': + resolution: {integrity: sha512-02S5fmqeoKzVZCHPZid4b8JH2eM5HzQLZWN2FohQEy/0eXTq8VXZfSN6Pcr3F6N9R/vNrj7cpgbhjie6m/1tCA==} - diff@5.2.0: - resolution: {integrity: sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==} - engines: {node: '>=0.3.1'} + '@types/express@4.17.25': + resolution: {integrity: sha512-dVd04UKsfpINUnK0yBoYHDF3xu7xVH4BuDotC/xGuycx4CgbP48X/KF/586bcObxT0HENHXEU8Nqtu6NR+eKhw==} - difflib@0.2.4: - resolution: {integrity: sha512-9YVwmMb0wQHQNr5J9m6BSj6fk4pfGITGQOOs+D9Fl+INODWFOfvhIU1hNv6GgR1RBoC/9NJcwu77zShxV0kT7w==} + '@types/form-data@0.0.33': + resolution: {integrity: sha512-8BSvG1kGm83cyJITQMZSulnl6QV8jqAGreJsc5tPu1Jq0vTSOiY/k24Wx82JRpWwZSqrala6sd5rWi6aNXvqcw==} - dijkstrajs@1.0.3: - resolution: {integrity: sha512-qiSlmBq9+BCdCA/L46dw8Uy93mloxsPSbwnm5yrKn2vMPiy8KyAskTF6zuV/j5BMsmOGZDPs7KjU+mjb670kfA==} + '@types/glob@7.2.0': + resolution: {integrity: sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==} - dir-glob@3.0.1: - resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} - engines: {node: '>=8'} + '@types/gtag.js@0.0.12': + resolution: {integrity: sha512-YQV9bUsemkzG81Ea295/nF/5GijnD2Af7QhEofh7xu+kvCN6RdodgNwwGWXB5GMI3NoyvQo0odNctoH/qLMIpg==} - dlv@1.1.3: - resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==} + '@types/hast@3.0.4': + resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==} - dotenv@16.6.1: - resolution: {integrity: sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==} - engines: {node: '>=12'} + '@types/history@4.7.11': + resolution: {integrity: sha512-qjDJRrmvBMiTx+jyLxvLfJU7UznFuokDv4f3WRuriHKERccVpFU+8XMQUAbDzoiJCsmexxRExQeMwwCdamSKDA==} - dunder-proto@1.0.1: - resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} - engines: {node: '>= 0.4'} + '@types/html-minifier-terser@6.1.0': + resolution: {integrity: sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg==} - duplexify@4.1.3: - resolution: {integrity: sha512-M3BmBhwJRZsSx38lZyhE53Csddgzl5R7xGJNk7CVddZD6CcmwMCH8J+7AprIrQKH7TonKxaCjcv27Qmf+sQ+oA==} + '@types/http-cache-semantics@4.0.4': + resolution: {integrity: sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==} - eciesjs@0.4.16: - resolution: {integrity: sha512-dS5cbA9rA2VR4Ybuvhg6jvdmp46ubLn3E+px8cG/35aEDNclrqoCjg6mt0HYZ/M+OoESS3jSkCrqk1kWAEhWAw==} - engines: {bun: '>=1', deno: '>=2', node: '>=16'} + '@types/http-errors@2.0.5': + resolution: {integrity: sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg==} - electron-to-chromium@1.5.267: - resolution: {integrity: sha512-0Drusm6MVRXSOJpGbaSVgcQsuB4hEkMpHXaVstcPmhu5LIedxs1xNK/nIxmQIU/RPC0+1/o0AVZfBTkTNJOdUw==} + '@types/http-proxy@1.17.17': + resolution: {integrity: sha512-ED6LB+Z1AVylNTu7hdzuBqOgMnvG/ld6wGCG8wFnAzKX5uyW2K3WD52v0gnLCTK/VLpXtKckgWuyScYK6cSPaw==} - elliptic@6.6.1: - resolution: {integrity: sha512-RaddvvMatK2LJHqFJ+YA4WysVN5Ita9E35botqIYspQ4TkRAlCicdzKOjlyv/1Za5RyTNn7di//eEV0uTAfe3g==} + '@types/istanbul-lib-coverage@2.0.6': + resolution: {integrity: sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==} - emoji-regex@8.0.0: - resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + '@types/istanbul-lib-report@3.0.3': + resolution: {integrity: sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==} - encode-utf8@1.0.3: - resolution: {integrity: sha512-ucAnuBEhUK4boH2HjVYG5Q2mQyPorvv0u/ocS+zhdw0S8AlHYY+GOFhP1Gio5z4icpP2ivFSvhtFjQi8+T9ppw==} + '@types/istanbul-reports@3.0.4': + resolution: {integrity: sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==} - end-of-stream@1.4.5: - resolution: {integrity: sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==} + '@types/json-schema@7.0.15': + resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} - engine.io-client@6.6.3: - resolution: {integrity: sha512-T0iLjnyNWahNyv/lcjS2y4oE358tVS/SYQNxYXGAJ9/GLgH4VCvOQ/mhTjqU88mLZCQgiG8RIegFHYCdVC+j5w==} + '@types/lodash@4.17.21': + resolution: {integrity: sha512-FOvQ0YPD5NOfPgMzJihoT+Za5pdkDJWcbpuj1DjaKZIr/gxodQjY/uWEFlTNqW2ugXHUiL8lRQgw63dzKHZdeQ==} - engine.io-parser@5.2.3: - resolution: {integrity: sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q==} - engines: {node: '>=10.0.0'} + '@types/mdast@4.0.4': + resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==} - enquirer@2.4.1: - resolution: {integrity: sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==} - engines: {node: '>=8.6'} + '@types/mdx@2.0.13': + resolution: {integrity: sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw==} - env-paths@2.2.1: - resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==} - engines: {node: '>=6'} + '@types/mime@1.3.5': + resolution: {integrity: sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==} - es-define-property@1.0.1: - resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} - engines: {node: '>= 0.4'} + '@types/minimatch@6.0.0': + resolution: {integrity: sha512-zmPitbQ8+6zNutpwgcQuLcsEpn/Cj54Kbn7L5pX0Os5kdWplB7xPgEh/g+SWOB/qmows2gpuCaPyduq8ZZRnxA==} + deprecated: This is a stub types definition. minimatch provides its own type definitions, so you do not need this installed. - es-errors@1.3.0: - resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} - engines: {node: '>= 0.4'} + '@types/mocha@10.0.10': + resolution: {integrity: sha512-xPyYSz1cMPnJQhl0CLMH68j3gprKZaTjG3s5Vi+fDgx+uhG9NOXwbVt52eFS8ECyXhyKcjDLCBEqBExKuiZb7Q==} - es-module-lexer@1.7.0: - resolution: {integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==} + '@types/ms@2.1.0': + resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==} - es-object-atoms@1.1.1: - resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} - engines: {node: '>= 0.4'} + '@types/node@10.17.60': + resolution: {integrity: sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==} - es-set-tostringtag@2.1.0: - resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} - engines: {node: '>= 0.4'} + '@types/node@12.20.55': + resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==} - es-toolkit@1.33.0: - resolution: {integrity: sha512-X13Q/ZSc+vsO1q600bvNK4bxgXMkHcf//RxCmYDaRY5DAcT+eoXjY5hoAPGMdRnWQjvyLEcyauG3b6hz76LNqg==} + '@types/node@17.0.45': + resolution: {integrity: sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==} - es6-promise@4.2.8: - resolution: {integrity: sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==} + '@types/node@20.19.27': + resolution: {integrity: sha512-N2clP5pJhB2YnZJ3PIHFk5RkygRX5WO/5f0WC08tp0wd+sv0rsJk3MqWn3CbNmT2J505a5336jaQj4ph1AdMug==} - es6-promisify@5.0.0: - resolution: {integrity: sha512-C+d6UdsYDk0lMebHNR4S2NybQMMngAOnOwYBQjTOiv0MkoJMP0Myw2mgpDLBcpfCmRLxyFqYhS/CfOENq4SJhQ==} + '@types/node@22.7.5': + resolution: {integrity: sha512-jML7s2NAzMWc//QSJ1a3prpk78cOPchGvXJsC3C6R6PSMoooztvRVQEz89gmBTBY1SPMaqo5teB4uNHPdetShQ==} - esbuild@0.21.5: - resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==} - engines: {node: '>=12'} - hasBin: true + '@types/node@8.10.66': + resolution: {integrity: sha512-tktOkFUA4kXx2hhhrB8bIFb5TbwzS4uOhKEmwiD+NoiL0qtP2OQ9mFldbgD4dV1djrlBYP6eBuQZiWjuHUpqFw==} - escalade@3.2.0: - resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} - engines: {node: '>=6'} + '@types/pbkdf2@3.1.2': + resolution: {integrity: sha512-uRwJqmiXmh9++aSu1VNEn3iIxWOhd8AHXNSdlaLfdAAdSTY9jYVeGWnzejM3dvrkbqE3/hyQkQQ29IFATEGlew==} - escape-string-regexp@1.0.5: - resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} - engines: {node: '>=0.8.0'} + '@types/prettier@2.7.3': + resolution: {integrity: sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA==} - escape-string-regexp@4.0.0: - resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} - engines: {node: '>=10'} + '@types/prismjs@1.26.5': + resolution: {integrity: sha512-AUZTa7hQ2KY5L7AmtSiqxlhWxb4ina0yd8hNbl4TWuqnv/pFP0nDMb3YrfSBf4hJVGLh2YEIBfKaBW/9UEl6IQ==} - escodegen@1.8.1: - resolution: {integrity: sha512-yhi5S+mNTOuRvyW4gWlg5W1byMaQGWWSYHXsuFZ7GBo7tpyOwi2EdzMP/QWxh9hwkD2m+wDVHJsxhRIj+v/b/A==} - engines: {node: '>=0.12.0'} - hasBin: true + '@types/prop-types@15.7.15': + resolution: {integrity: sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==} - esprima@2.7.3: - resolution: {integrity: sha512-OarPfz0lFCiW4/AV2Oy1Rp9qu0iusTKqykwTspGCZtPxmF81JR4MmIebvF1F9+UOKth2ZubLQ4XGGaU+hSn99A==} - engines: {node: '>=0.10.0'} - hasBin: true + '@types/qs@6.14.0': + resolution: {integrity: sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ==} - esprima@4.0.1: - resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} - engines: {node: '>=4'} - hasBin: true + '@types/range-parser@1.2.7': + resolution: {integrity: sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==} - estraverse@1.9.3: - resolution: {integrity: sha512-25w1fMXQrGdoquWnScXZGckOv+Wes+JDnuN/+7ex3SauFRS72r2lFDec0EKPt2YD1wUJ/IrfEex+9yp4hfSOJA==} - engines: {node: '>=0.10.0'} + '@types/react-dom@18.3.7': + resolution: {integrity: sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ==} + peerDependencies: + '@types/react': ^18.0.0 - estree-walker@3.0.3: - resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} + '@types/react-router-config@5.0.11': + resolution: {integrity: sha512-WmSAg7WgqW7m4x8Mt4N6ZyKz0BubSj/2tVUMsAHp+Yd2AMwcSbeFq9WympT19p5heCFmF97R9eD5uUR/t4HEqw==} - esutils@2.0.3: - resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} - engines: {node: '>=0.10.0'} + '@types/react-router-dom@5.3.3': + resolution: {integrity: sha512-kpqnYK4wcdm5UaWI3fLcELopqLrHgLqNsdpHauzlQktfkHL3npOSwtj1Uz9oKBAzs7lFtVkV8j83voAz2D8fhw==} - eth-block-tracker@7.1.0: - resolution: {integrity: sha512-8YdplnuE1IK4xfqpf4iU7oBxnOYAc35934o083G8ao+8WM8QQtt/mVlAY6yIAdY1eMeLqg4Z//PZjJGmWGPMRg==} - engines: {node: '>=14.0.0'} + '@types/react-router@5.1.20': + resolution: {integrity: sha512-jGjmu/ZqS7FjSH6owMcD5qpq19+1RS9DeVRqfl1FeBMxTDQAGwlMWOcs52NDoXaNKyG3d1cYQFMs9rCrb88o9Q==} - eth-gas-reporter@0.2.27: - resolution: {integrity: sha512-femhvoAM7wL0GcI8ozTdxfuBtBFJ9qsyIAsmKVjlWAHUbdnnXHt+lKzz/kmldM5lA9jLuNHGwuIxorNpLbR1Zw==} - peerDependencies: - '@codechecks/client': ^0.1.0 - peerDependenciesMeta: - '@codechecks/client': - optional: true + '@types/react@18.3.27': + resolution: {integrity: sha512-cisd7gxkzjBKU2GgdYrTdtQx1SORymWyaAFhaxQPK9bYO9ot3Y5OikQRvY0VYQtvwjeQnizCINJAenh/V7MK2w==} - eth-json-rpc-filters@6.0.1: - resolution: {integrity: sha512-ITJTvqoCw6OVMLs7pI8f4gG92n/St6x80ACtHodeS+IXmO0w+t1T5OOzfSt7KLSMLRkVUoexV7tztLgDxg+iig==} - engines: {node: '>=14.0.0'} + '@types/retry@0.12.2': + resolution: {integrity: sha512-XISRgDJ2Tc5q4TRqvgJtzsRkFYNJzZrhTdtMoGVBttwzzQJkPnS3WWTFc7kuDRoPtPakl+T+OfdEUjYJj7Jbow==} - eth-query@2.1.2: - resolution: {integrity: sha512-srES0ZcvwkR/wd5OQBRA1bIJMww1skfGS0s8wlwK3/oNP4+wnds60krvu5R1QbpRQjMmpG5OMIWro5s7gvDPsA==} + '@types/sax@1.2.7': + resolution: {integrity: sha512-rO73L89PJxeYM3s3pPPjiPgVVcymqU490g0YO5n5By0k2Erzj6tay/4lr1CHAAU4JyOWd1rpQ8bCf6cZfHU96A==} - eth-rpc-errors@4.0.3: - resolution: {integrity: sha512-Z3ymjopaoft7JDoxZcEb3pwdGh7yiYMhOwm2doUt6ASXlMavpNlK6Cre0+IMl2VSGyEU9rkiperQhp5iRxn5Pg==} + '@types/secp256k1@4.0.7': + resolution: {integrity: sha512-Rcvjl6vARGAKRO6jHeKMatGrvOMGrR/AR11N1x2LqintPCyDZ7NBhrh238Z2VZc7aM7KIwnFpFQ7fnfK4H/9Qw==} - ethereum-bloom-filters@1.2.0: - resolution: {integrity: sha512-28hyiE7HVsWubqhpVLVmZXFd4ITeHi+BUu05o9isf0GUpMtzBUi+8/gFrGaGYzvGAJQmJ3JKj77Mk9G98T84rA==} + '@types/send@0.17.6': + resolution: {integrity: sha512-Uqt8rPBE8SY0RK8JB1EzVOIZ32uqy8HwdxCnoCOsYrvnswqmFZ/k+9Ikidlk/ImhsdvBsloHbAlewb2IEBV/Og==} - ethereum-cryptography@0.1.3: - resolution: {integrity: sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==} + '@types/send@1.2.1': + resolution: {integrity: sha512-arsCikDvlU99zl1g69TcAB3mzZPpxgw0UQnaHeC1Nwb015xp8bknZv5rIfri9xTOcMuaVgvabfIRA7PSZVuZIQ==} - ethereum-cryptography@1.2.0: - resolution: {integrity: sha512-6yFQC9b5ug6/17CQpCyE3k9eKBMdhyVjzUy1WkiuY/E4vj/SXDBbCw8QEIaXqf0Mf2SnY6RmpDcwlUmBSS0EJw==} + '@types/serve-index@1.9.4': + resolution: {integrity: sha512-qLpGZ/c2fhSs5gnYsQxtDEq3Oy8SXPClIXkW5ghvAvsNuVSA8k+gCONcUCS/UjLEYvYps+e8uBtfgXgvhwfNug==} - ethereum-cryptography@2.2.1: - resolution: {integrity: sha512-r/W8lkHSiTLxUxW8Rf3u4HGB0xQweG2RyETjywylKZSzLWoWAijRz8WCuOtJ6wah+avllXBqZuk29HCCvhEIRg==} + '@types/serve-static@1.15.10': + resolution: {integrity: sha512-tRs1dB+g8Itk72rlSI2ZrW6vZg0YrLI81iQSTkMmOqnqCaNr/8Ek4VwWcN5vZgCYWbg/JJSGBlUaYGAOP73qBw==} - ethereumjs-util@7.1.5: - resolution: {integrity: sha512-SDl5kKrQAudFBUe5OJM9Ac6WmMyYmXX/6sTmLZ3ffG2eY6ZIGBes3pEDxNN6V72WyOw4CPD5RomKdsa8DAAwLg==} - engines: {node: '>=10.0.0'} + '@types/sockjs@0.3.36': + resolution: {integrity: sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q==} - ethers@5.8.0: - resolution: {integrity: sha512-DUq+7fHrCg1aPDFCHx6UIPb3nmt2XMpM7Y/g2gLhsl3lIBqeAfOJIl1qEvRf2uq3BiKxmh6Fh5pfp2ieyek7Kg==} + '@types/trusted-types@2.0.7': + resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==} - ethers@6.16.0: - resolution: {integrity: sha512-U1wulmetNymijEhpSEQ7Ct/P/Jw9/e7R1j5XIbPRydgV2DjLVMsULDlNksq3RQnFgKoLlZf88ijYtWEXcPa07A==} - engines: {node: '>=14.0.0'} + '@types/unist@2.0.11': + resolution: {integrity: sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==} - ethjs-unit@0.1.6: - resolution: {integrity: sha512-/Sn9Y0oKl0uqQuvgFk/zQgR7aw1g36qX/jzSQ5lSwlO0GigPymk4eGQfeNTD03w1dPOqfz8V77Cy43jH56pagw==} - engines: {node: '>=6.5.0', npm: '>=3'} + '@types/unist@3.0.3': + resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} - eventemitter2@6.4.9: - resolution: {integrity: sha512-JEPTiaOt9f04oa6NOkc4aH+nVp5I3wEjpHbIPqfgCdD5v5bUzy7xQqwcVO2aDQgOWhI28da57HksMrzK9HlRxg==} + '@types/uuid@8.3.4': + resolution: {integrity: sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw==} - eventemitter3@5.0.1: - resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==} + '@types/ws@7.4.7': + resolution: {integrity: sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww==} - events@3.3.0: - resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} - engines: {node: '>=0.8.x'} + '@types/ws@8.18.1': + resolution: {integrity: sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==} - evp_bytestokey@1.0.3: - resolution: {integrity: sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==} + '@types/yargs-parser@21.0.3': + resolution: {integrity: sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==} - expect-type@1.3.0: - resolution: {integrity: sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==} - engines: {node: '>=12.0.0'} + '@types/yargs@17.0.35': + resolution: {integrity: sha512-qUHkeCyQFxMXg79wQfTtfndEC+N9ZZg76HJftDJp+qH2tV7Gj4OJi7l+PiWwJ+pWtW8GwSmqsDj/oymhrTWXjg==} - extension-port-stream@3.0.0: - resolution: {integrity: sha512-an2S5quJMiy5bnZKEf6AkfH/7r8CzHvhchU40gxN+OM6HPhe7Z9T1FUychcf2M9PpPOO0Hf7BAEfJkw2TDIBDw==} - engines: {node: '>=12.0.0'} + '@ungap/structured-clone@1.3.0': + resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==} - eyes@0.1.8: - resolution: {integrity: sha512-GipyPsXO1anza0AOZdy69Im7hGFCNB7Y/NGjDlZGJ3GJJLtwNSb2vrzYrTYJRrRloVx7pl+bhUaTB8yiccPvFQ==} - engines: {node: '> 0.1.90'} + '@uniswap/lib@4.0.1-alpha': + resolution: {integrity: sha512-f6UIliwBbRsgVLxIaBANF6w09tYqc6Y/qXdsrbEmXHyFA7ILiKrIwRFXe1yOg8M3cksgVsO9N7yuL2DdCGQKBA==} + engines: {node: '>=10'} - fast-base64-decode@1.0.0: - resolution: {integrity: sha512-qwaScUgUGBYeDNRnbc/KyllVU88Jk1pRHPStuF/lO7B0/RTRLj7U0lkdTAutlBblY08rwZDff6tNU9cjv6j//Q==} + '@uniswap/v2-core@1.0.1': + resolution: {integrity: sha512-MtybtkUPSyysqLY2U210NBDeCHX+ltHt3oADGdjqoThZaFRDKwM6k1Nb3F0A3hk5hwuQvytFWhrWHOEq6nVJ8Q==} + engines: {node: '>=10'} - fast-deep-equal@3.1.3: - resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + '@uniswap/v3-core@1.0.1': + resolution: {integrity: sha512-7pVk4hEm00j9tc71Y9+ssYpO6ytkeI0y7WE9P6UcmNzhxPePwyAxImuhVsTqWK9YFvzgtvzJHi64pBl4jUzKMQ==} + engines: {node: '>=10'} - fast-glob@3.3.3: - resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} - engines: {node: '>=8.6.0'} + '@uniswap/v3-periphery@1.4.4': + resolution: {integrity: sha512-S4+m+wh8HbWSO3DKk4LwUCPZJTpCugIsHrWR86m/OrUyvSqGDTXKFfc2sMuGXCZrD1ZqO3rhQsKgdWg3Hbb2Kw==} + engines: {node: '>=10'} - fast-levenshtein@2.0.6: - resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + '@vanilla-extract/css@1.17.3': + resolution: {integrity: sha512-jHivr1UPoJTX5Uel4AZSOwrCf4mO42LcdmnhJtUxZaRWhW4FviFbIfs0moAWWld7GOT+2XnuVZjjA/K32uUnMQ==} - fast-redact@3.5.0: - resolution: {integrity: sha512-dwsoQlS7h9hMeYUq1W++23NDcBLV4KqONnITDV9DjfS3q1SgDGVrBdvvTLUotWtPSD7asWDV9/CmsZPy8Hf70A==} - engines: {node: '>=6'} + '@vanilla-extract/dynamic@2.1.4': + resolution: {integrity: sha512-7+Ot7VlP3cIzhJnTsY/kBtNs21s0YD7WI1rKJJKYP56BkbDxi/wrQUWMGEczKPUDkJuFcvbye+E2ub1u/mHH9w==} - fast-safe-stringify@2.1.1: - resolution: {integrity: sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==} + '@vanilla-extract/private@1.0.9': + resolution: {integrity: sha512-gT2jbfZuaaCLrAxwXbRgIhGhcXbRZCG3v4TTUnjw0EJ7ArdBRxkq4msNJkbuRkCgfIK5ATmprB5t9ljvLeFDEA==} - fast-stable-stringify@1.0.0: - resolution: {integrity: sha512-wpYMUmFu5f00Sm0cj2pfivpmawLZ0NKdviQ4w9zJeR8JVtOpOxHmLaJuj0vxvGqMJQWyP/COUkF75/57OKyRag==} + '@vanilla-extract/sprinkles@1.6.4': + resolution: {integrity: sha512-lW3MuIcdIeHKX81DzhTnw68YJdL1ial05exiuvTLJMdHXQLKcVB93AncLPajMM6mUhaVVx5ALZzNHMTrq/U9Hg==} + peerDependencies: + '@vanilla-extract/css': ^1.0.0 - fast-uri@3.1.0: - resolution: {integrity: sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==} - - fast-xml-parser@5.2.5: - resolution: {integrity: sha512-pfX9uG9Ki0yekDHx2SiuRIyFdyAr1kMIMitPvb0YBo8SUfKvia7w7FIyd/l6av85pFYRhZscS75MwMnbvY+hcQ==} - hasBin: true - - fastestsmallesttextencoderdecoder@1.0.22: - resolution: {integrity: sha512-Pb8d48e+oIuY4MaM64Cd7OW1gt4nxCHs7/ddPPZ/Ic3sg8yVGM7O9wDvZ7us6ScaUupzM+pfBolwtYhN1IxBIw==} + '@vitejs/plugin-react@4.7.0': + resolution: {integrity: sha512-gUu9hwfWvvEDBBmgtAowQCojwZmJ5mcLn3aufeCsitijs3+f2NsrPtlAWIR6OPiqljl96GVCUbLe0HyqIpVaoA==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + vite: ^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 - fastq@1.19.1: - resolution: {integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==} + '@vitest/expect@3.2.4': + resolution: {integrity: sha512-Io0yyORnB6sikFlt8QW5K7slY4OjqNX9jmJQ02QDda8lyM6B5oNgVWoSoKPac8/kgnCUzuHQKrSLtu/uOqqrig==} - fdir@6.5.0: - resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} - engines: {node: '>=12.0.0'} + '@vitest/mocker@3.2.4': + resolution: {integrity: sha512-46ryTE9RZO/rfDd7pEqFl7etuyzekzEhUbTW3BvmeO/BcCMEgq59BKhek3dXDWgAj4oMK6OZi+vRr1wPW6qjEQ==} peerDependencies: - picomatch: ^3 || ^4 + msw: ^2.4.9 + vite: ^5.0.0 || ^6.0.0 || ^7.0.0-0 peerDependenciesMeta: - picomatch: + msw: + optional: true + vite: optional: true - fill-range@7.1.1: - resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} - engines: {node: '>=8'} + '@vitest/pretty-format@3.2.4': + resolution: {integrity: sha512-IVNZik8IVRJRTr9fxlitMKeJeXFFFN0JaB9PHPGQ8NKQbGpfjlTx9zO4RefN8gp7eqjNy8nyK3NZmBzOPeIxtA==} - filter-obj@1.1.0: - resolution: {integrity: sha512-8rXg1ZnX7xzy2NGDVkBVaAy+lSlPNwad13BtgSlLuxfIslyt5Vg64U7tFcCt4WS1R0hvtnQybT/IyCkGZ3DpXQ==} - engines: {node: '>=0.10.0'} + '@vitest/runner@3.2.4': + resolution: {integrity: sha512-oukfKT9Mk41LreEW09vt45f8wx7DordoWUZMYdY/cyAk7w5TWkTRCNZYF7sX7n2wB7jyGAl74OxgwhPgKaqDMQ==} - find-replace@3.0.0: - resolution: {integrity: sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ==} - engines: {node: '>=4.0.0'} + '@vitest/snapshot@3.2.4': + resolution: {integrity: sha512-dEYtS7qQP2CjU27QBC5oUOxLE/v5eLkGqPE0ZKEIDGMs4vKWe7IjgLOeauHsR0D5YuuycGRO5oSRXnwnmA78fQ==} - find-up@4.1.0: - resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} - engines: {node: '>=8'} + '@vitest/spy@3.2.4': + resolution: {integrity: sha512-vAfasCOe6AIK70iP5UD11Ac4siNUNJ9i/9PZ3NKx07sG6sUxeag1LWdNrMWeKKYBLlzuK+Gn65Yd5nyL6ds+nw==} - find-up@5.0.0: - resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} - engines: {node: '>=10'} + '@vitest/utils@3.2.4': + resolution: {integrity: sha512-fB2V0JFrQSMsCo9HiSq3Ezpdv4iYaXRG1Sx8edX3MwxfyNn83mKiGzOcH+Fkxt4MHxr3y42fQi1oeAInqgX2QA==} - flat@5.0.2: - resolution: {integrity: sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==} - hasBin: true + '@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 - follow-redirects@1.15.11: - resolution: {integrity: sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==} - engines: {node: '>=4.0'} + '@wagmi/core@2.22.1': + resolution: {integrity: sha512-cG/xwQWsBEcKgRTkQVhH29cbpbs/TdcUJVFXCyri3ZknxhMyGv0YEjTcrNpRgt2SaswL1KrvslSNYKKo+5YEAg==} peerDependencies: - debug: '*' + '@tanstack/query-core': '>=5.0.0' + typescript: '>=5.0.4' + viem: 2.x peerDependenciesMeta: - debug: + '@tanstack/query-core': + optional: true + typescript: optional: true - for-each@0.3.5: - resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==} - engines: {node: '>= 0.4'} + '@walletconnect/core@2.21.0': + resolution: {integrity: sha512-o6R7Ua4myxR8aRUAJ1z3gT9nM+jd2B2mfamu6arzy1Cc6vi10fIwFWb6vg3bC8xJ6o9H3n/cN5TOW3aA9Y1XVw==} + engines: {node: '>=18'} - form-data@2.5.5: - resolution: {integrity: sha512-jqdObeR2rxZZbPSGL+3VckHMYtu+f9//KXBsVny6JSX/pa38Fy+bGjuG8eW/H6USNQWhLi8Num++cU2yOCNz4A==} - engines: {node: '>= 0.12'} + '@walletconnect/core@2.21.1': + resolution: {integrity: sha512-Tp4MHJYcdWD846PH//2r+Mu4wz1/ZU/fr9av1UWFiaYQ2t2TPLDiZxjLw54AAEpMqlEHemwCgiRiAmjR1NDdTQ==} + engines: {node: '>=18'} - form-data@4.0.5: - resolution: {integrity: sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==} - engines: {node: '>= 6'} + '@walletconnect/environment@1.0.1': + resolution: {integrity: sha512-T426LLZtHj8e8rYnKfzsw1aG6+M0BT1ZxayMdv/p8yM0MU+eJDISqNY3/bccxRr4LrF9csq02Rhqt08Ibl0VRg==} - fp-ts@1.19.3: - resolution: {integrity: sha512-H5KQDspykdHuztLTg+ajGN0Z2qUjcEf3Ybxc6hLt0k7/zPkn29XnKnxlBPyW2XIddWrGaJBzBl4VLYOtk39yZg==} + '@walletconnect/ethereum-provider@2.21.1': + resolution: {integrity: sha512-SSlIG6QEVxClgl1s0LMk4xr2wg4eT3Zn/Hb81IocyqNSGfXpjtawWxKxiC5/9Z95f1INyBD6MctJbL/R1oBwIw==} - fraction.js@5.3.4: - resolution: {integrity: sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ==} + '@walletconnect/events@1.0.1': + resolution: {integrity: sha512-NPTqaoi0oPBVNuLv7qPaJazmGHs5JGyO8eEAk5VGKmJzDR7AHzD4k6ilox5kxk1iwiOnFopBOOMLs86Oa76HpQ==} - framer-motion@12.23.26: - resolution: {integrity: sha512-cPcIhgR42xBn1Uj+PzOyheMtZ73H927+uWPDVhUMqxy8UHt6Okavb6xIz9J/phFUHUj0OncR6UvMfJTXoc/LKA==} + '@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: - '@emotion/is-prop-valid': '*' - react: ^18.0.0 || ^19.0.0 - react-dom: ^18.0.0 || ^19.0.0 + '@react-native-async-storage/async-storage': 1.x peerDependenciesMeta: - '@emotion/is-prop-valid': - optional: true - react: - optional: true - react-dom: + '@react-native-async-storage/async-storage': optional: true - fs-extra@10.1.0: - resolution: {integrity: sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==} - engines: {node: '>=12'} + '@walletconnect/logger@2.1.2': + resolution: {integrity: sha512-aAb28I3S6pYXZHQm5ESB+V6rDqIYfsnHaQyzFbwUUBFY4H0OXx/YtTl8lvhUNhMMfb9UxbwEBS253TlXUYJWSw==} - fs-extra@7.0.1: - resolution: {integrity: sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==} - engines: {node: '>=6 <7 || >=8'} + '@walletconnect/relay-api@1.0.11': + resolution: {integrity: sha512-tLPErkze/HmC9aCmdZOhtVmYZq1wKfWTJtygQHoWtgg722Jd4homo54Cs4ak2RUFUZIGO2RsOpIcWipaua5D5Q==} - fs-extra@8.1.0: - resolution: {integrity: sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==} - engines: {node: '>=6 <7 || >=8'} + '@walletconnect/relay-auth@1.1.0': + resolution: {integrity: sha512-qFw+a9uRz26jRCDgL7Q5TA9qYIgcNY8jpJzI1zAWNZ8i7mQjaijRnWFKsCHAU9CyGjvt6RKrRXyFtFOpWTVmCQ==} - fs-extra@9.1.0: - resolution: {integrity: sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==} - engines: {node: '>=10'} + '@walletconnect/safe-json@1.0.2': + resolution: {integrity: sha512-Ogb7I27kZ3LPC3ibn8ldyUr5544t3/STow9+lzz7Sfo808YD7SBWk7SAsdBFlYgP2zDRy2hS3sKRcuSRM0OTmA==} - fs-readdir-recursive@1.1.0: - resolution: {integrity: sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA==} + '@walletconnect/sign-client@2.21.0': + resolution: {integrity: sha512-z7h+PeLa5Au2R591d/8ZlziE0stJvdzP9jNFzFolf2RG/OiXulgFKum8PrIyXy+Rg2q95U9nRVUF9fWcn78yBA==} - fs.realpath@1.0.0: - resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + '@walletconnect/sign-client@2.21.1': + resolution: {integrity: sha512-QaXzmPsMnKGV6tc4UcdnQVNOz4zyXgarvdIQibJ4L3EmLat73r5ZVl4c0cCOcoaV7rgM9Wbphgu5E/7jNcd3Zg==} - fsevents@2.3.3: - resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} - engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} - os: [darwin] + '@walletconnect/time@1.0.2': + resolution: {integrity: sha512-uzdd9woDcJ1AaBZRhqy5rNC9laqWGErfc4dxA9a87mPdKOgWMD85mcFo9dIYIts/Jwocfwn07EC6EzclKubk/g==} - function-bind@1.1.2: - resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + '@walletconnect/types@2.21.0': + resolution: {integrity: sha512-ll+9upzqt95ZBWcfkOszXZkfnpbJJ2CmxMfGgE5GmhdxxxCcO5bGhXkI+x8OpiS555RJ/v/sXJYMSOLkmu4fFw==} - generator-function@2.0.1: - resolution: {integrity: sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==} - engines: {node: '>= 0.4'} + '@walletconnect/types@2.21.1': + resolution: {integrity: sha512-UeefNadqP6IyfwWC1Yi7ux+ljbP2R66PLfDrDm8izmvlPmYlqRerJWJvYO4t0Vvr9wrG4Ko7E0c4M7FaPKT/sQ==} - gensync@1.0.0-beta.2: - resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} - engines: {node: '>=6.9.0'} + '@walletconnect/universal-provider@2.21.0': + resolution: {integrity: sha512-mtUQvewt+X0VBQay/xOJBvxsB3Xsm1lTwFjZ6WUwSOTR1X+FNb71hSApnV5kbsdDIpYPXeQUbGt2se1n5E5UBg==} - get-caller-file@2.0.5: - resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} - engines: {node: 6.* || 8.* || >= 10.*} + '@walletconnect/universal-provider@2.21.1': + resolution: {integrity: sha512-Wjx9G8gUHVMnYfxtasC9poGm8QMiPCpXpbbLFT+iPoQskDDly8BwueWnqKs4Mx2SdIAWAwuXeZ5ojk5qQOxJJg==} - get-func-name@2.0.2: - resolution: {integrity: sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==} + '@walletconnect/utils@2.21.0': + resolution: {integrity: sha512-zfHLiUoBrQ8rP57HTPXW7rQMnYxYI4gT9yTACxVW6LhIFROTF6/ytm5SKNoIvi4a5nX5dfXG4D9XwQUCu8Ilig==} - get-intrinsic@1.3.0: - resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} - engines: {node: '>= 0.4'} + '@walletconnect/utils@2.21.1': + resolution: {integrity: sha512-VPZvTcrNQCkbGOjFRbC24mm/pzbRMUq2DSQoiHlhh0X1U7ZhuIrzVtAoKsrzu6rqjz0EEtGxCr3K1TGRqDG4NA==} - get-nonce@1.0.1: - resolution: {integrity: sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==} - engines: {node: '>=6'} + '@walletconnect/window-getters@1.0.1': + resolution: {integrity: sha512-vHp+HqzGxORPAN8gY03qnbTMnhqIwjeRJNOMOAzePRg4xVEEE2WvYsI9G2NMjOknA8hnuYbU3/hwLcKbjhc8+Q==} - get-port@3.2.0: - resolution: {integrity: sha512-x5UJKlgeUiNT8nyo/AcnwLnZuZNcSjSw0kogRB+Whd1fjjFq4B1hySFxSFWWSn4mIBzg3sRNUDFYc4g5gjPoLg==} - engines: {node: '>=4'} + '@walletconnect/window-metadata@1.0.1': + resolution: {integrity: sha512-9koTqyGrM2cqFRW517BPY/iEtUDx2r1+Pwwu5m7sJ7ka79wi3EyqhqcICk/yDmv6jAS1rjKgTKXlEhanYjijcA==} - get-proto@1.0.1: - resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} - engines: {node: '>= 0.4'} + '@webassemblyjs/ast@1.14.1': + resolution: {integrity: sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==} - ghost-testrpc@0.0.2: - resolution: {integrity: sha512-i08dAEgJ2g8z5buJIrCTduwPIhih3DP+hOCTyyryikfV8T0bNvHnGXO67i0DD1H4GBDETTclPy9njZbfluQYrQ==} - hasBin: true + '@webassemblyjs/floating-point-hex-parser@1.13.2': + resolution: {integrity: sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==} - glob-parent@5.1.2: - resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} - engines: {node: '>= 6'} + '@webassemblyjs/helper-api-error@1.13.2': + resolution: {integrity: sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==} - glob-parent@6.0.2: - resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} - engines: {node: '>=10.13.0'} + '@webassemblyjs/helper-buffer@1.14.1': + resolution: {integrity: sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==} - glob@5.0.15: - resolution: {integrity: sha512-c9IPMazfRITpmAAKi22dK1VKxGDX9ehhqfABDriL/lzO92xcUKEJPQHrVA/2YHSNFB4iFlykVmWvwo48nr3OxA==} - deprecated: Glob versions prior to v9 are no longer supported + '@webassemblyjs/helper-numbers@1.13.2': + resolution: {integrity: sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==} - glob@7.1.7: - resolution: {integrity: sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==} - deprecated: Glob versions prior to v9 are no longer supported + '@webassemblyjs/helper-wasm-bytecode@1.13.2': + resolution: {integrity: sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==} - glob@7.2.3: - resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} - deprecated: Glob versions prior to v9 are no longer supported + '@webassemblyjs/helper-wasm-section@1.14.1': + resolution: {integrity: sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==} - glob@8.1.0: - resolution: {integrity: sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==} - engines: {node: '>=12'} - deprecated: Glob versions prior to v9 are no longer supported + '@webassemblyjs/ieee754@1.13.2': + resolution: {integrity: sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==} - global-modules@2.0.0: - resolution: {integrity: sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==} - engines: {node: '>=6'} + '@webassemblyjs/leb128@1.13.2': + resolution: {integrity: sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==} - global-prefix@3.0.0: - resolution: {integrity: sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==} - engines: {node: '>=6'} + '@webassemblyjs/utf8@1.13.2': + resolution: {integrity: sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==} - globby@10.0.2: - resolution: {integrity: sha512-7dUi7RvCoT/xast/o/dLN53oqND4yk0nsHkhRgn9w65C4PofCLOoJ39iSOg+qVDdWQPIEj+eszMHQ+aLVwwQSg==} - engines: {node: '>=8'} + '@webassemblyjs/wasm-edit@1.14.1': + resolution: {integrity: sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==} - gopd@1.2.0: - resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} - engines: {node: '>= 0.4'} + '@webassemblyjs/wasm-gen@1.14.1': + resolution: {integrity: sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==} - graceful-fs@4.2.11: - resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + '@webassemblyjs/wasm-opt@1.14.1': + resolution: {integrity: sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==} - h3@1.15.4: - resolution: {integrity: sha512-z5cFQWDffyOe4vQ9xIqNfCZdV4p//vy6fBnr8Q1AWnVZ0teurKMG66rLj++TKwKPUP3u7iMUvrvKaEUiQw2QWQ==} + '@webassemblyjs/wasm-parser@1.14.1': + resolution: {integrity: sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==} - handlebars@4.7.8: - resolution: {integrity: sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==} - engines: {node: '>=0.4.7'} - hasBin: true + '@webassemblyjs/wast-printer@1.14.1': + resolution: {integrity: sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==} - hardhat-dependency-compiler@1.2.1: - resolution: {integrity: sha512-xG5iwbspTtxOEiP5UsPngEYQ1Hg+fjTjliapIjdTQmwGkCPofrsDhQDV2O/dopcYzcR68nTx2X8xTewYHgA2rQ==} - engines: {node: '>=14.14.0'} - peerDependencies: - hardhat: ^2.0.0 + '@xtuc/ieee754@1.2.0': + resolution: {integrity: sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==} - hardhat-gas-reporter@1.0.10: - resolution: {integrity: sha512-02N4+So/fZrzJ88ci54GqwVA3Zrf0C9duuTyGt0CFRIh/CdNwbnTgkXkRfojOMLBQ+6t+lBIkgbsOtqMvNwikA==} + '@xtuc/long@4.2.2': + resolution: {integrity: sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==} + + abbrev@1.0.9: + resolution: {integrity: sha512-LEyx4aLEC3x6T0UguF6YILf+ntvmOaWsVfENmIW0E9H09vKlLDGelMjjSm0jkDHALj8A8quZ/HapKNigzwge+Q==} + + abitype@1.0.6: + resolution: {integrity: sha512-MMSqYh4+C/aVqI2RQaWqbvI4Kxo5cQV40WQ4QFtDnNzCkqChm8MuENhElmynZlO0qUy/ObkEUaXtKqYnx1Kp3A==} peerDependencies: - hardhat: ^2.0.2 + typescript: '>=5.0.4' + zod: ^3 >=3.22.0 + peerDependenciesMeta: + typescript: + optional: true + zod: + optional: true - hardhat@2.28.0: - resolution: {integrity: sha512-A3yBISI18EcnY2IR7Ny2xZF33Q3qH01yrWapeWbyGOiJm/386SasWjbHRHYgUlZ3YWJETIMh7wYfMUaXrofTDQ==} - hasBin: true + abitype@1.0.8: + resolution: {integrity: sha512-ZeiI6h3GnW06uYDLx0etQtX/p8E24UaHHBj57RSjK7YBFe7iuVn07EDpOeP451D06sF27VOz9JJPlIKJmXgkEg==} peerDependencies: - ts-node: '*' - typescript: '*' + typescript: '>=5.0.4' + zod: ^3 >=3.22.0 peerDependenciesMeta: - ts-node: + typescript: + optional: true + zod: optional: true + + abitype@1.2.3: + resolution: {integrity: sha512-Ofer5QUnuUdTFsBRwARMoWKOH1ND5ehwYhJ3OJ/BQO+StkwQjHw0XyVh4vDttzHB7QOFhPHa/o413PJ82gU/Tg==} + peerDependencies: + typescript: '>=5.0.4' + zod: ^3.22.0 || ^4.0.0 + peerDependenciesMeta: typescript: optional: true + zod: + optional: true - has-flag@1.0.0: - resolution: {integrity: sha512-DyYHfIYwAJmjAjSSPKANxI8bFY9YtFrgkAfinBojQ8YJTOuOuav64tMUJv584SES4xl74PmuaevIyaLESHdTAA==} - engines: {node: '>=0.10.0'} + accepts@1.3.8: + resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==} + engines: {node: '>= 0.6'} - has-flag@3.0.0: - resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} - engines: {node: '>=4'} + acorn-import-phases@1.0.4: + resolution: {integrity: sha512-wKmbr/DDiIXzEOiWrTTUcDm24kQ2vGfZQvM2fwg2vXqR5uW6aapr7ObPtj1th32b9u90/Pf4AItvdTh42fBmVQ==} + engines: {node: '>=10.13.0'} + peerDependencies: + acorn: ^8.14.0 - has-flag@4.0.0: - resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} - engines: {node: '>=8'} + acorn-jsx@5.3.2: + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 - has-property-descriptors@1.0.2: - resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} + acorn-walk@8.3.4: + resolution: {integrity: sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==} + engines: {node: '>=0.4.0'} - has-symbols@1.1.0: - resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} - engines: {node: '>= 0.4'} + acorn@8.15.0: + resolution: {integrity: sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==} + engines: {node: '>=0.4.0'} + hasBin: true - has-tostringtag@1.0.2: - resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} - engines: {node: '>= 0.4'} + address@1.2.2: + resolution: {integrity: sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA==} + engines: {node: '>= 10.0.0'} - hash-base@3.1.2: - resolution: {integrity: sha512-Bb33KbowVTIj5s7Ked1OsqHUeCpz//tPwR+E2zJgJKo9Z5XolZ9b6bdUgjmYlwnWhoOQKoTd1TYToZGn5mAYOg==} - engines: {node: '>= 0.8'} + adm-zip@0.4.16: + resolution: {integrity: sha512-TFi4HBKSGfIKsK5YCkKaaFG2m4PEDyViZmEwof3MTIgzimHLto6muaHVpbrljdIvIrFZzEq/p4nafOeLcYegrg==} + engines: {node: '>=0.3.0'} - hash.js@1.1.7: - resolution: {integrity: sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==} + aes-js@3.0.0: + resolution: {integrity: sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw==} - hasown@2.0.2: - resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} - engines: {node: '>= 0.4'} + aes-js@4.0.0-beta.5: + resolution: {integrity: sha512-G965FqalsNyrPqgEGON7nIx1e/OVENSgiEIzyC63haUMuvNnwIgIjMs52hlTCKhkBny7A2ORNlfY9Zu+jmGk1Q==} - he@1.2.0: - resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==} - hasBin: true + agent-base@6.0.2: + resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} + engines: {node: '>= 6.0.0'} - heap@0.2.7: - resolution: {integrity: sha512-2bsegYkkHO+h/9MGbn6KWcE45cHZgPANo5LXF7EvWdT0yT2EguSVO1nDgU5c8+ZOPwp2vMNa7YFsJhVcDR9Sdg==} + agentkeepalive@4.6.0: + resolution: {integrity: sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ==} + engines: {node: '>= 8.0.0'} - hmac-drbg@1.0.1: - resolution: {integrity: sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==} + aggregate-error@3.1.0: + resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==} + engines: {node: '>=8'} - hono@4.11.1: - resolution: {integrity: sha512-KsFcH0xxHes0J4zaQgWbYwmz3UPOOskdqZmItstUG93+Wk1ePBLkLGwbP9zlmh1BFUiL8Qp+Xfu9P7feJWpGNg==} - engines: {node: '>=16.9.0'} + ajv-formats@2.1.1: + resolution: {integrity: sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==} + peerDependencies: + ajv: ^8.0.0 + peerDependenciesMeta: + ajv: + optional: true - http-basic@8.1.3: - resolution: {integrity: sha512-/EcDMwJZh3mABI2NhGfHOGOeOZITqfkEO4p/xK+l3NpyncIHUQBoMvCSF/b5GqvKtySC2srL/GGG3+EtlqlmCw==} - engines: {node: '>=6.0.0'} + ajv-keywords@3.5.2: + resolution: {integrity: sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==} + peerDependencies: + ajv: ^6.9.1 - http-errors@2.0.1: - resolution: {integrity: sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==} - engines: {node: '>= 0.8'} + ajv-keywords@5.1.0: + resolution: {integrity: sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==} + peerDependencies: + ajv: ^8.8.2 - http-response-object@3.0.2: - resolution: {integrity: sha512-bqX0XTF6fnXSQcEJ2Iuyr75yVakyjIDCqroJQ/aHfSdlM743Cwqoi2nDYMzLGWUcuTWGWy8AAvOKXTfiv6q9RA==} + ajv@6.12.6: + resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} - https-proxy-agent@5.0.1: - resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} - engines: {node: '>= 6'} + ajv@8.17.1: + resolution: {integrity: sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==} - humanize-ms@1.2.1: - resolution: {integrity: sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==} + algoliasearch-helper@3.27.0: + resolution: {integrity: sha512-eNYchRerbsvk2doHOMfdS1/B6Tm70oGtu8mzQlrNzbCeQ8p1MjCW8t/BL6iZ5PD+cL5NNMgTMyMnmiXZ1sgmNw==} + peerDependencies: + algoliasearch: '>= 3.1 < 6' - iconv-lite@0.4.24: - resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} - engines: {node: '>=0.10.0'} + algoliasearch@5.47.0: + resolution: {integrity: sha512-AGtz2U7zOV4DlsuYV84tLp2tBbA7RPtLA44jbVH4TTpDcc1dIWmULjHSsunlhscbzDydnjuFlNhflR3nV4VJaQ==} + engines: {node: '>= 14.0.0'} - idb-keyval@6.2.1: - resolution: {integrity: sha512-8Sb3veuYCyrZL+VBt9LJfZjLUPWVvqn8tG28VqYNFCo43KHcKuq+b4EiXGeuaLAQWL2YmyDgMp2aSpH9JHsEQg==} + amazon-cognito-identity-js@6.3.16: + resolution: {integrity: sha512-HPGSBGD6Q36t99puWh0LnptxO/4icnk2kqIQ9cTJ2tFQo5NMUnWQIgtrTAk8nm+caqUbjDzXzG56GBjI2tS6jQ==} - idb-keyval@6.2.2: - resolution: {integrity: sha512-yjD9nARJ/jb1g+CvD0tlhUHOrJ9Sy0P8T9MF3YaLlHnSRpwPfpTX0XIvpmw3gAJUmEu3FiICLBDPXVwyEvrleg==} + amdefine@1.0.1: + resolution: {integrity: sha512-S2Hw0TtNkMJhIabBwIojKL9YHO5T0n5eNqWJ7Lrlel/zDbftQpxpapi8tZs3X1HWa+u+QeydGmzzNU0m09+Rcg==} + engines: {node: '>=0.4.2'} - ieee754@1.2.1: - resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} + ansi-align@3.0.1: + resolution: {integrity: sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==} - ignore@5.3.2: - resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} - engines: {node: '>= 4'} + ansi-colors@4.1.3: + resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} + engines: {node: '>=6'} - immer@10.0.2: - resolution: {integrity: sha512-Rx3CqeqQ19sxUtYV9CU911Vhy8/721wRFnJv3REVGWUmoAcIwzifTsdmJte/MV+0/XpM35LZdQMBGkRIoLPwQA==} + ansi-escapes@4.3.2: + resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} + engines: {node: '>=8'} - immutable@4.3.7: - resolution: {integrity: sha512-1hqclzwYwjRDFLjcFxOM5AYkkG0rpFPpr1RLPMEuGczoS7YA8gLhy8SWXYRAA/XwfEHpfo3cw5JGioS32fnMRw==} + ansi-html-community@0.0.8: + resolution: {integrity: sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==} + engines: {'0': node >= 0.8.0} + hasBin: true - indent-string@4.0.0: - resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} - engines: {node: '>=8'} + ansi-regex@3.0.1: + resolution: {integrity: sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==} + engines: {node: '>=4'} - inflight@1.0.6: - resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} - deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} - inherits@2.0.4: - resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + ansi-regex@6.2.2: + resolution: {integrity: sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==} + engines: {node: '>=12'} - ini@1.3.8: - resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} + ansi-styles@3.2.1: + resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} + engines: {node: '>=4'} - interpret@1.4.0: - resolution: {integrity: sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==} - engines: {node: '>= 0.10'} + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} - io-ts@1.10.4: - resolution: {integrity: sha512-b23PteSnYXSONJ6JQXRAlvJhuw8KOtkqa87W4wDtvMrud/DTJd5X+NpOOI+O/zZwVq6v0VLAaJ+1EDViKEuN9g==} + ansi-styles@6.2.3: + resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==} + engines: {node: '>=12'} - iron-webcrypto@1.2.1: - resolution: {integrity: sha512-feOM6FaSr6rEABp/eDfVseKyTMDt+KGpeB35SkVn9Tyn0CqvVsY3EwI0v5i8nMHyJnzCIQf7nsy3p41TPkJZhg==} + antlr4ts@0.5.0-alpha.4: + resolution: {integrity: sha512-WPQDt1B74OfPv/IMS2ekXAKkTZIHl88uMetg6q3OTqgFxZ/dxDXI0EWLyZid/1Pe6hTftyg5N7gel5wNAGxXyQ==} - is-arguments@1.2.0: - resolution: {integrity: sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA==} - engines: {node: '>= 0.4'} + any-promise@1.3.0: + resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} - is-binary-path@2.1.0: - resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} - engines: {node: '>=8'} + anymatch@3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} - is-buffer@1.1.6: - resolution: {integrity: sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==} + arg@4.1.3: + resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} - is-callable@1.2.7: - resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} - engines: {node: '>= 0.4'} + arg@5.0.2: + resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==} - is-core-module@2.16.1: - resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==} - engines: {node: '>= 0.4'} + argparse@1.0.10: + resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} - is-extglob@2.1.1: - resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} - engines: {node: '>=0.10.0'} + argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} - is-fullwidth-code-point@2.0.0: - resolution: {integrity: sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==} - engines: {node: '>=4'} + array-back@3.1.0: + resolution: {integrity: sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==} + engines: {node: '>=6'} - is-fullwidth-code-point@3.0.0: - resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + array-back@4.0.2: + resolution: {integrity: sha512-NbdMezxqf94cnNfWLL7V/im0Ub+Anbb0IoZhvzie8+4HJ4nMQuzHuy49FkGYCJK2yAloZ3meiB6AVMClbrI1vg==} engines: {node: '>=8'} - is-generator-function@1.1.2: - resolution: {integrity: sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==} - engines: {node: '>= 0.4'} + array-flatten@1.1.1: + resolution: {integrity: sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==} - is-glob@4.0.3: - resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + array-union@2.1.0: + resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} + engines: {node: '>=8'} + + array-uniq@1.0.3: + resolution: {integrity: sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==} engines: {node: '>=0.10.0'} - is-hex-prefixed@1.0.0: - resolution: {integrity: sha512-WvtOiug1VFrE9v1Cydwm+FnXd3+w9GaeVUss5W4v/SLy3UW00vP+6iNF2SdnfiBoLy4bTqVdkftNGTUeOFVsbA==} - engines: {node: '>=6.5.0', npm: '>=3'} + asap@2.0.6: + resolution: {integrity: sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==} - is-number@7.0.0: - resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} - engines: {node: '>=0.12.0'} + asn1js@3.0.7: + resolution: {integrity: sha512-uLvq6KJu04qoQM6gvBfKFjlh6Gl0vOKQuR5cJMDHQkmwfMOQeN3F3SHCv9SNYSL+CRoHvOGFfllDlVz03GQjvQ==} + engines: {node: '>=12.0.0'} - is-plain-obj@2.1.0: - resolution: {integrity: sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==} - engines: {node: '>=8'} + assertion-error@1.1.0: + resolution: {integrity: sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==} - 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'} + assertion-error@2.0.1: + resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} + engines: {node: '>=12'} - is-stream@2.0.1: - resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} + astral-regex@2.0.0: + resolution: {integrity: sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==} engines: {node: '>=8'} - is-typed-array@1.1.15: - resolution: {integrity: sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==} - engines: {node: '>= 0.4'} + astring@1.9.0: + resolution: {integrity: sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg==} + hasBin: true - is-unicode-supported@0.1.0: - resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} - engines: {node: '>=10'} + async-mutex@0.2.6: + resolution: {integrity: sha512-Hs4R+4SPgamu6rSGW8C7cV9gaWUKEHykfzCCvIRuaVv636Ju10ZdeUbvb4TBEW0INuq2DHZqXbK4Nd3yG4RaRw==} - isarray@1.0.0: - resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} + async-retry@1.3.3: + resolution: {integrity: sha512-wfr/jstw9xNi/0teMHrRW7dsz3Lt5ARhYNZ2ewpadnhaIp5mbALhOAP+EAdsC7t4Z6wqsDVv9+W6gm1Dk9mEyw==} - isarray@2.0.5: - resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} + async@1.5.2: + resolution: {integrity: sha512-nSVgobk4rv61R9PUSDtYt7mPVB2olxNR5RWJcAsH676/ef11bUZwvu7+RGYrYauVdDPcO519v68wRhXQtxsV9w==} - isexe@2.0.0: - resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} - isomorphic-unfetch@3.1.0: - resolution: {integrity: sha512-geDJjpoZ8N0kWexiwkX8F9NkTsXhetLPVbZFQ+JTW239QNOwvB0gniuR1Wc6f0AMTn7/mFGyXvHTifrCp/GH8Q==} + at-least-node@1.0.0: + resolution: {integrity: sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==} + engines: {node: '>= 4.0.0'} - isomorphic-ws@4.0.1: - resolution: {integrity: sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w==} - peerDependencies: - ws: '*' + atomic-sleep@1.0.0: + resolution: {integrity: sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==} + engines: {node: '>=8.0.0'} - isows@1.0.6: - resolution: {integrity: sha512-lPHCayd40oW98/I0uvgaHKWCSvkzY27LjWLbtzOm64yQ+G3Q5npjjbdppU65iZXkK1Zt+kH9pfegli0AYfwYYw==} + autoprefixer@10.4.23: + resolution: {integrity: sha512-YYTXSFulfwytnjAPlw8QHncHJmlvFKtczb8InXaAx9Q0LbfDnfEYDE55omerIJKihhmU61Ft+cAOSzQVaBUmeA==} + engines: {node: ^10 || ^12 || >=14} + hasBin: true peerDependencies: - ws: '*' + postcss: ^8.1.0 - isows@1.0.7: - resolution: {integrity: sha512-I1fSfDCZL5P0v33sVqeTDSpcstAg/N+wF5HS033mogOVIp4B+oHC7oOCsA3axAbBSGTJ8QubbNmnIRN/h8U7hg==} + 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: - ws: '*' + axios: 0.x || 1.x - jayson@4.2.0: - resolution: {integrity: sha512-VfJ9t1YLwacIubLhONk0KFeosUBwstRWQ0IRT1KDjEjnVnSOVHC3uwugyV7L0c7R9lpVyrUGT2XWiBA1UTtpyg==} - engines: {node: '>=8'} - hasBin: true + axios@1.13.2: + resolution: {integrity: sha512-VPk9ebNqPcy5lRGuSlKx752IlDatOjT9paPlm8A7yOuW2Fbvp4X3JznJtT4f0GzGLLiWE9W8onz51SqLYwzGaA==} - jiti@1.21.7: - resolution: {integrity: sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==} - hasBin: true + babel-loader@9.2.1: + resolution: {integrity: sha512-fqe8naHt46e0yIdkjUZYqddSXfej3AHajX+CSO5X7oy0EmPc6o5Xh+RClNoHjnieWz9AW4kZxW9yyFMhVB1QLA==} + engines: {node: '>= 14.15.0'} + peerDependencies: + '@babel/core': ^7.12.0 + webpack: '>=5' - jose@6.1.3: - resolution: {integrity: sha512-0TpaTfihd4QMNwrz/ob2Bp7X04yuxJkjRGi4aKmOqwhov54i6u79oCv7T+C7lo70MKH6BesI3vscD1yb/yzKXQ==} + babel-plugin-dynamic-import-node@2.3.3: + resolution: {integrity: sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==} - js-cookie@2.2.1: - resolution: {integrity: sha512-HvdH2LzI/EAZcUwA8+0nKNtWHqS+ZmijLA30RwZA0bo7ToCckjK5MkGhjED9KoRcXO6BaGI3I9UIzSA1FKFPOQ==} + babel-plugin-polyfill-corejs2@0.4.14: + resolution: {integrity: sha512-Co2Y9wX854ts6U8gAAPXfn0GmAyctHuK8n0Yhfjd6t30g7yvKjspvvOo9yG+z52PZRgFErt7Ka2pYnXCjLKEpg==} + peerDependencies: + '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 - js-sha3@0.8.0: - resolution: {integrity: sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==} + babel-plugin-polyfill-corejs3@0.13.0: + resolution: {integrity: sha512-U+GNwMdSFgzVmfhNm8GJUX88AadB3uo9KpJqS3FaqNIPKgySuvMb+bHPsOmmuWyIcuqZj/pzt1RUIUZns4y2+A==} + peerDependencies: + '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 - js-tokens@4.0.0: - resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + babel-plugin-polyfill-regenerator@0.6.5: + resolution: {integrity: sha512-ISqQ2frbiNU9vIJkzg7dlPpznPZ4jOiUQ1uSmB0fEHeowtN3COYRsXr/xexn64NpU13P06jc/L5TgiJXOgrbEg==} + peerDependencies: + '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 - js-tokens@9.0.1: - resolution: {integrity: sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==} + bail@2.0.2: + resolution: {integrity: sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==} - js-yaml@3.14.2: - resolution: {integrity: sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==} - hasBin: true + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} - js-yaml@4.1.1: - resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==} - hasBin: true + base-x@3.0.11: + resolution: {integrity: sha512-xz7wQ8xDhdyP7tQxwdteLYeFfS68tSMNCZ/Y37WJ4bhGfKPpqEIlmIyueQHqOyoPhE6xNUqjzRr8ra0eF9VRvA==} - jsesc@3.1.0: - resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} - engines: {node: '>=6'} - hasBin: true + base-x@5.0.1: + resolution: {integrity: sha512-M7uio8Zt++eg3jPj+rHMfCC+IuygQHHCOU+IYsVtik6FWjuYpVt/+MRKcgsAMHh8mMFAwnB+Bs+mTrFiXjMzKg==} - json-rpc-engine@6.1.0: - resolution: {integrity: sha512-NEdLrtrq1jUZyfjkr9OCz9EzCNhnRyWtt1PAnvnhwy6e8XETS0Dtc+ZNCO2gvuAoKsIn2+vCSowXTYE4CkgnAQ==} - engines: {node: '>=10.0.0'} + base64-js@1.5.1: + resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} - json-rpc-random-id@1.0.1: - resolution: {integrity: sha512-RJ9YYNCkhVDBuP4zN5BBtYAzEl03yq/jIIsyif0JY9qyJuQQZNeDK7anAPKKlyEtLSj2s8h6hNh2F8zO5q7ScA==} + base64-sol@1.0.1: + resolution: {integrity: sha512-ld3cCNMeXt4uJXmLZBHFGMvVpK9KsLVEhPpFRXnvSVAqABKbuNZg/+dsq3NuM+wxFLb/UrVkz7m1ciWmkMfTbg==} - json-schema-traverse@1.0.0: - resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} + baseline-browser-mapping@2.9.10: + resolution: {integrity: sha512-2VIKvDx8Z1a9rTB2eCkdPE5nSe28XnA+qivGnWHoB40hMMt/h1hSz0960Zqsn6ZyxWXUie0EBdElKv8may20AA==} + hasBin: true - json-stream-stringify@3.1.6: - resolution: {integrity: sha512-x7fpwxOkbhFCaJDJ8vb1fBY3DdSa4AlITaz+HHILQJzdPMnHEFjxPwVUi1ALIbcIxDE0PNe/0i7frnY8QnBQog==} - engines: {node: '>=7.10.1'} + batch@0.6.1: + resolution: {integrity: sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==} - json-stringify-safe@5.0.1: - resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==} + bech32@1.1.4: + resolution: {integrity: sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==} - json5@2.2.3: - resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} - engines: {node: '>=6'} - hasBin: true + big.js@5.2.2: + resolution: {integrity: sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==} - jsonfile@4.0.0: - resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} + big.js@6.2.2: + resolution: {integrity: sha512-y/ie+Faknx7sZA5MfGA2xKlu0GDv8RWrXGsmlteyJQ2lvoKv9GBK/fpRMc2qlSoBAgNxrixICFCBefIq8WCQpQ==} - jsonfile@6.2.0: - resolution: {integrity: sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==} + bignumber.js@9.3.1: + resolution: {integrity: sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ==} - jsonschema@1.5.0: - resolution: {integrity: sha512-K+A9hhqbn0f3pJX17Q/7H6yQfD/5OXgdrR5UE12gMXCiN9D5Xq2o5mddV2QEcX/bjla99ASsAAQUyMCCRWAEhw==} + binary-extensions@2.3.0: + resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} + engines: {node: '>=8'} - keccak@3.0.4: - resolution: {integrity: sha512-3vKuW0jV8J3XNTzvfyicFR5qvxrSAGl7KIhvgOu5cmWwM7tZRj3fMbj/pfIf4be7aznbc+prBWGjywox/g2Y6Q==} - engines: {node: '>=10.0.0'} + blakejs@1.2.1: + resolution: {integrity: sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ==} - keyvaluestorage-interface@1.0.0: - resolution: {integrity: sha512-8t6Q3TclQ4uZynJY9IGr2+SsIGwK9JHcO6ootkHCGA0CrQCRy+VkouYNO2xicET6b9al7QKzpebNow+gkpCL8g==} + bn.js@4.11.6: + resolution: {integrity: sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA==} - kind-of@6.0.3: - resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} - engines: {node: '>=0.10.0'} + bn.js@4.12.2: + resolution: {integrity: sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw==} - kleur@3.0.3: - resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} - engines: {node: '>=6'} + bn.js@5.2.2: + resolution: {integrity: sha512-v2YAxEmKaBLahNwE1mjp4WON6huMNeuDvagFZW+ASCuA/ku0bXR9hSMw0XpiqMoA3+rmnyck/tPRSFQkoC9Cuw==} - levn@0.3.0: - resolution: {integrity: sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==} - engines: {node: '>= 0.8.0'} + body-parser@1.20.4: + resolution: {integrity: sha512-ZTgYYLMOXY9qKU/57FAo8F+HA2dGX7bqGc71txDRC1rS4frdFI5R7NhluHxH6M0YItAP0sHB4uqAOcYKxO6uGA==} + engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} - lilconfig@3.1.3: - resolution: {integrity: sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==} - engines: {node: '>=14'} + bonjour-service@1.3.0: + resolution: {integrity: sha512-3YuAUiSkWykd+2Azjgyxei8OWf8thdn8AITIog2M4UICzoqfjlqr64WIjEXZllf/W6vK1goqleSR6brGomxQqA==} - lines-and-columns@1.2.4: - resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + boolbase@1.0.0: + resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} - lit-element@4.2.1: - resolution: {integrity: sha512-WGAWRGzirAgyphK2urmYOV72tlvnxw7YfyLDgQ+OZnM9vQQBQnumQ7jUJe6unEzwGU3ahFOjuz1iz1jjrpCPuw==} + borsh@0.7.0: + resolution: {integrity: sha512-CLCsZGIBCFnPtkNnieW/a8wmreDmfUtjU2m9yHrzPXIlNbqVs0AQrSatSG6vdNYUqdc83tkQi2eHfF98ubzQLA==} - lit-html@3.3.1: - resolution: {integrity: sha512-S9hbyDu/vs1qNrithiNyeyv64c9yqiW9l+DBgI18fL+MTvOtWoFR0FWiyq1TxaYef5wNlpEmzlXoBlZEO+WjoA==} + bowser@2.13.1: + resolution: {integrity: sha512-OHawaAbjwx6rqICCKgSG0SAnT05bzd7ppyKLVUITZpANBaaMFBAsaNkto3LoQ31tyFP5kNujE8Cdx85G9VzOkw==} - lit@3.3.0: - resolution: {integrity: sha512-DGVsqsOIHBww2DqnuZzW7QsuCdahp50ojuDaBPC7jUDRpYoH0z7kHBBYZewRzer75FwtrkmkKk7iOAwSaWdBmw==} + boxen@5.1.2: + resolution: {integrity: sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ==} + engines: {node: '>=10'} - locate-path@5.0.0: - resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} - engines: {node: '>=8'} + boxen@6.2.1: + resolution: {integrity: sha512-H4PEsJXfFI/Pt8sjDWbHlQPx4zL/bvSQjcilJmaulGt5mLDorHOHpmdXAJcBcmru7PhYSp/cDMWRko4ZUMFkSw==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - locate-path@6.0.0: - resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} - engines: {node: '>=10'} + boxen@7.1.1: + resolution: {integrity: sha512-2hCgjEmP8YLWQ130n2FerGv7rYpfBmnmp9Uy2Le1vge6X3gZIfSmEzP5QTDElFxcvVcXlEn8Aq6MU/PZygIOog==} + engines: {node: '>=14.16'} - lodash.camelcase@4.3.0: - resolution: {integrity: sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==} + brace-expansion@1.1.12: + resolution: {integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==} - lodash.clonedeep@4.5.0: - resolution: {integrity: sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==} + brace-expansion@2.0.2: + resolution: {integrity: sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==} - lodash.isequal@4.5.0: - resolution: {integrity: sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==} - deprecated: This package is deprecated. Use require('node:util').isDeepStrictEqual instead. + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} - lodash.truncate@4.4.2: - resolution: {integrity: sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==} + brorand@1.1.0: + resolution: {integrity: sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==} - lodash@4.17.21: - resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + browser-stdout@1.3.1: + resolution: {integrity: sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==} - log-symbols@4.1.0: - resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} - engines: {node: '>=10'} + browserify-aes@1.2.0: + resolution: {integrity: sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==} - loose-envify@1.4.0: - resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} + browserslist@4.28.1: + resolution: {integrity: sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true - loupe@2.3.7: - resolution: {integrity: sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==} + bs58@4.0.1: + resolution: {integrity: sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==} - loupe@3.2.1: - resolution: {integrity: sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==} + bs58@6.0.0: + resolution: {integrity: sha512-PD0wEnEYg6ijszw/u8s+iI3H17cTymlrwkKhDhPZq+Sokl3AU4htyBFTjAeNAlCCmg0f53g6ih3jATyCKftTfw==} - lru-cache@10.4.3: - resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} + bs58check@2.1.2: + resolution: {integrity: sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==} - lru-cache@5.1.1: - resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + buffer-from@1.1.2: + resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} - lru_map@0.3.3: - resolution: {integrity: sha512-Pn9cox5CsMYngeDbmChANltQl+5pi6XmTrraMSzhPmMBbmgcxmqWry0U3PGapCU1yB4/LqCcom7qhHZiF/jGfQ==} + buffer-xor@1.0.3: + resolution: {integrity: sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==} - lucide-react@0.525.0: - resolution: {integrity: sha512-Tm1txJ2OkymCGkvwoHt33Y2JpN5xucVq1slHcgE6Lk0WjDfjgKWor5CdVER8U6DvcfMwh4M8XxmpTiyzfmfDYQ==} - peerDependencies: - react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0 + buffer@4.9.2: + resolution: {integrity: sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==} - magic-string@0.30.21: - resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} + buffer@6.0.3: + resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} - make-error@1.3.6: - resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} + bufferutil@4.0.9: + resolution: {integrity: sha512-WDtdLmJvAuNNPzByAYpRo2rF1Mmradw6gvWsQKf63476DDXmomT9zUiGypLcG4ibIM67vhAj8jJRdbmEws2Aqw==} + engines: {node: '>=6.14.2'} - markdown-table@1.1.3: - resolution: {integrity: sha512-1RUZVgQlpJSPWYbFSpmudq5nHY1doEIv89gBtF0s4gW1GF2XorxcA/70M5vq7rLv0a6mhOUccRsqkwhwLCIQ2Q==} - - math-intrinsics@1.1.0: - resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} - engines: {node: '>= 0.4'} - - md5.js@1.3.5: - resolution: {integrity: sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==} - - md5@2.3.0: - resolution: {integrity: sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g==} + bundle-name@4.1.0: + resolution: {integrity: sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==} + engines: {node: '>=18'} - media-query-parser@2.0.2: - resolution: {integrity: sha512-1N4qp+jE0pL5Xv4uEcwVUhIkwdUO3S/9gML90nqKA7v7FcOS5vUtatfzok9S9U1EJU8dHWlcv95WLnKmmxZI9w==} + bytes@3.0.0: + resolution: {integrity: sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==} + engines: {node: '>= 0.8'} - memorystream@0.3.1: - resolution: {integrity: sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==} - engines: {node: '>= 0.10.0'} + bytes@3.1.2: + resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} + engines: {node: '>= 0.8'} - merge2@1.4.1: - resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} - engines: {node: '>= 8'} + bytestreamjs@2.0.1: + resolution: {integrity: sha512-U1Z/ob71V/bXfVABvNr/Kumf5VyeQRBEm6Txb0PQ6S7V5GpBM3w4Cbqz/xPDicR5tN0uvDifng8C+5qECeGwyQ==} + engines: {node: '>=6.0.0'} - micro-eth-signer@0.14.0: - resolution: {integrity: sha512-5PLLzHiVYPWClEvZIXXFu5yutzpadb73rnQCpUqIHu3No3coFuWQNfE5tkBQJ7djuLYl6aRLaS0MgWJYGoqiBw==} + cac@6.7.14: + resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} + engines: {node: '>=8'} - micro-ftch@0.3.1: - resolution: {integrity: sha512-/0LLxhzP0tfiR5hcQebtudP56gUurs2CLkGarnCiB/OqEyUFQ6U3paQi/tgLv0hBJYt2rnr9MNpxz4fiiugstg==} + cacheable-lookup@7.0.0: + resolution: {integrity: sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w==} + engines: {node: '>=14.16'} - micro-packed@0.7.3: - resolution: {integrity: sha512-2Milxs+WNC00TRlem41oRswvw31146GiSaoCT7s3Xi2gMUglW5QBeqlQaZeHr5tJx9nm3i57LNXPqxOOaWtTYg==} + cacheable-request@10.2.14: + resolution: {integrity: sha512-zkDT5WAF4hSSoUgyfg5tFIxz8XQK+25W/TLVojJTMKBaxevLBBtLxgqguAuVQB8PVW79FVjHcU+GJ9tVbDZ9mQ==} + engines: {node: '>=14.16'} - micromatch@4.0.8: - resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} - engines: {node: '>=8.6'} + call-bind-apply-helpers@1.0.2: + resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} + engines: {node: '>= 0.4'} - mime-db@1.52.0: - resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} - engines: {node: '>= 0.6'} + call-bind@1.0.8: + resolution: {integrity: sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==} + engines: {node: '>= 0.4'} - mime-types@2.1.35: - resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} - engines: {node: '>= 0.6'} + call-bound@1.0.4: + resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} + engines: {node: '>= 0.4'} - minimalistic-assert@1.0.1: - resolution: {integrity: sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==} + callsites@3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} - minimalistic-crypto-utils@1.0.1: - resolution: {integrity: sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==} + camel-case@4.1.2: + resolution: {integrity: sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==} - minimatch@10.1.1: - resolution: {integrity: sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==} - engines: {node: 20 || >=22} + camelcase-css@2.0.1: + resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==} + engines: {node: '>= 6'} - minimatch@3.1.2: - resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + camelcase@5.3.1: + resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==} + engines: {node: '>=6'} - minimatch@5.1.6: - resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==} + camelcase@6.3.0: + resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} engines: {node: '>=10'} - minimatch@9.0.5: - resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} - engines: {node: '>=16 || 14 >=14.17'} - - minimist@1.2.8: - resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + camelcase@7.0.1: + resolution: {integrity: sha512-xlx1yCK2Oc1APsPXDL2LdlNP6+uu8OCDdhOBSVT279M/S+y75O30C2VuD8T2ogdePBBl7PfPF4504tnLgX3zfw==} + engines: {node: '>=14.16'} - mipd@0.0.7: - resolution: {integrity: sha512-aAPZPNDQ3uMTdKbuO2YmAw2TxLHO0moa4YKAyETM/DTj5FloZo+a+8tU+iv4GmW+sOxKLSRwcSFuczk+Cpt6fg==} - peerDependencies: - typescript: '>=5.0.4' - peerDependenciesMeta: - typescript: - optional: true + caniuse-api@3.0.0: + resolution: {integrity: sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==} - mkdirp@0.5.6: - resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==} - hasBin: true + caniuse-lite@1.0.30001760: + resolution: {integrity: sha512-7AAMPcueWELt1p3mi13HR/LHH0TJLT11cnwDJEs3xA4+CK/PLKeO9Kl1oru24htkyUKtkGCvAx4ohB0Ttry8Dw==} - mkdirp@1.0.4: - resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} - engines: {node: '>=10'} - hasBin: true + caseless@0.12.0: + resolution: {integrity: sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==} - mnemonist@0.38.5: - resolution: {integrity: sha512-bZTFT5rrPKtPJxj8KSV0WkPyNxl72vQepqqVUAW2ARUpUSF2qXMB6jZj7hW5/k7C1rtpzqbD/IIbJwLXUjCHeg==} + cbor@10.0.11: + resolution: {integrity: sha512-vIwORDd/WyB8Nc23o2zNN5RrtFGlR6Fca61TtjkUXueI3Jf2DOZDl1zsshvBntZ3wZHBM9ztjnkXSmzQDaq3WA==} + engines: {node: '>=20'} - mocha@10.8.2: - resolution: {integrity: sha512-VZlYo/WE8t1tstuRmqgeyBgCbJc/lEdopaa+axcKzTBJ+UIdlAB9XnmvTCAH4pwR4ElNInaedhEBmZD8iCSVEg==} - engines: {node: '>= 14.0.0'} - hasBin: true + cbor@8.1.0: + resolution: {integrity: sha512-DwGjNW9omn6EwP70aXsn7FQJx5kO12tX0bZkaTjzdVFM6/7nhA4t0EENocKGx6D2Bch9PE2KzCUf5SceBdeijg==} + engines: {node: '>=12.19'} - modern-ahocorasick@1.1.0: - resolution: {integrity: sha512-sEKPVl2rM+MNVkGQt3ChdmD8YsigmXdn5NifZn6jiwn9LRJpWm8F3guhaqrJT/JOat6pwpbXEk6kv+b9DMIjsQ==} + cbor@9.0.2: + resolution: {integrity: sha512-JPypkxsB10s9QOWwa6zwPzqE1Md3vqpPc+cai4sAecuCsRyAtAl/pMyhPlMbT/xtPnm2dznJZYRLui57qiRhaQ==} + engines: {node: '>=16'} - motion-dom@12.23.23: - resolution: {integrity: sha512-n5yolOs0TQQBRUFImrRfs/+6X4p3Q4n1dUEqt/H58Vx7OW6RF+foWEgmTVDhIWJIMXOuNNL0apKH2S16en9eiA==} + ccount@2.0.1: + resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} - motion-utils@12.23.6: - resolution: {integrity: sha512-eAWoPgr4eFEOFfg2WjIsMoqJTW6Z8MTUCgn/GZ3VRpClWBdnbjryiA3ZSNLyxCTmCQx4RmYX6jX1iWHbenUPNQ==} + chai-as-promised@7.1.2: + resolution: {integrity: sha512-aBDHZxRzYnUYuIAIPBH2s511DjlKPzXNlXSGFC8CwmroWQLfrW0LtE1nK3MAwwNhJPa9raEjNCmRoFpG0Hurdw==} + peerDependencies: + chai: '>= 2.1.2 < 6' - ms@2.1.2: - resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} + chai@4.5.0: + resolution: {integrity: sha512-RITGBfijLkBddZvnn8jdqoTypxvqbOLYQkGGxXzeFjVHvudaPw0HNFD9x928/eUwYWd2dPCugVqspGALTZZQKw==} + engines: {node: '>=4'} - ms@2.1.3: - resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + chai@5.3.3: + resolution: {integrity: sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==} + engines: {node: '>=18'} - multiformats@9.9.0: - resolution: {integrity: sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg==} + chalk@2.4.2: + resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} + engines: {node: '>=4'} - mz@2.7.0: - resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} + chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} - nanoid@3.3.11: - resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} - engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} - hasBin: true + chalk@5.6.2: + resolution: {integrity: sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==} + engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} - ndjson@2.0.0: - resolution: {integrity: sha512-nGl7LRGrzugTtaFcJMhLbpzJM6XdivmbkdlaGcrk/LXg2KL/YBC6z1g70xh0/al+oFuVFP8N8kiWRucmeEH/qQ==} + char-regex@1.0.2: + resolution: {integrity: sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==} engines: {node: '>=10'} - hasBin: true - neo-async@2.6.2: - resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} + character-entities-html4@2.1.0: + resolution: {integrity: sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==} - node-addon-api@2.0.2: - resolution: {integrity: sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==} + character-entities-legacy@3.0.0: + resolution: {integrity: sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==} - node-addon-api@5.1.0: - resolution: {integrity: sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA==} + character-entities@2.0.2: + resolution: {integrity: sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==} - node-emoji@1.11.0: - resolution: {integrity: sha512-wo2DpQkQp7Sjm2A0cq+sN7EHKO6Sl0ctXeBdFZrL9T9+UywORbufTcTZxom8YqpLQt/FqNMUkOpkZrJVYSKD3A==} + character-reference-invalid@2.0.1: + resolution: {integrity: sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==} - node-fetch-native@1.6.7: - resolution: {integrity: sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q==} + charenc@0.0.2: + resolution: {integrity: sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==} - node-fetch@2.7.0: - resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} - engines: {node: 4.x || >=6.0.0} - peerDependencies: - encoding: ^0.1.0 - peerDependenciesMeta: - encoding: - optional: true + check-error@1.0.3: + resolution: {integrity: sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==} - node-gyp-build@4.8.4: - resolution: {integrity: sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==} - hasBin: true + check-error@2.1.1: + resolution: {integrity: sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==} + engines: {node: '>= 16'} - node-mock-http@1.0.4: - resolution: {integrity: sha512-8DY+kFsDkNXy1sJglUfuODx1/opAGJGyrTuFqEoN90oRc2Vk0ZbD4K2qmKXBBEhZQzdKHIVfEJpDU8Ak2NJEvQ==} + cheerio-select@2.1.0: + resolution: {integrity: sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==} - node-releases@2.0.27: - resolution: {integrity: sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==} + cheerio@1.0.0-rc.12: + resolution: {integrity: sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==} + engines: {node: '>= 6'} - nofilter@3.1.0: - resolution: {integrity: sha512-l2NNj07e9afPnhAhvgVrCD/oy2Ai1yfLpuo3EpiO1jFTsB4sFz6oIfAfSZyQzVpkZQ9xS8ZS5g1jCBgq4Hwo0g==} - engines: {node: '>=12.19'} + chokidar@3.6.0: + resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} + engines: {node: '>= 8.10.0'} - nopt@3.0.6: - resolution: {integrity: sha512-4GUt3kSEYmk4ITxzB/b9vaIDfUVWN/Ml1Fwl11IlnIG2iaJ9O6WXZ9SrYM9NLI8OCBieN2Y8SWC2oJV0RQ7qYg==} - hasBin: true + chokidar@4.0.3: + resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} + engines: {node: '>= 14.16.0'} - normalize-path@3.0.0: - resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} - engines: {node: '>=0.10.0'} + chrome-trace-event@1.0.4: + resolution: {integrity: sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==} + engines: {node: '>=6.0'} - number-to-bn@1.7.0: - resolution: {integrity: sha512-wsJ9gfSz1/s4ZsJN01lyonwuxA1tml6X1yBDnfpMglypcBRFZZkus26EdPSlqS5GJfYddVZa22p3VNb3z5m5Ig==} - engines: {node: '>=6.5.0', npm: '>=3'} + ci-info@2.0.0: + resolution: {integrity: sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==} - obj-multiplex@1.0.0: - resolution: {integrity: sha512-0GNJAOsHoBHeNTvl5Vt6IWnpUEcc3uSRxzBri7EDyIcMgYvnY2JL2qdeV5zTMjWQX5OHcD5amcW2HFfDh0gjIA==} + ci-info@3.9.0: + resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==} + engines: {node: '>=8'} - object-assign@4.1.1: - resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} - engines: {node: '>=0.10.0'} + cipher-base@1.0.7: + resolution: {integrity: sha512-Mz9QMT5fJe7bKI7MH31UilT5cEK5EHHRCccw/YRFsRY47AuNgaV6HY3rscp0/I4Q+tTW/5zoqpSeRRI54TkDWA==} + engines: {node: '>= 0.10'} - object-hash@3.0.0: - resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==} - engines: {node: '>= 6'} + clean-css@5.3.3: + resolution: {integrity: sha512-D5J+kHaVb/wKSFcyyV75uCn8fiY4sV38XJoe4CUyGQ+mOU/fMVYUdH1hJC+CJQ5uY3EnW27SbJYS4X8BiLrAFg==} + engines: {node: '>= 10.0'} - object-inspect@1.13.4: - resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} - engines: {node: '>= 0.4'} + clean-stack@2.2.0: + resolution: {integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==} + engines: {node: '>=6'} - obliterator@2.0.5: - resolution: {integrity: sha512-42CPE9AhahZRsMNslczq0ctAEtqk8Eka26QofnqC346BZdHDySk3LWka23LI7ULIw11NmltpiLagIq8gBozxTw==} + cli-boxes@2.2.1: + resolution: {integrity: sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==} + engines: {node: '>=6'} - ofetch@1.5.1: - resolution: {integrity: sha512-2W4oUZlVaqAPAil6FUg/difl6YhqhUR7x2eZY4bQCko22UXg3hptq9KLQdqFClV+Wu85UX7hNtdGTngi/1BxcA==} + cli-boxes@3.0.0: + resolution: {integrity: sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==} + engines: {node: '>=10'} - on-exit-leak-free@0.2.0: - resolution: {integrity: sha512-dqaz3u44QbRXQooZLTUKU41ZrzYrcvLISVgbrzbyCMxpmSLJvZ3ZamIJIZ29P6OhZIkNIQKosdeM6t1LYbA9hg==} + cli-table3@0.5.1: + resolution: {integrity: sha512-7Qg2Jrep1S/+Q3EceiZtQcDPWxhAvBw+ERf1162v4sikJrvojMHFqXt8QIVha8UlH9rgU0BeWPytZ9/TzYqlUw==} + engines: {node: '>=6'} - once@1.4.0: - resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + cli-table3@0.6.5: + resolution: {integrity: sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ==} + engines: {node: 10.* || >= 12.*} - openapi-fetch@0.13.8: - resolution: {integrity: sha512-yJ4QKRyNxE44baQ9mY5+r/kAzZ8yXMemtNAOFwOzRXJscdjSxxzWSNlyBAr+o5JjkUw9Lc3W7OIoca0cY3PYnQ==} + cliui@6.0.0: + resolution: {integrity: sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==} - openapi-typescript-helpers@0.0.15: - resolution: {integrity: sha512-opyTPaunsklCBpTK8JGef6mfPhLSnyy5a0IN9vKtx3+4aExf+KxEqYwIy3hqkedXIB97u357uLMJsOnm3GVjsw==} + cliui@7.0.4: + resolution: {integrity: sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==} - optionator@0.8.3: - resolution: {integrity: sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==} - engines: {node: '>= 0.8.0'} + clone-deep@4.0.1: + resolution: {integrity: sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==} + engines: {node: '>=6'} - ordinal@1.0.3: - resolution: {integrity: sha512-cMddMgb2QElm8G7vdaa02jhUNbTSrhsgAGUz1OokD83uJTwSUn+nKoNoKVVaRa08yF6sgfO7Maou1+bgLd9rdQ==} + clsx@1.2.1: + resolution: {integrity: sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==} + engines: {node: '>=6'} - os-tmpdir@1.0.2: - resolution: {integrity: sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==} - engines: {node: '>=0.10.0'} + clsx@2.1.1: + resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} + engines: {node: '>=6'} - ox@0.10.5: - resolution: {integrity: sha512-mXJRiZswmX46abrzNkJpTN9sPJ/Rhevsp5Dfg0z80D55aoLNmEV4oN+/+feSNW593c2CnHavMqSVBanpJ0lUkQ==} - peerDependencies: - typescript: '>=5.4.0' - peerDependenciesMeta: - typescript: - optional: true + collapse-white-space@2.1.0: + resolution: {integrity: sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw==} - ox@0.6.7: - resolution: {integrity: sha512-17Gk/eFsFRAZ80p5eKqv89a57uXjd3NgIf1CaXojATPBuujVc/fQSVhBeAU9JCRB+k7J50WQAyWTxK19T9GgbA==} - peerDependencies: - typescript: '>=5.4.0' - peerDependenciesMeta: - typescript: - optional: true + color-convert@1.9.3: + resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} - ox@0.6.9: - resolution: {integrity: sha512-wi5ShvzE4eOcTwQVsIPdFr+8ycyX+5le/96iAJutaZAvCes1J0+RvpEPg5QDPDiaR0XQQAvZVl7AwqQcINuUug==} - peerDependencies: - typescript: '>=5.4.0' - peerDependenciesMeta: - typescript: - optional: true + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} - ox@0.9.17: - resolution: {integrity: sha512-rKAnhzhRU3Xh3hiko+i1ZxywZ55eWQzeS/Q4HRKLx2PqfHOolisZHErSsJVipGlmQKHW5qwOED/GighEw9dbLg==} - peerDependencies: - typescript: '>=5.4.0' - peerDependenciesMeta: - typescript: - optional: true + color-name@1.1.3: + resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} - p-limit@2.3.0: - resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} - engines: {node: '>=6'} + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} - p-limit@3.1.0: - resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} - engines: {node: '>=10'} + colord@2.9.3: + resolution: {integrity: sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==} - p-locate@4.1.0: - resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} - engines: {node: '>=8'} + colorette@2.0.20: + resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} - p-locate@5.0.0: - resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} - engines: {node: '>=10'} + colors@1.4.0: + resolution: {integrity: sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==} + engines: {node: '>=0.1.90'} - p-map@4.0.0: - resolution: {integrity: sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==} + combine-promises@1.2.0: + resolution: {integrity: sha512-VcQB1ziGD0NXrhKxiwyNbCDmRzs/OShMs2GqW2DlU2A/Sd0nQxE1oWDAE5O0ygSx5mgQOn9eIFh7yKPgFRVkPQ==} engines: {node: '>=10'} - p-try@2.2.0: - resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} - engines: {node: '>=6'} + combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} - parse-cache-control@1.0.1: - resolution: {integrity: sha512-60zvsJReQPX5/QP0Kzfd/VrpjScIQ7SHBW6bFCYfEP+fp0Eppr1SHhIO5nd1PjZtvclzSzES9D/p5nFJurwfWg==} + comma-separated-tokens@2.0.3: + resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==} - path-exists@4.0.0: - resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} - engines: {node: '>=8'} + command-exists@1.2.9: + resolution: {integrity: sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w==} - path-is-absolute@1.0.1: - resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} - engines: {node: '>=0.10.0'} + command-line-args@5.2.1: + resolution: {integrity: sha512-H4UfQhZyakIjC74I9d34fGYDwk3XpSr17QhEd0Q3I9Xq1CETHo4Hcuo87WyWHpAF1aSLjLRf5lD9ZGX2qStUvg==} + engines: {node: '>=4.0.0'} - path-parse@1.0.7: - resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + command-line-usage@6.1.3: + resolution: {integrity: sha512-sH5ZSPr+7UStsloltmDh7Ce5fb8XPlHyoPzTpyyMuYCtervL65+ubVZ6Q61cFtFl62UyJlc8/JwERRbAFPUqgw==} + engines: {node: '>=8.0.0'} - path-type@4.0.0: - resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} - engines: {node: '>=8'} + commander@10.0.1: + resolution: {integrity: sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==} + engines: {node: '>=14'} - pathe@2.0.3: - resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} + commander@14.0.0: + resolution: {integrity: sha512-2uM9rYjPvyq39NwLRqaiLtWHyDC1FvryJDa2ATTVims5YAS4PupsEQsDvP14FqhFr0P49CYDugi59xaxJlTXRA==} + engines: {node: '>=20'} - pathval@1.1.1: - resolution: {integrity: sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==} + commander@14.0.2: + resolution: {integrity: sha512-TywoWNNRbhoD0BXs1P3ZEScW8W5iKrnbithIl0YH+uCmBd0QpPOA8yc82DS3BIE5Ma6FnBVUsJ7wVUDz4dvOWQ==} + engines: {node: '>=20'} - pathval@2.0.1: - resolution: {integrity: sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==} - engines: {node: '>= 14.16'} + commander@2.20.3: + resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} - pbkdf2@3.1.5: - resolution: {integrity: sha512-Q3CG/cYvCO1ye4QKkuH7EXxs3VC/rI1/trd+qX2+PolbaKG0H+bgcZzrTt96mMyRtejk+JMCiLUn3y29W8qmFQ==} - engines: {node: '>= 0.10'} + commander@4.1.1: + resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} + engines: {node: '>= 6'} - picocolors@1.1.1: - resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + commander@5.1.0: + resolution: {integrity: sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==} + engines: {node: '>= 6'} - picomatch@2.3.1: - resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} - engines: {node: '>=8.6'} + commander@7.2.0: + resolution: {integrity: sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==} + engines: {node: '>= 10'} - picomatch@4.0.3: - resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} + commander@8.3.0: + resolution: {integrity: sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==} + engines: {node: '>= 12'} + + common-path-prefix@3.0.0: + resolution: {integrity: sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==} + + compare-versions@6.1.1: + resolution: {integrity: sha512-4hm4VPpIecmlg59CHXnRDnqGplJFrbLG4aFEl5vl6cK1u76ws3LLvX7ikFnTDl5vo39sjWD6AaDPYodJp/NNHg==} + + compressible@2.0.18: + resolution: {integrity: sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==} + engines: {node: '>= 0.6'} + + compression@1.8.1: + resolution: {integrity: sha512-9mAqGPHLakhCLeNyxPkK4xVo746zQ/czLH1Ky+vkitMnWfWZps8r0qXuwhwizagCRttsL4lfG4pIOvaWLpAP0w==} + engines: {node: '>= 0.8.0'} + + concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + + concat-stream@1.6.2: + resolution: {integrity: sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==} + engines: {'0': node >= 0.8} + + config-chain@1.1.13: + resolution: {integrity: sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==} + + configstore@6.0.0: + resolution: {integrity: sha512-cD31W1v3GqUlQvbBCGcXmd2Nj9SvLDOP1oQ0YFuLETufzSPaKp11rYBsSOm7rCsW3OnIRAFM3OxRhceaXNYHkA==} engines: {node: '>=12'} - pify@2.3.0: - resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==} - engines: {node: '>=0.10.0'} + connect-history-api-fallback@2.0.0: + resolution: {integrity: sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==} + engines: {node: '>=0.8'} - pify@3.0.0: - resolution: {integrity: sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==} - engines: {node: '>=4'} + consola@3.4.2: + resolution: {integrity: sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==} + engines: {node: ^14.18.0 || >=16.10.0} - pify@4.0.1: - resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==} - engines: {node: '>=6'} + content-disposition@0.5.2: + resolution: {integrity: sha512-kRGRZw3bLlFISDBgwTSA1TMBFN6J6GWDeubmDE3AF+3+yXL8hTWv8r5rkLbqYXY4RjPk/EzHnClI3zQf1cFmHA==} + engines: {node: '>= 0.6'} - pify@5.0.0: - resolution: {integrity: sha512-eW/gHNMlxdSP6dmG6uJip6FXN0EQBwm2clYYd8Wul42Cwu/DK8HEftzsapcNdYe2MfLiIwZqsDk2RDEsTE79hA==} - engines: {node: '>=10'} + content-disposition@0.5.4: + resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==} + engines: {node: '>= 0.6'} - pino-abstract-transport@0.5.0: - resolution: {integrity: sha512-+KAgmVeqXYbTtU2FScx1XS3kNyfZ5TrXY07V96QnUSFqo2gAqlvmaxH67Lj7SWazqsMabf+58ctdTcBgnOLUOQ==} + content-type@1.0.5: + resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} + engines: {node: '>= 0.6'} - pino-std-serializers@4.0.0: - resolution: {integrity: sha512-cK0pekc1Kjy5w9V2/n+8MkZwusa6EyyxfeQCB799CQRhRt/CqYKiWs5adeu8Shve2ZNffvfC/7J64A2PJo1W/Q==} + convert-source-map@2.0.0: + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} - pino@7.11.0: - resolution: {integrity: sha512-dMACeu63HtRLmCG8VKdy4cShCPKaYDR4youZqoSWLxl5Gu99HUw8bw75thbPv9Nip+H+QYX8o3ZJbTdVZZ2TVg==} - hasBin: true + cookie-es@1.2.2: + resolution: {integrity: sha512-+W7VmiVINB+ywl1HGXJXmrqkOhpKrIiVZV6tQuV54ZyQC7MMuBt81Vc336GMLoHBq5hV/F9eXgt5Mnx0Rha5Fg==} - pirates@4.0.7: - resolution: {integrity: sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==} - engines: {node: '>= 6'} + cookie-signature@1.0.7: + resolution: {integrity: sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA==} - pngjs@5.0.0: - resolution: {integrity: sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==} - engines: {node: '>=10.13.0'} + cookie@0.4.2: + resolution: {integrity: sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==} + engines: {node: '>= 0.6'} - pony-cause@2.1.11: - resolution: {integrity: sha512-M7LhCsdNbNgiLYiP4WjsfLUuFmCfnjdF6jKe2R9NKl4WFN+HZPGHJZ9lnLP7f9ZnKe3U9nuWD0szirmj+migUg==} - engines: {node: '>=12.0.0'} + cookie@0.7.2: + resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==} + engines: {node: '>= 0.6'} - porto@0.2.35: - resolution: {integrity: sha512-gu9FfjjvvYBgQXUHWTp6n3wkTxVtEcqFotM7i3GEZeoQbvLGbssAicCz6hFZ8+xggrJWwi/RLmbwNra50SMmUQ==} - hasBin: true + copy-webpack-plugin@11.0.0: + resolution: {integrity: sha512-fX2MWpamkW0hZxMEg0+mYnA40LTosOSa5TqZ9GYIBzyJa9C3QUaMPSE2xAi/buNr8u89SfD9wHSQVBzrRa/SOQ==} + engines: {node: '>= 14.15.0'} 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 + webpack: ^5.1.0 - possible-typed-array-names@1.1.0: - resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==} - engines: {node: '>= 0.4'} + core-js-compat@3.47.0: + resolution: {integrity: sha512-IGfuznZ/n7Kp9+nypamBhvwdwLsW6KC8IOaURw2doAK5e98AG3acVLdh0woOnEqCfUtS+Vu882JE4k/DAm3ItQ==} - postcss-import@15.1.0: - resolution: {integrity: sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==} - engines: {node: '>=14.0.0'} - peerDependencies: - postcss: ^8.0.0 + core-js-pure@3.47.0: + resolution: {integrity: sha512-BcxeDbzUrRnXGYIVAGFtcGQVNpFcUhVjr6W7F8XktvQW2iJP9e66GP6xdKotCRFlrxBvNIBrhwKteRXqMV86Nw==} - postcss-js@4.1.0: - resolution: {integrity: sha512-oIAOTqgIo7q2EOwbhb8UalYePMvYoIeRY2YKntdpFQXNosSu3vLrniGgmH9OKs/qAkfoj5oB3le/7mINW1LCfw==} - engines: {node: ^12 || ^14 || >= 16} - peerDependencies: - postcss: ^8.4.21 + core-js@3.47.0: + resolution: {integrity: sha512-c3Q2VVkGAUyupsjRnaNX6u8Dq2vAdzm9iuPj5FW0fRxzlxgq9Q39MDq10IvmQSpLgHQNyQzQmOo6bgGHmH3NNg==} - postcss-load-config@6.0.1: - resolution: {integrity: sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==} - engines: {node: '>= 18'} + core-util-is@1.0.3: + resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} + + cosmiconfig@8.3.6: + resolution: {integrity: sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==} + engines: {node: '>=14'} peerDependencies: - jiti: '>=1.21.0' - postcss: '>=8.0.9' - tsx: ^4.8.1 - yaml: ^2.4.2 + typescript: '>=4.9.5' peerDependenciesMeta: - jiti: - optional: true - postcss: - optional: true - tsx: - optional: true - yaml: + typescript: optional: true - postcss-nested@6.2.0: - resolution: {integrity: sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==} - engines: {node: '>=12.0'} - peerDependencies: - postcss: ^8.2.14 + crc-32@1.2.2: + resolution: {integrity: sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==} + engines: {node: '>=0.8'} + hasBin: true - postcss-selector-parser@6.1.2: - resolution: {integrity: sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==} - engines: {node: '>=4'} + create-hash@1.2.0: + resolution: {integrity: sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==} - postcss-value-parser@4.2.0: - resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} + create-hmac@1.1.7: + resolution: {integrity: sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==} - postcss@8.5.6: - resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==} - engines: {node: ^10 || ^12 || >=14} + create-require@1.1.1: + resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} - preact@10.24.2: - resolution: {integrity: sha512-1cSoF0aCC8uaARATfrlz4VCBqE8LwZwRfLgkxJOQwAlQt6ayTmi0D9OF7nXid1POI5SZidFuG9CnlXbDfLqY/Q==} + cross-fetch@3.2.0: + resolution: {integrity: sha512-Q+xVJLoGOeIMXZmbUK4HYk+69cQH6LudR0Vu/pRm2YlU/hDV9CiS0gKUMaWY5f2NeUH9C1nV3bsTlCo0FsTV1Q==} - preact@10.28.0: - resolution: {integrity: sha512-rytDAoiXr3+t6OIP3WGlDd0ouCUG1iCWzkcY3++Nreuoi17y6T5i/zRhe6uYfoVcxq6YU+sBtJouuRDsq8vvqA==} + cross-fetch@4.1.0: + resolution: {integrity: sha512-uKm5PU+MHTootlWEY+mZ4vvXoCn4fLQxT9dSc1sXVMSFkINTJVN8cAQROpwcKm8bJ/c7rgZVIBWzH5T78sNZZw==} - prelude-ls@1.1.2: - resolution: {integrity: sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==} - engines: {node: '>= 0.8.0'} + cross-spawn@7.0.6: + resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} + engines: {node: '>= 8'} - prettier@2.8.8: - resolution: {integrity: sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==} - engines: {node: '>=10.13.0'} - hasBin: true + crossws@0.3.5: + resolution: {integrity: sha512-ojKiDvcmByhwa8YYqbQI/hg7MEU0NC03+pSdEq4ZUnZR9xXpwk7E43SMNGkn+JxJGPFtNvQ48+vV2p+P1ml5PA==} - process-nextick-args@2.0.1: - resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} + crypt@0.0.2: + resolution: {integrity: sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==} - process-warning@1.0.0: - resolution: {integrity: sha512-du4wfLyj4yCZq1VupnVSZmRsPJsNuxoDQFdCFHLaYiEbFBD7QE0a+I4D7hOxrVnh78QE/YipFAj9lXHiXocV+Q==} + crypto-random-string@4.0.0: + resolution: {integrity: sha512-x8dy3RnvYdlUcPOjkEHqozhiwzKNSq7GcPuXFbnyMOCHxX8V3OgIg/pYuabl2sbUPfIJaeAQB7PMOK8DFIdoRA==} + engines: {node: '>=12'} - promise@8.3.0: - resolution: {integrity: sha512-rZPNPKTOYVNEEKFaq1HqTgOwZD+4/YHS5ukLzQCypkj+OkYx7iv0mA91lJlpPPZ8vMau3IIGj5Qlwrx+8iiSmg==} + css-blank-pseudo@7.0.1: + resolution: {integrity: sha512-jf+twWGDf6LDoXDUode+nc7ZlrqfaNphrBIBrcmeP3D8yw1uPaix1gCC8LUQUGQ6CycuK2opkbFFWFuq/a94ag==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 - prompts@2.4.2: - resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} - engines: {node: '>= 6'} + css-declaration-sorter@7.3.1: + resolution: {integrity: sha512-gz6x+KkgNCjxq3Var03pRYLhyNfwhkKF1g/yoLgDNtFvVu0/fOLV9C8fFEZRjACp/XQLumjAYo7JVjzH3wLbxA==} + engines: {node: ^14 || ^16 || >=18} + peerDependencies: + postcss: ^8.0.9 - proper-lockfile@4.1.2: - resolution: {integrity: sha512-TjNPblN4BwAWMXU8s9AEz4JmQxnD1NNL7bNOY/AKUzyamc379FWASUhc/K1pL2noVb+XmZKLL68cjzLsiOAMaA==} + css-has-pseudo@7.0.3: + resolution: {integrity: sha512-oG+vKuGyqe/xvEMoxAQrhi7uY16deJR3i7wwhBerVrGQKSqUC5GiOVxTpM9F9B9hw0J+eKeOWLH7E9gZ1Dr5rA==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 - proxy-compare@2.6.0: - resolution: {integrity: sha512-8xuCeM3l8yqdmbPoYeLbrAXCBWu19XEYc5/F28f5qOaoAIMyfmBUkl5axiK+x9olUvRlcekvnm98AP9RDngOIw==} + css-loader@6.11.0: + resolution: {integrity: sha512-CTJ+AEQJjq5NzLga5pE39qdiSV56F8ywCIsqNIRF0r7BDgWsN25aazToqAFg7ZrtA/U016xudB3ffgweORxX7g==} + engines: {node: '>= 12.13.0'} + peerDependencies: + '@rspack/core': 0.x || 1.x + webpack: ^5.0.0 + peerDependenciesMeta: + '@rspack/core': + optional: true + webpack: + optional: true - proxy-from-env@1.1.0: - resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + css-minimizer-webpack-plugin@5.0.1: + resolution: {integrity: sha512-3caImjKFQkS+ws1TGcFn0V1HyDJFq1Euy589JlD6/3rV2kj+w7r5G9WDMgSHvpvXHNZ2calVypZWuEDQd9wfLg==} + engines: {node: '>= 14.15.0'} + peerDependencies: + '@parcel/css': '*' + '@swc/css': '*' + clean-css: '*' + csso: '*' + esbuild: '*' + lightningcss: '*' + webpack: ^5.0.0 + peerDependenciesMeta: + '@parcel/css': + optional: true + '@swc/css': + optional: true + clean-css: + optional: true + csso: + optional: true + esbuild: + optional: true + lightningcss: + optional: true - pump@3.0.3: - resolution: {integrity: sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==} + css-prefers-color-scheme@10.0.0: + resolution: {integrity: sha512-VCtXZAWivRglTZditUfB4StnsWr6YVZ2PRtuxQLKTNRdtAf8tpzaVPE9zXIF3VaSc7O70iK/j1+NXxyQCqdPjQ==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 - pvtsutils@1.3.6: - resolution: {integrity: sha512-PLgQXQ6H2FWCaeRak8vvk1GW462lMxB5s3Jm673N82zI4vqtVUPuZdffdZbPDFRoU8kAhItWFtPCWiPpp4/EDg==} + css-select@4.3.0: + resolution: {integrity: sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==} - pvutils@1.1.5: - resolution: {integrity: sha512-KTqnxsgGiQ6ZAzZCVlJH5eOjSnvlyEgx1m8bkRJfOhmGRqfo5KLvmAlACQkrjEtOQ4B7wF9TdSLIs9O90MX9xA==} - engines: {node: '>=16.0.0'} + css-select@5.2.2: + resolution: {integrity: sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==} - qr@0.5.3: - resolution: {integrity: sha512-BSrGdNXa8z6PfEYWtvITV21mQ4asR4UCj38Fa3MUUoFAtYzFK/swEQXF+OeBuNbHPFfs3PzpZuK0BXizWXgFOQ==} - engines: {node: '>= 20.19.0'} + css-tree@2.2.1: + resolution: {integrity: sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==} + engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0, npm: '>=7.0.0'} - qrcode@1.5.3: - resolution: {integrity: sha512-puyri6ApkEHYiVl4CFzo1tDkAZ+ATcnbJrJ6RiBM1Fhctdn/ix9MTE3hRph33omisEbC/2fcfemsseiKgBPKZg==} - engines: {node: '>=10.13.0'} - hasBin: true + css-tree@2.3.1: + resolution: {integrity: sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==} + engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0} - qs@6.14.0: - resolution: {integrity: sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==} - engines: {node: '>=0.6'} + css-what@6.2.2: + resolution: {integrity: sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==} + engines: {node: '>= 6'} - query-string@7.1.3: - resolution: {integrity: sha512-hh2WYhq4fi8+b+/2Kg9CEge4fDPvHS534aOOvOZeQ3+Vf2mCFsaFBYj0i+iXcAq6I9Vzp5fjMFBlONvayDC1qg==} - engines: {node: '>=6'} + cssdb@8.7.0: + resolution: {integrity: sha512-UxiWVpV953ENHqAKjKRPZHNDfRo3uOymvO5Ef7MFCWlenaohkYj7PTO7WCBdjZm8z/aDZd6rXyUIlwZ0AjyFSg==} - queue-microtask@1.2.3: - resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + cssesc@3.0.0: + resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} + engines: {node: '>=4'} + hasBin: true - quick-format-unescaped@4.0.4: - resolution: {integrity: sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==} + cssnano-preset-advanced@6.1.2: + resolution: {integrity: sha512-Nhao7eD8ph2DoHolEzQs5CfRpiEP0xa1HBdnFZ82kvqdmbwVBUr2r1QuQ4t1pi+D1ZpqpcO4T+wy/7RxzJ/WPQ==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 - radix3@1.1.2: - resolution: {integrity: sha512-b484I/7b8rDEdSDKckSSBA8knMpcdsXudlE/LNL639wFoHKwLbEkQFZHWEYwDC0wa0FKUcCY+GAF73Z7wxNVFA==} + cssnano-preset-default@6.1.2: + resolution: {integrity: sha512-1C0C+eNaeN8OcHQa193aRgYexyJtU8XwbdieEjClw+J9d94E41LwT6ivKH0WT+fYwYWB0Zp3I3IZ7tI/BbUbrg==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 - randombytes@2.1.0: - resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} + cssnano-utils@4.0.2: + resolution: {integrity: sha512-ZR1jHg+wZ8o4c3zqf1SIUSTIvm/9mU343FMR6Obe/unskbvpGhZOo1J6d/r8D1pzkRQYuwbcH3hToOuoA2G7oQ==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 - raw-body@2.5.3: - resolution: {integrity: sha512-s4VSOf6yN0rvbRZGxs8Om5CWj6seneMwK3oDb4lWDH0UPhWcxwOWw5+qk24bxq87szX1ydrwylIOp2uG1ojUpA==} - engines: {node: '>= 0.8'} + cssnano@6.1.2: + resolution: {integrity: sha512-rYk5UeX7VAM/u0lNqewCdasdtPK81CgX8wJFLEIXHbV2oldWRgJAsZrdhRXkV1NJzA2g850KiFm9mMU2HxNxMA==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 - react-dom@18.3.1: - resolution: {integrity: sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==} + csso@5.0.5: + resolution: {integrity: sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==} + engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0, npm: '>=7.0.0'} + + csstype@3.2.3: + resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} + + cuer@0.0.3: + resolution: {integrity: sha512-f/UNxRMRCYtfLEGECAViByA3JNflZImOk11G9hwSd+44jvzrc99J35u5l+fbdQ2+ZG441GvOpaeGYBmWquZsbQ==} peerDependencies: - react: ^18.3.1 + react: '>=18' + react-dom: '>=18' + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true - react-refresh@0.17.0: - resolution: {integrity: sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ==} - engines: {node: '>=0.10.0'} + date-fns@2.30.0: + resolution: {integrity: sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==} + engines: {node: '>=0.11'} - react-remove-scroll-bar@2.3.8: - resolution: {integrity: sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==} - engines: {node: '>=10'} + dayjs@1.11.13: + resolution: {integrity: sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==} + + death@1.1.0: + resolution: {integrity: sha512-vsV6S4KVHvTGxbEcij7hkWRv0It+sGGWVOM67dQde/o5Xjnr+KmLjxWJii2uEObIrt1CcM9w0Yaovx+iOlIL+w==} + + debounce@1.2.1: + resolution: {integrity: sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==} + + debug@2.6.9: + resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} peerDependencies: - '@types/react': '*' - react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + supports-color: '*' peerDependenciesMeta: - '@types/react': + supports-color: optional: true - react-remove-scroll@2.6.2: - resolution: {integrity: sha512-KmONPx5fnlXYJQqC62Q+lwIeAk64ws/cUw6omIumRzMRPqgnYqhSSti99nbj0Ry13bv7dF+BKn7NB+OqkdZGTw==} - engines: {node: '>=10'} + debug@4.3.4: + resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} + engines: {node: '>=6.0'} peerDependencies: - '@types/react': '*' - react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc + supports-color: '*' peerDependenciesMeta: - '@types/react': + supports-color: optional: true - react-style-singleton@2.2.3: - resolution: {integrity: sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==} - engines: {node: '>=10'} + debug@4.4.3: + resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} + engines: {node: '>=6.0'} peerDependencies: - '@types/react': '*' - react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc + supports-color: '*' peerDependenciesMeta: - '@types/react': + supports-color: optional: true - react@18.3.1: - resolution: {integrity: sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==} + decamelize@1.2.0: + resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==} engines: {node: '>=0.10.0'} - read-cache@1.0.0: - resolution: {integrity: sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==} - - 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'} + decamelize@4.0.0: + resolution: {integrity: sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==} + engines: {node: '>=10'} - readdirp@3.6.0: - resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} - engines: {node: '>=8.10.0'} + decode-named-character-reference@1.3.0: + resolution: {integrity: sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q==} - readdirp@4.1.2: - resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} - engines: {node: '>= 14.18.0'} + decode-uri-component@0.2.2: + resolution: {integrity: sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==} + engines: {node: '>=0.10'} - real-require@0.1.0: - resolution: {integrity: sha512-r/H9MzAWtrv8aSVjPCMFpDMl5q66GqtmmRkRjpHTsp4zBAa+snZyiQNlMONiUmEJcsnaw0wCauJ2GWODr/aFkg==} - engines: {node: '>= 12.13.0'} + decompress-response@6.0.0: + resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==} + engines: {node: '>=10'} - rechoir@0.6.2: - resolution: {integrity: sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==} - engines: {node: '>= 0.10'} + dedent@1.7.1: + resolution: {integrity: sha512-9JmrhGZpOlEgOLdQgSm0zxFaYoQon408V1v49aqTWuXENVlnCuY9JBZcXZiCsZQWDjTm5Qf/nIvAy77mXDAjEg==} + peerDependencies: + babel-plugin-macros: ^3.1.0 + peerDependenciesMeta: + babel-plugin-macros: + optional: true - recursive-readdir@2.2.3: - resolution: {integrity: sha512-8HrF5ZsXk5FAH9dgsx3BlUer73nIhuj+9OrQwEbLTPOBzGkL1lsFCR01am+v+0m2Cmbs1nP12hLDl5FA7EszKA==} - engines: {node: '>=6.0.0'} + deep-eql@4.1.4: + resolution: {integrity: sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg==} + engines: {node: '>=6'} - reduce-flatten@2.0.0: - resolution: {integrity: sha512-EJ4UNY/U1t2P/2k6oqotuX2Cc3T6nxJwsM0N0asT7dhrtH1ltUxDn4NalSYmPE2rCkVpcf/X6R0wDwcFpzhd4w==} + deep-eql@5.0.2: + resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==} engines: {node: '>=6'} - req-cwd@2.0.0: - resolution: {integrity: sha512-ueoIoLo1OfB6b05COxAA9UpeoscNpYyM+BqYlA7H6LVF4hKGPXQQSSaD2YmvDVJMkk4UDpAHIeU1zG53IqjvlQ==} - engines: {node: '>=4'} + deep-extend@0.6.0: + resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==} + engines: {node: '>=4.0.0'} - req-from@2.0.0: - resolution: {integrity: sha512-LzTfEVDVQHBRfjOUMgNBA+V6DWsSnoeKzf42J7l0xa/B4jyPOuuF5MlNSmomLNGemWTnV2TIdjSSLnEn95fOQA==} - engines: {node: '>=4'} + deep-is@0.1.4: + resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} - require-directory@2.1.1: - resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} - engines: {node: '>=0.10.0'} + deep-object-diff@1.1.9: + resolution: {integrity: sha512-Rn+RuwkmkDwCi2/oXOFS9Gsr5lJZu/yTGpK7wAaAIE75CC+LCGEZHpY6VQJa/RoJcrmaA/docWJZvYohlNkWPA==} - require-from-string@2.0.2: - resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} + deepmerge@4.3.1: + resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} engines: {node: '>=0.10.0'} - require-main-filename@2.0.0: - resolution: {integrity: sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==} - - resolve-from@3.0.0: - resolution: {integrity: sha512-GnlH6vxLymXJNMBo7XP1fJIzBFbdYt49CuTwmB/6N53t+kMPRMFKz783LlQ4tv28XoQfMWinAJX6WCGf2IlaIw==} - engines: {node: '>=4'} + default-browser-id@5.0.1: + resolution: {integrity: sha512-x1VCxdX4t+8wVfd1so/9w+vQ4vx7lKd2Qp5tDRutErwmR85OgmfX7RlLRMWafRMY7hbEiXIbudNrjOAPa/hL8Q==} + engines: {node: '>=18'} - resolve@1.1.7: - resolution: {integrity: sha512-9znBF0vBcaSN3W2j7wKvdERPwqTxSpCq+if5C0WoTCyV9n24rua28jeuQ2pL/HOf+yUe/Mef+H/5p60K0Id3bg==} + default-browser@5.4.0: + resolution: {integrity: sha512-XDuvSq38Hr1MdN47EDvYtx3U0MTqpCEn+F6ft8z2vYDzMrvQhVp0ui9oQdqW3MvK3vqUETglt1tVGgjLuJ5izg==} + engines: {node: '>=18'} - resolve@1.17.0: - resolution: {integrity: sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==} + defer-to-connect@2.0.1: + resolution: {integrity: sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==} + engines: {node: '>=10'} - resolve@1.22.11: - resolution: {integrity: sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==} + define-data-property@1.1.4: + resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} engines: {node: '>= 0.4'} - hasBin: true - retry@0.12.0: - resolution: {integrity: sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==} - engines: {node: '>= 4'} + define-lazy-prop@2.0.0: + resolution: {integrity: sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==} + engines: {node: '>=8'} - retry@0.13.1: - resolution: {integrity: sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==} - engines: {node: '>= 4'} - - reusify@1.1.0: - resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} - engines: {iojs: '>=1.0.0', node: '>=0.10.0'} - - ripemd160@2.0.3: - resolution: {integrity: sha512-5Di9UC0+8h1L6ZD2d7awM7E/T4uA1fJRlx6zk/NvdCCVEoAnFqvHmCuNeIKoCeIixBX/q8uM+6ycDvF8woqosA==} - engines: {node: '>= 0.8'} + define-lazy-prop@3.0.0: + resolution: {integrity: sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==} + engines: {node: '>=12'} - rlp@2.2.7: - resolution: {integrity: sha512-d5gdPmgQ0Z+AklL2NVXr/IoSjNZFfTVvQWzL/AM2AOcSzYP2xjlb0AC8YyCLc41MSNf6P6QVtjgPdmVtzb+4lQ==} - hasBin: true + define-properties@1.2.1: + resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} + engines: {node: '>= 0.4'} - rollup@4.53.5: - resolution: {integrity: sha512-iTNAbFSlRpcHeeWu73ywU/8KuU/LZmNCSxp6fjQkJBD3ivUb8tpDrXhIxEzA05HlYMEwmtaUnb3RP+YNv162OQ==} - engines: {node: '>=18.0.0', npm: '>=8.0.0'} - hasBin: true + defu@6.1.4: + resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==} - rpc-websockets@9.3.2: - resolution: {integrity: sha512-VuW2xJDnl1k8n8kjbdRSWawPRkwaVqUQNjE1TdeTawf0y0abGhtVJFTXCLfgpgGDBkO/Fj6kny8Dc/nvOW78MA==} + delay@5.0.0: + resolution: {integrity: sha512-ReEBKkIfe4ya47wlPYf/gu5ib6yUG0/Aez0JQZQz94kiWtRQvZIQbTiehsnwHvLSWJnQdhVeqYue7Id1dKr0qw==} + engines: {node: '>=10'} - run-parallel@1.2.0: - resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} - safe-buffer@5.1.2: - resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} + depd@1.1.2: + resolution: {integrity: sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==} + engines: {node: '>= 0.6'} - safe-buffer@5.2.1: - resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + depd@2.0.0: + resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} + engines: {node: '>= 0.8'} - safe-regex-test@1.1.0: - resolution: {integrity: sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==} - engines: {node: '>= 0.4'} + dequal@2.0.3: + resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} + engines: {node: '>=6'} - safe-stable-stringify@2.5.0: - resolution: {integrity: sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==} - engines: {node: '>=10'} + derive-valtio@0.1.0: + resolution: {integrity: sha512-OCg2UsLbXK7GmmpzMXhYkdO64vhJ1ROUUGaTFyHjVwEdMEcTTRj7W1TxLbSBxdY8QLBPCcp66MTyaSy0RpO17A==} + peerDependencies: + valtio: '*' - safer-buffer@2.1.2: - resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + destr@2.0.5: + resolution: {integrity: sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==} - sc-istanbul@0.4.6: - resolution: {integrity: sha512-qJFF/8tW/zJsbyfh/iT/ZM5QNHE3CXxtLJbZsL+CzdJLBsPD7SedJZoUA4d8iAcN2IoMp/Dx80shOOd2x96X/g==} - hasBin: true + destroy@1.2.0: + resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==} + engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} - scheduler@0.23.2: - resolution: {integrity: sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==} + detect-browser@5.3.0: + resolution: {integrity: sha512-53rsFbGdwMwlF7qvCt0ypLM5V5/Mbl0szB7GPN8y9NCcbknYOeVVXdrXEq+90IwAfrrzt6Hd+u2E2ntakICU8w==} - scrypt-js@3.0.1: - resolution: {integrity: sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==} + detect-node-es@1.1.0: + resolution: {integrity: sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==} - secp256k1@4.0.4: - resolution: {integrity: sha512-6JfvwvjUOn8F/jUoBY2Q1v5WY5XS+rj8qSe0v8Y4ezH4InLgTEeOOPQsRll9OV429Pvo6BCHGavIyJfr3TAhsw==} - engines: {node: '>=18.0.0'} + detect-node@2.1.0: + resolution: {integrity: sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==} - semver@5.7.2: - resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==} + detect-port@1.6.1: + resolution: {integrity: sha512-CmnVc+Hek2egPx1PeTFVta2W78xy2K/9Rkf6cC4T59S50tVnzKj+tnx5mmx5lwvCkujZ4uRrpRSuV+IVs3f90Q==} + engines: {node: '>= 4.0.0'} hasBin: true - semver@6.3.1: - resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} - hasBin: true + devlop@1.1.0: + resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} - semver@7.7.3: - resolution: {integrity: sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==} - engines: {node: '>=10'} - hasBin: true + dexie@4.2.1: + resolution: {integrity: sha512-Ckej0NS6jxQ4Po3OrSQBFddayRhTCic2DoCAG5zacOfOVB9P2Q5Xc5uL/nVa7ZVs+HdMnvUPzLFCB/JwpB6Csg==} - serialize-javascript@6.0.2: - resolution: {integrity: sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==} + didyoumean@1.2.2: + resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==} - set-blocking@2.0.0: - resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} + diff@4.0.2: + resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} + engines: {node: '>=0.3.1'} - set-function-length@1.2.2: - resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} - engines: {node: '>= 0.4'} + diff@5.2.0: + resolution: {integrity: sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==} + engines: {node: '>=0.3.1'} - setimmediate@1.0.5: - resolution: {integrity: sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==} + difflib@0.2.4: + resolution: {integrity: sha512-9YVwmMb0wQHQNr5J9m6BSj6fk4pfGITGQOOs+D9Fl+INODWFOfvhIU1hNv6GgR1RBoC/9NJcwu77zShxV0kT7w==} - setprototypeof@1.2.0: - resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} + dijkstrajs@1.0.3: + resolution: {integrity: sha512-qiSlmBq9+BCdCA/L46dw8Uy93mloxsPSbwnm5yrKn2vMPiy8KyAskTF6zuV/j5BMsmOGZDPs7KjU+mjb670kfA==} - sha.js@2.4.12: - resolution: {integrity: sha512-8LzC5+bvI45BjpfXU8V5fdU2mfeKiQe1D1gIMn7XUlF3OTUrpdJpPPH4EMAnF0DsHHdSZqCdSss5qCmJKuiO3w==} - engines: {node: '>= 0.10'} - hasBin: true + dir-glob@3.0.1: + resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} + engines: {node: '>=8'} - sha1@1.1.1: - resolution: {integrity: sha512-dZBS6OrMjtgVkopB1Gmo4RQCDKiZsqcpAQpkV/aaj+FCrCg8r4I4qMkDPQjBgLIxlmu9k4nUbWq6ohXahOneYA==} + dlv@1.1.3: + resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==} - shelljs@0.8.5: - resolution: {integrity: sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==} - engines: {node: '>=4'} - hasBin: true + dns-packet@5.6.1: + resolution: {integrity: sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw==} + engines: {node: '>=6'} - side-channel-list@1.0.0: - resolution: {integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==} - engines: {node: '>= 0.4'} + dom-converter@0.2.0: + resolution: {integrity: sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==} - side-channel-map@1.0.1: - resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==} - engines: {node: '>= 0.4'} + dom-serializer@1.4.1: + resolution: {integrity: sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==} - side-channel-weakmap@1.0.2: - resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==} - engines: {node: '>= 0.4'} + dom-serializer@2.0.0: + resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==} - side-channel@1.1.0: - resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==} - engines: {node: '>= 0.4'} + domelementtype@2.3.0: + resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} - siginfo@2.0.0: - resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} + domhandler@4.3.1: + resolution: {integrity: sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==} + engines: {node: '>= 4'} - signal-exit@3.0.7: - resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + domhandler@5.0.3: + resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} + engines: {node: '>= 4'} - sisteransi@1.0.5: - resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} + domutils@2.8.0: + resolution: {integrity: sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==} - slash@3.0.0: - resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} - engines: {node: '>=8'} + domutils@3.2.2: + resolution: {integrity: sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==} - slice-ansi@4.0.0: - resolution: {integrity: sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==} - engines: {node: '>=10'} + dot-case@3.0.4: + resolution: {integrity: sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==} - socket.io-client@4.8.1: - resolution: {integrity: sha512-hJVXfu3E28NmzGk8o1sHhN3om52tRvwYeidbj7xKy2eIIse5IoKX3USlS6Tqt3BHAtflLIkCQBkzVrEEfWUyYQ==} - engines: {node: '>=10.0.0'} + dot-prop@6.0.1: + resolution: {integrity: sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA==} + engines: {node: '>=10'} - socket.io-parser@4.2.4: - resolution: {integrity: sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==} - engines: {node: '>=10.0.0'} + dotenv@16.6.1: + resolution: {integrity: sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==} + engines: {node: '>=12'} - solc@0.8.26: - resolution: {integrity: sha512-yiPQNVf5rBFHwN6SIf3TUUvVAFKcQqmSUFeq+fb6pNRCo0ZCgpYOZDi3BVoezCPIAcKrVYd/qXlBLUP9wVrZ9g==} - engines: {node: '>=10.0.0'} - hasBin: true + dunder-proto@1.0.1: + resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} + engines: {node: '>= 0.4'} - solidity-ast@0.4.61: - resolution: {integrity: sha512-OYBJYcYyG7gLV0VuXl9CUrvgJXjV/v0XnR4+1YomVe3q+QyENQXJJxAEASUz4vN6lMAl+C8RSRSr5MBAz09f6w==} + duplexer@0.1.2: + resolution: {integrity: sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==} - solidity-coverage@0.8.17: - resolution: {integrity: sha512-5P8vnB6qVX9tt1MfuONtCTEaEGO/O4WuEidPHIAJjx4sktHHKhO3rFvnE0q8L30nWJPTrcqGQMT7jpE29B2qow==} - hasBin: true - peerDependencies: - hardhat: ^2.11.0 + duplexify@4.1.3: + resolution: {integrity: sha512-M3BmBhwJRZsSx38lZyhE53Csddgzl5R7xGJNk7CVddZD6CcmwMCH8J+7AprIrQKH7TonKxaCjcv27Qmf+sQ+oA==} - sonic-boom@2.8.0: - resolution: {integrity: sha512-kuonw1YOYYNOve5iHdSahXPOK49GqwA+LZhI6Wz/l0rP57iKyXXIHaRagOBHAPmGwJC6od2Z9zgvZ5loSgMlVg==} + eastasianwidth@0.2.0: + resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} - source-map-js@1.2.1: - resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} - engines: {node: '>=0.10.0'} + eciesjs@0.4.16: + resolution: {integrity: sha512-dS5cbA9rA2VR4Ybuvhg6jvdmp46ubLn3E+px8cG/35aEDNclrqoCjg6mt0HYZ/M+OoESS3jSkCrqk1kWAEhWAw==} + engines: {bun: '>=1', deno: '>=2', node: '>=16'} - source-map-support@0.5.21: - resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} + ee-first@1.1.1: + resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} - source-map@0.2.0: - resolution: {integrity: sha512-CBdZ2oa/BHhS4xj5DlhjWNHcan57/5YuvfdLf17iVmIpd9KRm+DFLmC6nBNj+6Ua7Kt3TmOjDpQT1aTYOQtoUA==} - engines: {node: '>=0.8.0'} + electron-to-chromium@1.5.267: + resolution: {integrity: sha512-0Drusm6MVRXSOJpGbaSVgcQsuB4hEkMpHXaVstcPmhu5LIedxs1xNK/nIxmQIU/RPC0+1/o0AVZfBTkTNJOdUw==} - source-map@0.6.1: - resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} - engines: {node: '>=0.10.0'} + elliptic@6.6.1: + resolution: {integrity: sha512-RaddvvMatK2LJHqFJ+YA4WysVN5Ita9E35botqIYspQ4TkRAlCicdzKOjlyv/1Za5RyTNn7di//eEV0uTAfe3g==} - split-on-first@1.1.0: - resolution: {integrity: sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw==} - engines: {node: '>=6'} + emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} - split2@3.2.2: - resolution: {integrity: sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==} + emoji-regex@9.2.2: + resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} - split2@4.2.0: - resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==} - engines: {node: '>= 10.x'} + emojilib@2.4.0: + resolution: {integrity: sha512-5U0rVMU5Y2n2+ykNLQqMoqklN9ICBT/KsvC1Gz6vqHbz2AXXGkG+Pm5rMWk/8Vjrr/mY9985Hi8DYzn1F09Nyw==} - sprintf-js@1.0.3: - resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} + emojis-list@3.0.0: + resolution: {integrity: sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==} + engines: {node: '>= 4'} - stackback@0.0.2: - resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} + emoticon@4.1.0: + resolution: {integrity: sha512-VWZfnxqwNcc51hIy/sbOdEem6D+cVtpPzEEtVAFdaas30+1dgkyaOQ4sQ6Bp0tOMqWO1v+HQfYaoodOkdhK6SQ==} - stacktrace-parser@0.1.11: - resolution: {integrity: sha512-WjlahMgHmCJpqzU8bIBy4qtsZdU9lRlcZE3Lvyej6t4tuOuv1vk57OW3MBrj6hXBFx/nNoC9MPMTcr5YA7NQbg==} - engines: {node: '>=6'} + encode-utf8@1.0.3: + resolution: {integrity: sha512-ucAnuBEhUK4boH2HjVYG5Q2mQyPorvv0u/ocS+zhdw0S8AlHYY+GOFhP1Gio5z4icpP2ivFSvhtFjQi8+T9ppw==} - statuses@2.0.2: - resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==} + encodeurl@2.0.0: + resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==} engines: {node: '>= 0.8'} - std-env@3.10.0: - resolution: {integrity: sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==} + end-of-stream@1.4.5: + resolution: {integrity: sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==} - stream-chain@2.2.5: - resolution: {integrity: sha512-1TJmBx6aSWqZ4tx7aTpBDXK0/e2hhcNSTV8+CbFJtDjbb+I1mZ8lHit0Grw9GRT+6JbIrrDd8esncgBi8aBXGA==} + engine.io-client@6.6.3: + resolution: {integrity: sha512-T0iLjnyNWahNyv/lcjS2y4oE358tVS/SYQNxYXGAJ9/GLgH4VCvOQ/mhTjqU88mLZCQgiG8RIegFHYCdVC+j5w==} - stream-json@1.9.1: - resolution: {integrity: sha512-uWkjJ+2Nt/LO9Z/JyKZbMusL8Dkh97uUBTv3AJQ74y07lVahLY4eEFsPsE97pxYBwr8nnjMAIch5eqI0gPShyw==} + engine.io-parser@5.2.3: + resolution: {integrity: sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q==} + engines: {node: '>=10.0.0'} - stream-shift@1.0.3: - resolution: {integrity: sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ==} + enhanced-resolve@5.18.4: + resolution: {integrity: sha512-LgQMM4WXU3QI+SYgEc2liRgznaD5ojbmY3sb8LxyguVkIg5FxdpTkvk72te2R38/TGKxH634oLxXRGY6d7AP+Q==} + engines: {node: '>=10.13.0'} - strict-uri-encode@2.0.0: - resolution: {integrity: sha512-QwiXZgpRcKkhTj2Scnn++4PKtWsH0kpzZ62L2R6c/LUVYv7hVnZqcg2+sMuT6R7Jusu1vviK/MFsu6kNJfWlEQ==} - engines: {node: '>=4'} + enquirer@2.4.1: + resolution: {integrity: sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==} + engines: {node: '>=8.6'} - string-format@2.0.0: - resolution: {integrity: sha512-bbEs3scLeYNXLecRRuk6uJxdXUSj6le/8rNPHChIJTn2V79aXVTR1EH2OH5zLKKoz0V02fOUKZZcw01pLUShZA==} + entities@2.2.0: + resolution: {integrity: sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==} - string-width@2.1.1: - resolution: {integrity: sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==} - engines: {node: '>=4'} + entities@4.5.0: + resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} + engines: {node: '>=0.12'} - string-width@4.2.3: - resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} - engines: {node: '>=8'} + entities@6.0.1: + resolution: {integrity: sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==} + engines: {node: '>=0.12'} - string_decoder@1.1.1: - resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} + env-paths@2.2.1: + resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==} + engines: {node: '>=6'} - string_decoder@1.3.0: - resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} + error-ex@1.3.4: + resolution: {integrity: sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==} - strip-ansi@4.0.0: - resolution: {integrity: sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==} - engines: {node: '>=4'} + es-define-property@1.0.1: + resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} + engines: {node: '>= 0.4'} - strip-ansi@6.0.1: - resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} - engines: {node: '>=8'} + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} - strip-hex-prefix@1.0.0: - resolution: {integrity: sha512-q8d4ue7JGEiVcypji1bALTos+0pWtyGlivAWyPuTkHzuTCJqrK9sWxYQZUq6Nq3cuyv3bm734IhHvHtGGURU6A==} - engines: {node: '>=6.5.0', npm: '>=3'} + es-module-lexer@1.7.0: + resolution: {integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==} - strip-json-comments@3.1.1: - resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} - engines: {node: '>=8'} + es-module-lexer@2.0.0: + resolution: {integrity: sha512-5POEcUuZybH7IdmGsD8wlf0AI55wMecM9rVBTI/qEAy2c1kTOm3DjFYjrBdI2K3BaJjJYfYFeRtM0t9ssnRuxw==} - strip-literal@3.1.0: - resolution: {integrity: sha512-8r3mkIM/2+PpjHoOtiAW8Rg3jJLHaV7xPwG+YRGrv6FP0wwk/toTpATxWYOW0BKdWwl82VT2tFYi5DlROa0Mxg==} + es-object-atoms@1.1.1: + resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} + engines: {node: '>= 0.4'} - strnum@2.1.2: - resolution: {integrity: sha512-l63NF9y/cLROq/yqKXSLtcMeeyOfnSQlfMSlzFt/K73oIaD8DGaQWd7Z34X9GPiKqP5rbSh84Hl4bOlLcjiSrQ==} + es-set-tostringtag@2.1.0: + resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} + engines: {node: '>= 0.4'} - sucrase@3.35.1: - resolution: {integrity: sha512-DhuTmvZWux4H1UOnWMB3sk0sbaCVOoQZjv8u1rDoTV0HTdGem9hkAZtl4JZy8P2z4Bg0nT+YMeOFyVr4zcG5Tw==} - engines: {node: '>=16 || 14 >=14.17'} - hasBin: true + es-toolkit@1.33.0: + resolution: {integrity: sha512-X13Q/ZSc+vsO1q600bvNK4bxgXMkHcf//RxCmYDaRY5DAcT+eoXjY5hoAPGMdRnWQjvyLEcyauG3b6hz76LNqg==} - superstruct@1.0.4: - resolution: {integrity: sha512-7JpaAoX2NGyoFlI9NBh66BQXGONc+uE+MRS5i2iOBKuS4e+ccgMDjATgZldkah+33DakBxDHiss9kvUcGAO8UQ==} - engines: {node: '>=14.0.0'} + es6-promise@4.2.8: + resolution: {integrity: sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==} - superstruct@2.0.2: - resolution: {integrity: sha512-uV+TFRZdXsqXTL2pRvujROjdZQ4RAlBUS5BTh9IGm+jTqQntYThciG/qu57Gs69yjnVUSqdxF9YLmSnpupBW9A==} - engines: {node: '>=14.0.0'} + es6-promisify@5.0.0: + resolution: {integrity: sha512-C+d6UdsYDk0lMebHNR4S2NybQMMngAOnOwYBQjTOiv0MkoJMP0Myw2mgpDLBcpfCmRLxyFqYhS/CfOENq4SJhQ==} - supports-color@3.2.3: - resolution: {integrity: sha512-Jds2VIYDrlp5ui7t8abHN2bjAu4LV/q4N2KivFPpGH0lrka0BMq/33AmECUXlKPcHigkNaqfXRENFju+rlcy+A==} - engines: {node: '>=0.8.0'} + esast-util-from-estree@2.0.0: + resolution: {integrity: sha512-4CyanoAudUSBAn5K13H4JhsMH6L9ZP7XbLVe/dKybkxMO7eDyLsT8UHl9TRNrU2Gr9nz+FovfSIjuXWJ81uVwQ==} - supports-color@5.5.0: - resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} - engines: {node: '>=4'} + esast-util-from-js@2.0.1: + resolution: {integrity: sha512-8Ja+rNJ0Lt56Pcf3TAmpBZjmx8ZcK5Ts4cAzIOjsjevg9oSXJnl6SUQ2EevU8tv3h6ZLWmoKL5H4fgWvdvfETw==} - supports-color@7.2.0: - resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} - engines: {node: '>=8'} + esbuild@0.21.5: + resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==} + engines: {node: '>=12'} + hasBin: true - supports-color@8.1.1: - resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} - engines: {node: '>=10'} + escalade@3.2.0: + resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} + engines: {node: '>=6'} - supports-preserve-symlinks-flag@1.0.0: - resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} - engines: {node: '>= 0.4'} + escape-goat@4.0.0: + resolution: {integrity: sha512-2Sd4ShcWxbx6OY1IHyla/CVNwvg7XwZVoXZHcSu9w9SReNP1EzzD5T8NWKIR38fIqEns9kDWKUQTXXAmlDrdPg==} + engines: {node: '>=12'} - sync-request@6.1.0: - resolution: {integrity: sha512-8fjNkrNlNCrVc/av+Jn+xxqfCjYaBoHqCsDz6mt030UMxJGr+GSfCV1dQt2gRtlL63+VPidwDVLr7V2OcTSdRw==} - engines: {node: '>=8.0.0'} + escape-html@1.0.3: + resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} - sync-rpc@1.3.6: - resolution: {integrity: sha512-J8jTXuZzRlvU7HemDgHi3pGnh/rkoqR/OZSjhTyyZrEkkYQbk7Z33AXp37mkPfPpfdOuj7Ex3H/TJM1z48uPQw==} + escape-string-regexp@1.0.5: + resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} + engines: {node: '>=0.8.0'} - table-layout@1.0.2: - resolution: {integrity: sha512-qd/R7n5rQTRFi+Zf2sk5XVVd9UQl6ZkduPFC3S7WEGJAmetDTjY3qPN50eSKzwuzEyQKy5TN2TiZdkIjos2L6A==} - engines: {node: '>=8.0.0'} + escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} - table@6.9.0: - resolution: {integrity: sha512-9kY+CygyYM6j02t5YFHbNz2FN5QmYGv9zAjVp4lCDjlCw7amdckXlEt/bjMhUIfj4ThGRE4gCUH5+yGnNuPo5A==} - engines: {node: '>=10.0.0'} + escape-string-regexp@5.0.0: + resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==} + engines: {node: '>=12'} - tailwindcss@3.4.19: - resolution: {integrity: sha512-3ofp+LL8E+pK/JuPLPggVAIaEuhvIz4qNcf3nA1Xn2o/7fb7s/TYpHhwGDv1ZU3PkBluUVaF8PyCHcm48cKLWQ==} - engines: {node: '>=14.0.0'} + escodegen@1.8.1: + resolution: {integrity: sha512-yhi5S+mNTOuRvyW4gWlg5W1byMaQGWWSYHXsuFZ7GBo7tpyOwi2EdzMP/QWxh9hwkD2m+wDVHJsxhRIj+v/b/A==} + engines: {node: '>=0.12.0'} hasBin: true - text-encoding-utf-8@1.0.2: - resolution: {integrity: sha512-8bw4MY9WjdsD2aMtO0OzOCY3pXGYNx2d2FfHRVUKkiCPDWjKuOlhLVASS+pD7VkLTVjW268LYJHwsnPFlBpbAg==} - - then-request@6.0.2: - resolution: {integrity: sha512-3ZBiG7JvP3wbDzA9iNY5zJQcHL4jn/0BWtXIkagfz7QgOL/LqjCEOBQuJNZfu0XYnv5JhKh+cDxCPM4ILrqruA==} - engines: {node: '>=6.0.0'} + eslint-scope@5.1.1: + resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==} + engines: {node: '>=8.0.0'} - thenify-all@1.6.0: - resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} - engines: {node: '>=0.8'} + esprima@2.7.3: + resolution: {integrity: sha512-OarPfz0lFCiW4/AV2Oy1Rp9qu0iusTKqykwTspGCZtPxmF81JR4MmIebvF1F9+UOKth2ZubLQ4XGGaU+hSn99A==} + engines: {node: '>=0.10.0'} + hasBin: true - thenify@3.3.1: - resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} + esprima@4.0.1: + resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} + engines: {node: '>=4'} + hasBin: true - thread-stream@0.15.2: - resolution: {integrity: sha512-UkEhKIg2pD+fjkHQKyJO3yoIvAP3N6RlNFt2dUhcS1FGvCD1cQa1M/PGknCLFIyZdtJOWQjejp7bdNqmN7zwdA==} + esrecurse@4.3.0: + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} + engines: {node: '>=4.0'} - through2@4.0.2: - resolution: {integrity: sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==} + estraverse@1.9.3: + resolution: {integrity: sha512-25w1fMXQrGdoquWnScXZGckOv+Wes+JDnuN/+7ex3SauFRS72r2lFDec0EKPt2YD1wUJ/IrfEex+9yp4hfSOJA==} + engines: {node: '>=0.10.0'} - tinybench@2.9.0: - resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} + estraverse@4.3.0: + resolution: {integrity: sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==} + engines: {node: '>=4.0'} - tinyexec@0.3.2: - resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==} + estraverse@5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} - tinyglobby@0.2.15: - resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} - engines: {node: '>=12.0.0'} + estree-util-attach-comments@3.0.0: + resolution: {integrity: sha512-cKUwm/HUcTDsYh/9FgnuFqpfquUbwIqwKM26BVCGDPVgvaCl/nDCCjUfiLlx6lsEZ3Z4RFxNbOQ60pkaEwFxGw==} - tinypool@1.1.1: - resolution: {integrity: sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg==} - engines: {node: ^18.0.0 || >=20.0.0} + estree-util-build-jsx@3.0.1: + resolution: {integrity: sha512-8U5eiL6BTrPxp/CHbs2yMgP8ftMhR5ww1eIKoWRMlqvltHF8fZn5LRDvTKuxD3DUn+shRbLGqXemcP51oFCsGQ==} - tinyrainbow@2.0.0: - resolution: {integrity: sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==} - engines: {node: '>=14.0.0'} + estree-util-is-identifier-name@3.0.0: + resolution: {integrity: sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==} - tinyspy@4.0.4: - resolution: {integrity: sha512-azl+t0z7pw/z958Gy9svOTuzqIk6xq+NSheJzn5MMWtWTFywIacg2wUlzKFGtt3cthx0r2SxMK0yzJOR0IES7Q==} - engines: {node: '>=14.0.0'} + estree-util-scope@1.0.0: + resolution: {integrity: sha512-2CAASclonf+JFWBNJPndcOpA8EMJwa0Q8LUFJEKqXLW6+qBvbFZuF5gItbQOs/umBUkjviCSDCbBwU2cXbmrhQ==} - tmp@0.0.33: - resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==} - engines: {node: '>=0.6.0'} + estree-util-to-js@2.0.0: + resolution: {integrity: sha512-WDF+xj5rRWmD5tj6bIqRi6CkLIXbbNQUcxQHzGysQzvHmdYG2G7p/Tf0J0gpxGgkeMZNTIjT/AoSvC9Xehcgdg==} - to-buffer@1.2.2: - resolution: {integrity: sha512-db0E3UJjcFhpDhAF4tLo03oli3pwl3dbnzXOUIlRKrp+ldk/VUxzpWYZENsw2SZiuBjHAk7DfB0VU7NKdpb6sw==} - engines: {node: '>= 0.4'} + estree-util-value-to-estree@3.5.0: + resolution: {integrity: sha512-aMV56R27Gv3QmfmF1MY12GWkGzzeAezAX+UplqHVASfjc9wNzI/X6hC0S9oxq61WT4aQesLGslWP9tKk6ghRZQ==} - to-regex-range@5.0.1: - resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} - engines: {node: '>=8.0'} + estree-util-visit@2.0.0: + resolution: {integrity: sha512-m5KgiH85xAhhW8Wta0vShLcUvOsh3LLPI2YVwcbio1l7E09NTLL1EyMZFM1OyWowoH0skScNbhOPl4kcBgzTww==} - toidentifier@1.0.1: - resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} - engines: {node: '>=0.6'} + estree-walker@3.0.3: + resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} - tr46@0.0.3: - resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} + esutils@2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} - ts-command-line-args@2.5.1: - resolution: {integrity: sha512-H69ZwTw3rFHb5WYpQya40YAX2/w7Ut75uUECbgBIsLmM+BNuYnxsltfyyLMxy6sEeKxgijLTnQtLd0nKd6+IYw==} - hasBin: true + eta@2.2.0: + resolution: {integrity: sha512-UVQ72Rqjy/ZKQalzV5dCCJP80GrmPrMxh6NlNf+erV6ObL0ZFkhCstWRawS85z3smdr3d2wXPsZEY7rDPfGd2g==} + engines: {node: '>=6.0.0'} - ts-essentials@7.0.3: - resolution: {integrity: sha512-8+gr5+lqO3G84KdiTSMRLtuyJ+nTBVRKuCrK4lidMPdVeEp0uqC875uE5NMcaA7YYMN7XsNiFQuMvasF8HT/xQ==} - peerDependencies: - typescript: '>=3.7.0' + etag@1.8.1: + resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} + engines: {node: '>= 0.6'} - ts-interface-checker@0.1.13: - resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} + eth-block-tracker@7.1.0: + resolution: {integrity: sha512-8YdplnuE1IK4xfqpf4iU7oBxnOYAc35934o083G8ao+8WM8QQtt/mVlAY6yIAdY1eMeLqg4Z//PZjJGmWGPMRg==} + engines: {node: '>=14.0.0'} - ts-node@10.9.2: - resolution: {integrity: sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==} - hasBin: true + eth-gas-reporter@0.2.27: + resolution: {integrity: sha512-femhvoAM7wL0GcI8ozTdxfuBtBFJ9qsyIAsmKVjlWAHUbdnnXHt+lKzz/kmldM5lA9jLuNHGwuIxorNpLbR1Zw==} peerDependencies: - '@swc/core': '>=1.2.50' - '@swc/wasm': '>=1.2.50' - '@types/node': '*' - typescript: '>=2.7' + '@codechecks/client': ^0.1.0 peerDependenciesMeta: - '@swc/core': - optional: true - '@swc/wasm': + '@codechecks/client': optional: true - tslib@1.14.1: - resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} + eth-json-rpc-filters@6.0.1: + resolution: {integrity: sha512-ITJTvqoCw6OVMLs7pI8f4gG92n/St6x80ACtHodeS+IXmO0w+t1T5OOzfSt7KLSMLRkVUoexV7tztLgDxg+iig==} + engines: {node: '>=14.0.0'} - tslib@2.7.0: - resolution: {integrity: sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==} + eth-query@2.1.2: + resolution: {integrity: sha512-srES0ZcvwkR/wd5OQBRA1bIJMww1skfGS0s8wlwK3/oNP4+wnds60krvu5R1QbpRQjMmpG5OMIWro5s7gvDPsA==} - tslib@2.8.1: - resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + eth-rpc-errors@4.0.3: + resolution: {integrity: sha512-Z3ymjopaoft7JDoxZcEb3pwdGh7yiYMhOwm2doUt6ASXlMavpNlK6Cre0+IMl2VSGyEU9rkiperQhp5iRxn5Pg==} - tsort@0.0.1: - resolution: {integrity: sha512-Tyrf5mxF8Ofs1tNoxA13lFeZ2Zrbd6cKbuH3V+MQ5sb6DtBj5FjrXVsRWT8YvNAQTqNoz66dz1WsbigI22aEnw==} + ethereum-bloom-filters@1.2.0: + resolution: {integrity: sha512-28hyiE7HVsWubqhpVLVmZXFd4ITeHi+BUu05o9isf0GUpMtzBUi+8/gFrGaGYzvGAJQmJ3JKj77Mk9G98T84rA==} - tweetnacl@1.0.3: - resolution: {integrity: sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==} + ethereum-cryptography@0.1.3: + resolution: {integrity: sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==} - type-check@0.3.2: - resolution: {integrity: sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==} - engines: {node: '>= 0.8.0'} + ethereum-cryptography@1.2.0: + resolution: {integrity: sha512-6yFQC9b5ug6/17CQpCyE3k9eKBMdhyVjzUy1WkiuY/E4vj/SXDBbCw8QEIaXqf0Mf2SnY6RmpDcwlUmBSS0EJw==} - type-detect@4.1.0: - resolution: {integrity: sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==} - engines: {node: '>=4'} + ethereum-cryptography@2.2.1: + resolution: {integrity: sha512-r/W8lkHSiTLxUxW8Rf3u4HGB0xQweG2RyETjywylKZSzLWoWAijRz8WCuOtJ6wah+avllXBqZuk29HCCvhEIRg==} - type-fest@0.20.2: - resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} - engines: {node: '>=10'} + ethereumjs-util@7.1.5: + resolution: {integrity: sha512-SDl5kKrQAudFBUe5OJM9Ac6WmMyYmXX/6sTmLZ3ffG2eY6ZIGBes3pEDxNN6V72WyOw4CPD5RomKdsa8DAAwLg==} + engines: {node: '>=10.0.0'} - type-fest@0.21.3: - resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} - engines: {node: '>=10'} + ethers@5.8.0: + resolution: {integrity: sha512-DUq+7fHrCg1aPDFCHx6UIPb3nmt2XMpM7Y/g2gLhsl3lIBqeAfOJIl1qEvRf2uq3BiKxmh6Fh5pfp2ieyek7Kg==} - type-fest@0.7.1: - resolution: {integrity: sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg==} - engines: {node: '>=8'} + ethers@6.16.0: + resolution: {integrity: sha512-U1wulmetNymijEhpSEQ7Ct/P/Jw9/e7R1j5XIbPRydgV2DjLVMsULDlNksq3RQnFgKoLlZf88ijYtWEXcPa07A==} + engines: {node: '>=14.0.0'} - typechain@8.3.2: - resolution: {integrity: sha512-x/sQYr5w9K7yv3es7jo4KTX05CLxOf7TRWwoHlrjRh8H82G64g+k7VuWPJlgMo6qrjfCulOdfBjiaDtmhFYD/Q==} - hasBin: true - peerDependencies: - typescript: '>=4.3.0' + ethjs-unit@0.1.6: + resolution: {integrity: sha512-/Sn9Y0oKl0uqQuvgFk/zQgR7aw1g36qX/jzSQ5lSwlO0GigPymk4eGQfeNTD03w1dPOqfz8V77Cy43jH56pagw==} + engines: {node: '>=6.5.0', npm: '>=3'} - typed-array-buffer@1.0.3: - resolution: {integrity: sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==} - engines: {node: '>= 0.4'} + eval@0.1.8: + resolution: {integrity: sha512-EzV94NYKoO09GLXGjXj9JIlXijVck4ONSr5wiCWDvhsvj5jxSrzTmRU/9C1DyB6uToszLs8aifA6NQ7lEQdvFw==} + engines: {node: '>= 0.8'} - typedarray@0.0.6: - resolution: {integrity: sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==} + eventemitter2@6.4.9: + resolution: {integrity: sha512-JEPTiaOt9f04oa6NOkc4aH+nVp5I3wEjpHbIPqfgCdD5v5bUzy7xQqwcVO2aDQgOWhI28da57HksMrzK9HlRxg==} - typescript@5.9.3: - resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} - engines: {node: '>=14.17'} - hasBin: true + eventemitter3@4.0.7: + resolution: {integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==} - typical@4.0.0: - resolution: {integrity: sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw==} - engines: {node: '>=8'} + eventemitter3@5.0.1: + resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==} - typical@5.2.0: - resolution: {integrity: sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg==} - engines: {node: '>=8'} + events@3.3.0: + resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} + engines: {node: '>=0.8.x'} - ua-parser-js@1.0.41: - resolution: {integrity: sha512-LbBDqdIC5s8iROCUjMbW1f5dJQTEFB1+KO9ogbvlb3nm9n4YHa5p4KTvFPWvh2Hs8gZMBuiB1/8+pdfe/tDPug==} - hasBin: true + evp_bytestokey@1.0.3: + resolution: {integrity: sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==} - ufo@1.6.1: - resolution: {integrity: sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==} + execa@5.1.1: + resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} + engines: {node: '>=10'} - uglify-js@3.19.3: - resolution: {integrity: sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==} - engines: {node: '>=0.8.0'} - hasBin: true + expect-type@1.3.0: + resolution: {integrity: sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==} + engines: {node: '>=12.0.0'} - uint8arrays@3.1.0: - resolution: {integrity: sha512-ei5rfKtoRO8OyOIor2Rz5fhzjThwIHJZ3uyDPnDHTXbP0aMQ1RN/6AI5B5d9dBxJOU+BvOAk7ZQ1xphsX8Lrog==} + express@4.22.1: + resolution: {integrity: sha512-F2X8g9P1X7uCPZMA3MVf9wcTqlyNp7IhH5qPCI0izhaOIYXaW9L535tGA3qmjRzpH+bZczqq7hVKxTR4NWnu+g==} + engines: {node: '>= 0.10.0'} - uncrypto@0.1.3: - resolution: {integrity: sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q==} + extend-shallow@2.0.1: + resolution: {integrity: sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==} + engines: {node: '>=0.10.0'} - undici-types@6.19.8: - resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==} + extend@3.0.2: + resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} - undici-types@6.21.0: - resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} + extension-port-stream@3.0.0: + resolution: {integrity: sha512-an2S5quJMiy5bnZKEf6AkfH/7r8CzHvhchU40gxN+OM6HPhe7Z9T1FUychcf2M9PpPOO0Hf7BAEfJkw2TDIBDw==} + engines: {node: '>=12.0.0'} - undici-types@7.16.0: - resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==} + eyes@0.1.8: + resolution: {integrity: sha512-GipyPsXO1anza0AOZdy69Im7hGFCNB7Y/NGjDlZGJ3GJJLtwNSb2vrzYrTYJRrRloVx7pl+bhUaTB8yiccPvFQ==} + engines: {node: '> 0.1.90'} - undici@5.29.0: - resolution: {integrity: sha512-raqeBD6NQK4SkWhQzeYKd1KmIG6dllBOTt55Rmkt4HtI9mwdWtJljnrXjAFUBLTSN67HWrOIZ3EPF4kjUw80Bg==} - engines: {node: '>=14.0'} + fast-base64-decode@1.0.0: + resolution: {integrity: sha512-qwaScUgUGBYeDNRnbc/KyllVU88Jk1pRHPStuF/lO7B0/RTRLj7U0lkdTAutlBblY08rwZDff6tNU9cjv6j//Q==} - undici@6.22.0: - resolution: {integrity: sha512-hU/10obOIu62MGYjdskASR3CUAiYaFTtC9Pa6vHyf//mAipSvSQg6od2CnJswq7fvzNS3zJhxoRkgNVaHurWKw==} - engines: {node: '>=18.17'} + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} - unfetch@4.2.0: - resolution: {integrity: sha512-F9p7yYCn6cIW9El1zi0HI6vqpeIvBsr3dSuRO6Xuppb1u5rXpCPmMvLSyECLhybr9isec8Ohl0hPekMVrEinDA==} + fast-glob@3.3.3: + resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} + engines: {node: '>=8.6.0'} - universalify@0.1.2: - resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} - engines: {node: '>= 4.0.0'} + fast-json-stable-stringify@2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} - universalify@2.0.1: - resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} - engines: {node: '>= 10.0.0'} + fast-levenshtein@2.0.6: + resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} - unpipe@1.0.0: - resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} - engines: {node: '>= 0.8'} + fast-redact@3.5.0: + resolution: {integrity: sha512-dwsoQlS7h9hMeYUq1W++23NDcBLV4KqONnITDV9DjfS3q1SgDGVrBdvvTLUotWtPSD7asWDV9/CmsZPy8Hf70A==} + engines: {node: '>=6'} - unstorage@1.17.3: - resolution: {integrity: sha512-i+JYyy0DoKmQ3FximTHbGadmIYb8JEpq7lxUjnjeB702bCPum0vzo6oy5Mfu0lpqISw7hCyMW2yj4nWC8bqJ3Q==} - 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.0.3 || ^7.0.0 - '@deno/kv': '>=0.9.0' - '@netlify/blobs': ^6.5.0 || ^7.0.0 || ^8.1.0 || ^9.0.0 || ^10.0.0 - '@planetscale/database': ^1.19.0 - '@upstash/redis': ^1.34.3 - '@vercel/blob': '>=0.27.1' - '@vercel/functions': ^2.2.12 || ^3.0.0 - '@vercel/kv': ^1.0.1 - aws4fetch: ^1.0.20 - db0: '>=0.2.1' - 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 + fast-safe-stringify@2.1.1: + resolution: {integrity: sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==} - update-browserslist-db@1.2.3: - resolution: {integrity: sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==} + fast-stable-stringify@1.0.0: + resolution: {integrity: sha512-wpYMUmFu5f00Sm0cj2pfivpmawLZ0NKdviQ4w9zJeR8JVtOpOxHmLaJuj0vxvGqMJQWyP/COUkF75/57OKyRag==} + + fast-uri@3.1.0: + resolution: {integrity: sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==} + + fast-xml-parser@5.2.5: + resolution: {integrity: sha512-pfX9uG9Ki0yekDHx2SiuRIyFdyAr1kMIMitPvb0YBo8SUfKvia7w7FIyd/l6av85pFYRhZscS75MwMnbvY+hcQ==} hasBin: true - peerDependencies: - browserslist: '>= 4.21.0' - use-callback-ref@1.3.3: - resolution: {integrity: sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==} - engines: {node: '>=10'} - peerDependencies: - '@types/react': '*' - react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true + fastestsmallesttextencoderdecoder@1.0.22: + resolution: {integrity: sha512-Pb8d48e+oIuY4MaM64Cd7OW1gt4nxCHs7/ddPPZ/Ic3sg8yVGM7O9wDvZ7us6ScaUupzM+pfBolwtYhN1IxBIw==} - use-sidecar@1.1.3: - resolution: {integrity: sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==} - engines: {node: '>=10'} + fastq@1.19.1: + resolution: {integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==} + + fault@2.0.1: + resolution: {integrity: sha512-WtySTkS4OKev5JtpHXnib4Gxiurzh5NCGvWrFaZ34m6JehfTUhKZvn9njTfw48t6JumVQOmrKqpmGcdwxnhqBQ==} + + faye-websocket@0.11.4: + resolution: {integrity: sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==} + engines: {node: '>=0.8.0'} + + fdir@6.5.0: + resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} + engines: {node: '>=12.0.0'} peerDependencies: - '@types/react': '*' - react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc + picomatch: ^3 || ^4 peerDependenciesMeta: - '@types/react': + picomatch: optional: true - use-sync-external-store@1.2.0: - resolution: {integrity: sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==} - peerDependencies: - react: ^16.8.0 || ^17.0.0 || ^18.0.0 + feed@4.2.2: + resolution: {integrity: sha512-u5/sxGfiMfZNtJ3OvQpXcvotFpYkL0n9u9mM2vkui2nGo8b4wvDkJ8gAkYqbA8QpGyFCv3RK0Z+Iv+9veCS9bQ==} + engines: {node: '>=0.4.0'} - use-sync-external-store@1.4.0: - resolution: {integrity: sha512-9WXSPC5fMv61vaupRkCKCxsPxBocVnwakBEkMIHHpkTTg6icbJtg6jzgtLDm4bl3cSHAca52rYWih0k4K3PfHw==} + figures@3.2.0: + resolution: {integrity: sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==} + engines: {node: '>=8'} + + file-loader@6.2.0: + resolution: {integrity: sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw==} + engines: {node: '>= 10.13.0'} peerDependencies: - react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + webpack: ^4.0.0 || ^5.0.0 - utf-8-validate@5.0.10: - resolution: {integrity: sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ==} - engines: {node: '>=6.14.2'} + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} - utf8@3.0.0: - resolution: {integrity: sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ==} + filter-obj@1.1.0: + resolution: {integrity: sha512-8rXg1ZnX7xzy2NGDVkBVaAy+lSlPNwad13BtgSlLuxfIslyt5Vg64U7tFcCt4WS1R0hvtnQybT/IyCkGZ3DpXQ==} + engines: {node: '>=0.10.0'} - util-deprecate@1.0.2: - resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + finalhandler@1.3.2: + resolution: {integrity: sha512-aA4RyPcd3badbdABGDuTXCMTtOneUCAYH/gxoYRTZlIJdF0YPWuGqiAsIrhNnnqdXGswYk6dGujem4w80UJFhg==} + engines: {node: '>= 0.8'} - util@0.12.5: - resolution: {integrity: sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==} + find-cache-dir@4.0.0: + resolution: {integrity: sha512-9ZonPT4ZAK4a+1pUPVPZJapbi7O5qbbJPdYw/NOQWZZbVLdDTYM3A4R9z/DpAM08IDaFGsvPgiGZ82WEwUDWjg==} + engines: {node: '>=14.16'} - uuid@8.3.2: - resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} - hasBin: true + find-replace@3.0.0: + resolution: {integrity: sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ==} + engines: {node: '>=4.0.0'} - uuid@9.0.1: - resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==} - hasBin: true + find-up@4.1.0: + resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} + engines: {node: '>=8'} - v8-compile-cache-lib@3.0.1: - resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} + find-up@5.0.0: + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} + engines: {node: '>=10'} - 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 + find-up@6.3.0: + resolution: {integrity: sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - viem@2.23.2: - resolution: {integrity: sha512-NVmW/E0c5crMOtbEAqMF0e3NmvQykFXhLOc/CkLIXOlzHSA6KXVz3CYVmaKqBF8/xtjsjHAGjdJN3Ru1kFJLaA==} - peerDependencies: - typescript: '>=5.0.4' - peerDependenciesMeta: - typescript: - optional: true + flat@5.0.2: + resolution: {integrity: sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==} + hasBin: true - viem@2.43.1: - resolution: {integrity: sha512-S33pBNlRvOlVv4+L94Z8ydCMDB1j0cuHFUvaC28i6OTxw3uY1P4M3h1YDFK8YC1H9/lIbeBTTvCRhi0FqU/2iw==} + follow-redirects@1.15.11: + resolution: {integrity: sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==} + engines: {node: '>=4.0'} peerDependencies: - typescript: '>=5.0.4' + debug: '*' peerDependenciesMeta: - typescript: + debug: optional: true - vite-node@3.2.4: - resolution: {integrity: sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg==} - engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} - hasBin: true + for-each@0.3.5: + resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==} + engines: {node: '>= 0.4'} - vite-plugin-wasm@3.5.0: - resolution: {integrity: sha512-X5VWgCnqiQEGb+omhlBVsvTfxikKtoOgAzQ95+BZ8gQ+VfMHIjSHr0wyvXFQCa0eKQ0fKyaL0kWcEnYqBac4lQ==} - peerDependencies: - vite: ^2 || ^3 || ^4 || ^5 || ^6 || ^7 + form-data-encoder@2.1.4: + resolution: {integrity: sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw==} + engines: {node: '>= 14.17'} - vite@5.4.21: - resolution: {integrity: sha512-o5a9xKjbtuhY6Bi5S3+HvbRERmouabWbyUcpXXUA1u+GNUKoROi9byOJ8M0nHbHYHkYICiMlqxkg1KkYmm25Sw==} - engines: {node: ^18.0.0 || >=20.0.0} - hasBin: true - peerDependencies: - '@types/node': ^18.0.0 || >=20.0.0 - less: '*' - lightningcss: ^1.21.0 - sass: '*' - sass-embedded: '*' - stylus: '*' - sugarss: '*' - terser: ^5.4.0 - peerDependenciesMeta: - '@types/node': - optional: true - less: - optional: true - lightningcss: - optional: true - sass: - optional: true - sass-embedded: - optional: true - stylus: - optional: true - sugarss: - optional: true - terser: - optional: true + form-data@2.5.5: + resolution: {integrity: sha512-jqdObeR2rxZZbPSGL+3VckHMYtu+f9//KXBsVny6JSX/pa38Fy+bGjuG8eW/H6USNQWhLi8Num++cU2yOCNz4A==} + engines: {node: '>= 0.12'} - vitest@3.2.4: - resolution: {integrity: sha512-LUCP5ev3GURDysTWiP47wRRUpLKMOfPh+yKTx3kVIEiu5KOMeqzpnYNsKyOoVrULivR8tLcks4+lga33Whn90A==} - engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} - hasBin: true + form-data@4.0.5: + resolution: {integrity: sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==} + engines: {node: '>= 6'} + + format@0.2.2: + resolution: {integrity: sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==} + engines: {node: '>=0.4.x'} + + forwarded@0.2.0: + resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} + engines: {node: '>= 0.6'} + + fp-ts@1.19.3: + resolution: {integrity: sha512-H5KQDspykdHuztLTg+ajGN0Z2qUjcEf3Ybxc6hLt0k7/zPkn29XnKnxlBPyW2XIddWrGaJBzBl4VLYOtk39yZg==} + + fraction.js@5.3.4: + resolution: {integrity: sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ==} + + framer-motion@12.23.26: + resolution: {integrity: sha512-cPcIhgR42xBn1Uj+PzOyheMtZ73H927+uWPDVhUMqxy8UHt6Okavb6xIz9J/phFUHUj0OncR6UvMfJTXoc/LKA==} peerDependencies: - '@edge-runtime/vm': '*' - '@types/debug': ^4.1.12 - '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0 - '@vitest/browser': 3.2.4 - '@vitest/ui': 3.2.4 - happy-dom: '*' - jsdom: '*' + '@emotion/is-prop-valid': '*' + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 peerDependenciesMeta: - '@edge-runtime/vm': - optional: true - '@types/debug': - optional: true - '@types/node': - optional: true - '@vitest/browser': - optional: true - '@vitest/ui': + '@emotion/is-prop-valid': optional: true - happy-dom: + react: optional: true - jsdom: + react-dom: 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 + fresh@0.5.2: + resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==} + engines: {node: '>= 0.6'} - web3-utils@1.10.4: - resolution: {integrity: sha512-tsu8FiKJLk2PzhDl9fXbGUWTkkVXYhtTA+SmEFkKft+9BgwLxfCRpU96sWv7ICC8zixBNd3JURVoiR3dUXgP8A==} - engines: {node: '>=8.0.0'} + fs-extra@10.1.0: + resolution: {integrity: sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==} + engines: {node: '>=12'} - webextension-polyfill@0.10.0: - resolution: {integrity: sha512-c5s35LgVa5tFaHhrZDnr3FpQpjj1BB+RXhLTYUxGqBVN460HkbM8TBtEqdXWbpTKfzwCcjAZVF7zXCYSKtcp9g==} + fs-extra@11.3.3: + resolution: {integrity: sha512-VWSRii4t0AFm6ixFFmLLx1t7wS1gh+ckoa84aOeapGum0h+EZd1EhEumSB+ZdDLnEPuucsVB9oB7cxJHap6Afg==} + engines: {node: '>=14.14'} - webidl-conversions@3.0.1: - resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} + fs-extra@7.0.1: + resolution: {integrity: sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==} + engines: {node: '>=6 <7 || >=8'} - whatwg-url@5.0.0: - resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} + fs-extra@8.1.0: + resolution: {integrity: sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==} + engines: {node: '>=6 <7 || >=8'} - which-module@2.0.1: - resolution: {integrity: sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==} + fs-extra@9.1.0: + resolution: {integrity: sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==} + engines: {node: '>=10'} - which-typed-array@1.1.19: - resolution: {integrity: sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==} + fs-readdir-recursive@1.1.0: + resolution: {integrity: sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA==} + + fs.realpath@1.0.0: + resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + 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'} - which@1.3.1: - resolution: {integrity: sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==} - hasBin: true + gensync@1.0.0-beta.2: + resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} + engines: {node: '>=6.9.0'} - why-is-node-running@2.3.0: - resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==} - engines: {node: '>=8'} - hasBin: true + get-caller-file@2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} - widest-line@3.1.0: - resolution: {integrity: sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==} - engines: {node: '>=8'} + get-func-name@2.0.2: + resolution: {integrity: sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==} - word-wrap@1.2.5: - resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} - engines: {node: '>=0.10.0'} + get-intrinsic@1.3.0: + resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} + engines: {node: '>= 0.4'} - wordwrap@1.0.0: - resolution: {integrity: sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==} + get-nonce@1.0.1: + resolution: {integrity: sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==} + engines: {node: '>=6'} - wordwrapjs@4.0.1: - resolution: {integrity: sha512-kKlNACbvHrkpIw6oPeYDSmdCTu2hdMHoyXLTcUKala++lx5Y+wjJ/e474Jqv5abnVmwxw08DiTuHmw69lJGksA==} - engines: {node: '>=8.0.0'} + get-own-enumerable-property-symbols@3.0.2: + resolution: {integrity: sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==} - workerpool@6.5.1: - resolution: {integrity: sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA==} + get-port@3.2.0: + resolution: {integrity: sha512-x5UJKlgeUiNT8nyo/AcnwLnZuZNcSjSw0kogRB+Whd1fjjFq4B1hySFxSFWWSn4mIBzg3sRNUDFYc4g5gjPoLg==} + engines: {node: '>=4'} - wrap-ansi@6.2.0: - resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} - engines: {node: '>=8'} + get-proto@1.0.1: + resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} + engines: {node: '>= 0.4'} - wrap-ansi@7.0.0: - resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + get-stream@6.0.1: + resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} engines: {node: '>=10'} - wrappy@1.0.2: - resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + ghost-testrpc@0.0.2: + resolution: {integrity: sha512-i08dAEgJ2g8z5buJIrCTduwPIhih3DP+hOCTyyryikfV8T0bNvHnGXO67i0DD1H4GBDETTclPy9njZbfluQYrQ==} + hasBin: true - ws@7.5.10: - resolution: {integrity: sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==} - engines: {node: '>=8.3.0'} - peerDependencies: - bufferutil: ^4.0.1 - utf-8-validate: ^5.0.2 - peerDependenciesMeta: - bufferutil: - optional: true - utf-8-validate: - optional: true + github-slugger@1.5.0: + resolution: {integrity: sha512-wIh+gKBI9Nshz2o46B0B3f5k/W+WI9ZAv6y5Dn5WJ5SK1t0TnDimB4WE5rmTD05ZAIn8HALCZVmCsvj0w0v0lw==} - ws@8.17.1: - resolution: {integrity: sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==} - 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 + glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} - 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 + glob-parent@6.0.2: + resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} + engines: {node: '>=10.13.0'} - ws@8.18.3: - resolution: {integrity: sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==} - engines: {node: '>=10.0.0'} + glob-to-regex.js@1.2.0: + resolution: {integrity: sha512-QMwlOQKU/IzqMUOAZWubUOT8Qft+Y0KQWnX9nK3ch0CJg0tTp4TvGZsTfudYKv2NzoQSyPcnA6TYeIQ3jGichQ==} + engines: {node: '>=10.0'} peerDependencies: - bufferutil: ^4.0.1 - utf-8-validate: '>=5.0.2' - peerDependenciesMeta: - bufferutil: - optional: true - utf-8-validate: - optional: true + tslib: '2' - xmlhttprequest-ssl@2.1.2: - resolution: {integrity: sha512-TEU+nJVUUnA4CYJFLvK5X9AOeH4KvDvhIfm0vV1GaQRtchnG0hgK5p8hw/xjv8cunWYCsiPCSDzObPyhEwq3KQ==} - engines: {node: '>=0.4.0'} + glob-to-regexp@0.4.1: + resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==} - xtend@4.0.2: - resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} - engines: {node: '>=0.4'} + glob@5.0.15: + resolution: {integrity: sha512-c9IPMazfRITpmAAKi22dK1VKxGDX9ehhqfABDriL/lzO92xcUKEJPQHrVA/2YHSNFB4iFlykVmWvwo48nr3OxA==} + deprecated: Glob versions prior to v9 are no longer supported - y18n@4.0.3: - resolution: {integrity: sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==} + glob@7.1.7: + resolution: {integrity: sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==} + deprecated: Glob versions prior to v9 are no longer supported - y18n@5.0.8: - resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} + glob@7.2.3: + resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + deprecated: Glob versions prior to v9 are no longer supported + + glob@8.1.0: + resolution: {integrity: sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==} + engines: {node: '>=12'} + deprecated: Glob versions prior to v9 are no longer supported + + global-dirs@3.0.1: + resolution: {integrity: sha512-NBcGGFbBA9s1VzD41QXDG+3++t9Mn5t1FpLdhESY6oKY4gYTFpX4wO3sqGUa0Srjtbfj3szX0RnemmrVRUdULA==} engines: {node: '>=10'} - yallist@3.1.1: - resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + global-modules@2.0.0: + resolution: {integrity: sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==} + engines: {node: '>=6'} - yargs-parser@18.1.3: - resolution: {integrity: sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==} + global-prefix@3.0.0: + resolution: {integrity: sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==} engines: {node: '>=6'} - yargs-parser@20.2.9: - resolution: {integrity: sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==} - engines: {node: '>=10'} + globby@10.0.2: + resolution: {integrity: sha512-7dUi7RvCoT/xast/o/dLN53oqND4yk0nsHkhRgn9w65C4PofCLOoJ39iSOg+qVDdWQPIEj+eszMHQ+aLVwwQSg==} + engines: {node: '>=8'} - yargs-unparser@2.0.0: - resolution: {integrity: sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==} + globby@11.1.0: + resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} engines: {node: '>=10'} - yargs@15.4.1: - resolution: {integrity: sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==} - engines: {node: '>=8'} + globby@13.2.2: + resolution: {integrity: sha512-Y1zNGV+pzQdh7H39l9zgB4PJqjRNqydvdYCDG4HFXM4XuvSaQQlEc91IU1yALL8gUTDomgBAfz3XJdmUS+oo0w==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - yargs@16.2.0: - resolution: {integrity: sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==} - engines: {node: '>=10'} + gopd@1.2.0: + resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} + engines: {node: '>= 0.4'} - yn@3.1.1: - resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==} - engines: {node: '>=6'} + got@12.6.1: + resolution: {integrity: sha512-mThBblvlAF1d4O5oqyvN+ZxLAYwIJK7bpMxgYqPD9okW0C3qm5FFn7k811QrcuEBwaogR3ngOFoCfs6mRv7teQ==} + engines: {node: '>=14.16'} - yocto-queue@0.1.0: - resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + graceful-fs@4.2.10: + resolution: {integrity: sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==} + + graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + + gray-matter@4.0.3: + resolution: {integrity: sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==} + engines: {node: '>=6.0'} + + gzip-size@6.0.0: + resolution: {integrity: sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==} engines: {node: '>=10'} - zod@3.22.4: - resolution: {integrity: sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==} + h3@1.15.4: + resolution: {integrity: sha512-z5cFQWDffyOe4vQ9xIqNfCZdV4p//vy6fBnr8Q1AWnVZ0teurKMG66rLj++TKwKPUP3u7iMUvrvKaEUiQw2QWQ==} - zod@3.25.76: - resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==} + handle-thing@2.0.1: + resolution: {integrity: sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==} - zod@4.2.1: - resolution: {integrity: sha512-0wZ1IRqGGhMP76gLqz8EyfBXKk0J2qo2+H3fi4mcUP/KtTocoX08nmIAHl1Z2kJIZbZee8KOpBCSNPRgauucjw==} + handlebars@4.7.8: + resolution: {integrity: sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==} + engines: {node: '>=0.4.7'} + hasBin: true - zustand@5.0.0: - resolution: {integrity: sha512-LE+VcmbartOPM+auOjCCLQOsQ05zUTp8RkgwRzefUk+2jISdMMFnxvyTjA4YNWr5ZGXYbVsEMZosttuxUBkojQ==} - engines: {node: '>=12.20.0'} + hardhat-dependency-compiler@1.2.1: + resolution: {integrity: sha512-xG5iwbspTtxOEiP5UsPngEYQ1Hg+fjTjliapIjdTQmwGkCPofrsDhQDV2O/dopcYzcR68nTx2X8xTewYHgA2rQ==} + engines: {node: '>=14.14.0'} peerDependencies: - '@types/react': '>=18.0.0' - immer: '>=9.0.6' - react: '>=18.0.0' - use-sync-external-store: '>=1.2.0' + hardhat: ^2.0.0 + + hardhat-gas-reporter@1.0.10: + resolution: {integrity: sha512-02N4+So/fZrzJ88ci54GqwVA3Zrf0C9duuTyGt0CFRIh/CdNwbnTgkXkRfojOMLBQ+6t+lBIkgbsOtqMvNwikA==} + peerDependencies: + hardhat: ^2.0.2 + + hardhat@2.28.0: + resolution: {integrity: sha512-A3yBISI18EcnY2IR7Ny2xZF33Q3qH01yrWapeWbyGOiJm/386SasWjbHRHYgUlZ3YWJETIMh7wYfMUaXrofTDQ==} + hasBin: true + peerDependencies: + ts-node: '*' + typescript: '*' peerDependenciesMeta: - '@types/react': - optional: true - immer: - optional: true - react: + ts-node: optional: true - use-sync-external-store: + typescript: optional: true - zustand@5.0.3: - resolution: {integrity: sha512-14fwWQtU3pH4dE0dOpdMiWjddcH+QzKIgk1cl8epwSE7yag43k/AD/m4L6+K7DytAOr9gGBe3/EXj9g7cdostg==} - engines: {node: '>=12.20.0'} + has-flag@1.0.0: + resolution: {integrity: sha512-DyYHfIYwAJmjAjSSPKANxI8bFY9YtFrgkAfinBojQ8YJTOuOuav64tMUJv584SES4xl74PmuaevIyaLESHdTAA==} + engines: {node: '>=0.10.0'} + + 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'} + + has-yarn@3.0.0: + resolution: {integrity: sha512-IrsVwUHhEULx3R8f/aA8AHuEzAorplsab/v8HBzEiIukwq5i/EC+xmOW+HfP1OaDP+2JkgT1yILHN2O3UFIbcA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + hash-base@3.1.2: + resolution: {integrity: sha512-Bb33KbowVTIj5s7Ked1OsqHUeCpz//tPwR+E2zJgJKo9Z5XolZ9b6bdUgjmYlwnWhoOQKoTd1TYToZGn5mAYOg==} + engines: {node: '>= 0.8'} + + hash.js@1.1.7: + resolution: {integrity: sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==} + + hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} + + hast-util-from-parse5@8.0.3: + resolution: {integrity: sha512-3kxEVkEKt0zvcZ3hCRYI8rqrgwtlIOFMWkbclACvjlDw8Li9S2hk/d51OI0nr/gIpdMHNepwgOKqZ/sy0Clpyg==} + + hast-util-parse-selector@4.0.0: + resolution: {integrity: sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==} + + hast-util-raw@9.1.0: + resolution: {integrity: sha512-Y8/SBAHkZGoNkpzqqfCldijcuUKh7/su31kEBp67cFY09Wy0mTRgtsLYsiIxMJxlu0f6AA5SUTbDR8K0rxnbUw==} + + hast-util-to-estree@3.1.3: + resolution: {integrity: sha512-48+B/rJWAp0jamNbAAf9M7Uf//UVqAoMmgXhBdxTDJLGKY+LRnZ99qcG+Qjl5HfMpYNzS5v4EAwVEF34LeAj7w==} + + hast-util-to-jsx-runtime@2.3.6: + resolution: {integrity: sha512-zl6s8LwNyo1P9uw+XJGvZtdFF1GdAkOg8ujOw+4Pyb76874fLps4ueHXDhXWdk6YHQ6OgUtinliG7RsYvCbbBg==} + + hast-util-to-parse5@8.0.1: + resolution: {integrity: sha512-MlWT6Pjt4CG9lFCjiz4BH7l9wmrMkfkJYCxFwKQic8+RTZgWPuWxwAfjJElsXkex7DJjfSJsQIt931ilUgmwdA==} + + hast-util-whitespace@3.0.0: + resolution: {integrity: sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==} + + hastscript@9.0.1: + resolution: {integrity: sha512-g7df9rMFX/SPi34tyGCyUBREQoKkapwdY/T04Qn9TDWfHhAYt4/I0gMVirzK5wEzeUqIjEB+LXC/ypb7Aqno5w==} + + he@1.2.0: + resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==} + hasBin: true + + heap@0.2.7: + resolution: {integrity: sha512-2bsegYkkHO+h/9MGbn6KWcE45cHZgPANo5LXF7EvWdT0yT2EguSVO1nDgU5c8+ZOPwp2vMNa7YFsJhVcDR9Sdg==} + + history@4.10.1: + resolution: {integrity: sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==} + + hmac-drbg@1.0.1: + resolution: {integrity: sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==} + + hoist-non-react-statics@3.3.2: + resolution: {integrity: sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==} + + hono@4.11.1: + resolution: {integrity: sha512-KsFcH0xxHes0J4zaQgWbYwmz3UPOOskdqZmItstUG93+Wk1ePBLkLGwbP9zlmh1BFUiL8Qp+Xfu9P7feJWpGNg==} + engines: {node: '>=16.9.0'} + + hpack.js@2.1.6: + resolution: {integrity: sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==} + + html-escaper@2.0.2: + resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} + + html-minifier-terser@6.1.0: + resolution: {integrity: sha512-YXxSlJBZTP7RS3tWnQw74ooKa6L9b9i9QYXY21eUEvhZ3u9XLfv6OnFsQq6RxkhHygsaUMvYsZRV5rU/OVNZxw==} + engines: {node: '>=12'} + hasBin: true + + html-minifier-terser@7.2.0: + resolution: {integrity: sha512-tXgn3QfqPIpGl9o+K5tpcj3/MN4SfLtsx2GWwBC3SSd0tXQGyF3gsSqad8loJgKZGM3ZxbYDd5yhiBIdWpmvLA==} + engines: {node: ^14.13.1 || >=16.0.0} + hasBin: true + + html-tags@3.3.1: + resolution: {integrity: sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==} + engines: {node: '>=8'} + + html-void-elements@3.0.0: + resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==} + + html-webpack-plugin@5.6.6: + resolution: {integrity: sha512-bLjW01UTrvoWTJQL5LsMRo1SypHW80FTm12OJRSnr3v6YHNhfe+1r0MYUZJMACxnCHURVnBWRwAsWs2yPU9Ezw==} + engines: {node: '>=10.13.0'} peerDependencies: - '@types/react': '>=18.0.0' - immer: '>=9.0.6' - react: '>=18.0.0' - use-sync-external-store: '>=1.2.0' + '@rspack/core': 0.x || 1.x + webpack: ^5.20.0 peerDependenciesMeta: - '@types/react': - optional: true - immer: + '@rspack/core': optional: true - react: - optional: true - use-sync-external-store: + webpack: optional: true - zustand@5.0.9: - resolution: {integrity: sha512-ALBtUj0AfjJt3uNRQoL1tL2tMvj6Gp/6e39dnfT6uzpelGru8v1tPOGBzayOWbPJvujM8JojDk3E1LxeFisBNg==} - engines: {node: '>=12.20.0'} + htmlparser2@6.1.0: + resolution: {integrity: sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==} + + htmlparser2@8.0.2: + resolution: {integrity: sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==} + + http-basic@8.1.3: + resolution: {integrity: sha512-/EcDMwJZh3mABI2NhGfHOGOeOZITqfkEO4p/xK+l3NpyncIHUQBoMvCSF/b5GqvKtySC2srL/GGG3+EtlqlmCw==} + engines: {node: '>=6.0.0'} + + http-cache-semantics@4.2.0: + resolution: {integrity: sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==} + + http-deceiver@1.2.7: + resolution: {integrity: sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==} + + http-errors@1.6.3: + resolution: {integrity: sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==} + engines: {node: '>= 0.6'} + + http-errors@2.0.1: + resolution: {integrity: sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==} + engines: {node: '>= 0.8'} + + http-parser-js@0.5.10: + resolution: {integrity: sha512-Pysuw9XpUq5dVc/2SMHpuTY01RFl8fttgcyunjL7eEMhGM3cI4eOmiCycJDVCo/7O7ClfQD3SaI6ftDzqOXYMA==} + + http-proxy-middleware@2.0.9: + resolution: {integrity: sha512-c1IyJYLYppU574+YI7R4QyX2ystMtVXZwIdzazUIPIJsHuWNd+mho2j+bKoHftndicGj9yh+xjd+l0yj7VeT1Q==} + engines: {node: '>=12.0.0'} peerDependencies: - '@types/react': '>=18.0.0' - immer: '>=9.0.6' - react: '>=18.0.0' - use-sync-external-store: '>=1.2.0' + '@types/express': ^4.17.13 peerDependenciesMeta: - '@types/react': - optional: true - immer: - optional: true - react: - optional: true - use-sync-external-store: + '@types/express': optional: true -snapshots: + http-proxy@1.18.1: + resolution: {integrity: sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==} + engines: {node: '>=8.0.0'} - '@account-abstraction/contracts@0.8.0': - dependencies: - '@openzeppelin/contracts': 5.4.0 - '@uniswap/v3-periphery': 1.4.4 + http-response-object@3.0.2: + resolution: {integrity: sha512-bqX0XTF6fnXSQcEJ2Iuyr75yVakyjIDCqroJQ/aHfSdlM743Cwqoi2nDYMzLGWUcuTWGWy8AAvOKXTfiv6q9RA==} - '@adraffy/ens-normalize@1.10.1': {} + http2-wrapper@2.2.1: + resolution: {integrity: sha512-V5nVw1PAOgfI3Lmeaj2Exmeg7fenjhRUgz1lPSezy1CuhPYbgQtbQj4jZfEAEMlaL+vupsvhjqCyjzob0yxsmQ==} + engines: {node: '>=10.19.0'} - '@adraffy/ens-normalize@1.11.1': {} + https-proxy-agent@5.0.1: + resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} + engines: {node: '>= 6'} - '@alloc/quick-lru@5.2.0': {} + human-signals@2.1.0: + resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} + engines: {node: '>=10.17.0'} - '@aws-crypto/crc32@5.2.0': - dependencies: - '@aws-crypto/util': 5.2.0 - '@aws-sdk/types': 3.953.0 - tslib: 2.8.1 + humanize-ms@1.2.1: + resolution: {integrity: sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==} - '@aws-crypto/sha256-browser@5.2.0': - dependencies: - '@aws-crypto/sha256-js': 5.2.0 - '@aws-crypto/supports-web-crypto': 5.2.0 - '@aws-crypto/util': 5.2.0 - '@aws-sdk/types': 3.953.0 - '@aws-sdk/util-locate-window': 3.953.0 - '@smithy/util-utf8': 2.3.0 - tslib: 2.8.1 + hyperdyperid@1.2.0: + resolution: {integrity: sha512-Y93lCzHYgGWdrJ66yIktxiaGULYc6oGiABxhcO5AufBeOyoIdZF7bIfLaOrbM0iGIOXQQgxxRrFEnb+Y6w1n4A==} + engines: {node: '>=10.18'} - '@aws-crypto/sha256-js@1.2.2': - dependencies: - '@aws-crypto/util': 1.2.2 - '@aws-sdk/types': 3.953.0 - tslib: 1.14.1 + iconv-lite@0.4.24: + resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} + engines: {node: '>=0.10.0'} - '@aws-crypto/sha256-js@5.2.0': - dependencies: - '@aws-crypto/util': 5.2.0 - '@aws-sdk/types': 3.953.0 - tslib: 2.8.1 + icss-utils@5.1.0: + resolution: {integrity: sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==} + engines: {node: ^10 || ^12 || >= 14} + peerDependencies: + postcss: ^8.1.0 - '@aws-crypto/supports-web-crypto@5.2.0': - dependencies: - tslib: 2.8.1 + idb-keyval@6.2.1: + resolution: {integrity: sha512-8Sb3veuYCyrZL+VBt9LJfZjLUPWVvqn8tG28VqYNFCo43KHcKuq+b4EiXGeuaLAQWL2YmyDgMp2aSpH9JHsEQg==} - '@aws-crypto/util@1.2.2': - dependencies: - '@aws-sdk/types': 3.953.0 - '@aws-sdk/util-utf8-browser': 3.259.0 - tslib: 1.14.1 + idb-keyval@6.2.2: + resolution: {integrity: sha512-yjD9nARJ/jb1g+CvD0tlhUHOrJ9Sy0P8T9MF3YaLlHnSRpwPfpTX0XIvpmw3gAJUmEu3FiICLBDPXVwyEvrleg==} - '@aws-crypto/util@5.2.0': - dependencies: - '@aws-sdk/types': 3.953.0 - '@smithy/util-utf8': 2.3.0 - tslib: 2.8.1 + ieee754@1.2.1: + resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} - '@aws-sdk/client-lambda@3.954.0': - dependencies: - '@aws-crypto/sha256-browser': 5.2.0 - '@aws-crypto/sha256-js': 5.2.0 - '@aws-sdk/core': 3.954.0 - '@aws-sdk/credential-provider-node': 3.954.0 - '@aws-sdk/middleware-host-header': 3.953.0 - '@aws-sdk/middleware-logger': 3.953.0 - '@aws-sdk/middleware-recursion-detection': 3.953.0 - '@aws-sdk/middleware-user-agent': 3.954.0 - '@aws-sdk/region-config-resolver': 3.953.0 + ignore@5.3.2: + resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} + engines: {node: '>= 4'} + + image-size@2.0.2: + resolution: {integrity: sha512-IRqXKlaXwgSMAMtpNzZa1ZAe8m+Sa1770Dhk8VkSsP9LS+iHD62Zd8FQKs8fbPiagBE7BzoFX23cxFnwshpV6w==} + engines: {node: '>=16.x'} + hasBin: true + + immer@10.0.2: + resolution: {integrity: sha512-Rx3CqeqQ19sxUtYV9CU911Vhy8/721wRFnJv3REVGWUmoAcIwzifTsdmJte/MV+0/XpM35LZdQMBGkRIoLPwQA==} + + immutable@4.3.7: + resolution: {integrity: sha512-1hqclzwYwjRDFLjcFxOM5AYkkG0rpFPpr1RLPMEuGczoS7YA8gLhy8SWXYRAA/XwfEHpfo3cw5JGioS32fnMRw==} + + import-fresh@3.3.1: + resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} + engines: {node: '>=6'} + + import-lazy@4.0.0: + resolution: {integrity: sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==} + engines: {node: '>=8'} + + imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + + indent-string@4.0.0: + resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} + engines: {node: '>=8'} + + infima@0.2.0-alpha.45: + resolution: {integrity: sha512-uyH0zfr1erU1OohLk0fT4Rrb94AOhguWNOcD9uGrSpRvNB+6gZXUoJX5J0NtvzBO10YZ9PgvA4NFgt+fYg8ojw==} + engines: {node: '>=12'} + + inflight@1.0.6: + resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. + + inherits@2.0.3: + resolution: {integrity: sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==} + + inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + + ini@1.3.8: + resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} + + ini@2.0.0: + resolution: {integrity: sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==} + engines: {node: '>=10'} + + inline-style-parser@0.2.7: + resolution: {integrity: sha512-Nb2ctOyNR8DqQoR0OwRG95uNWIC0C1lCgf5Naz5H6Ji72KZ8OcFZLz2P5sNgwlyoJ8Yif11oMuYs5pBQa86csA==} + + interpret@1.4.0: + resolution: {integrity: sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==} + engines: {node: '>= 0.10'} + + invariant@2.2.4: + resolution: {integrity: sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==} + + io-ts@1.10.4: + resolution: {integrity: sha512-b23PteSnYXSONJ6JQXRAlvJhuw8KOtkqa87W4wDtvMrud/DTJd5X+NpOOI+O/zZwVq6v0VLAaJ+1EDViKEuN9g==} + + ipaddr.js@1.9.1: + resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} + engines: {node: '>= 0.10'} + + ipaddr.js@2.3.0: + resolution: {integrity: sha512-Zv/pA+ciVFbCSBBjGfaKUya/CcGmUHzTydLMaTwrUUEM2DIEO3iZvueGxmacvmN50fGpGVKeTXpb2LcYQxeVdg==} + engines: {node: '>= 10'} + + iron-webcrypto@1.2.1: + resolution: {integrity: sha512-feOM6FaSr6rEABp/eDfVseKyTMDt+KGpeB35SkVn9Tyn0CqvVsY3EwI0v5i8nMHyJnzCIQf7nsy3p41TPkJZhg==} + + is-alphabetical@2.0.1: + resolution: {integrity: sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==} + + is-alphanumerical@2.0.1: + resolution: {integrity: sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==} + + is-arguments@1.2.0: + resolution: {integrity: sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA==} + engines: {node: '>= 0.4'} + + is-arrayish@0.2.1: + resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} + + is-binary-path@2.1.0: + resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} + engines: {node: '>=8'} + + 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-ci@3.0.1: + resolution: {integrity: sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==} + hasBin: true + + is-core-module@2.16.1: + resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==} + engines: {node: '>= 0.4'} + + is-decimal@2.0.1: + resolution: {integrity: sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==} + + is-docker@2.2.1: + resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==} + engines: {node: '>=8'} + hasBin: true + + is-docker@3.0.0: + resolution: {integrity: sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + hasBin: true + + is-extendable@0.1.1: + resolution: {integrity: sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==} + engines: {node: '>=0.10.0'} + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + is-fullwidth-code-point@2.0.0: + resolution: {integrity: sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==} + engines: {node: '>=4'} + + is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + + is-generator-function@1.1.2: + resolution: {integrity: sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==} + engines: {node: '>= 0.4'} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + + is-hex-prefixed@1.0.0: + resolution: {integrity: sha512-WvtOiug1VFrE9v1Cydwm+FnXd3+w9GaeVUss5W4v/SLy3UW00vP+6iNF2SdnfiBoLy4bTqVdkftNGTUeOFVsbA==} + engines: {node: '>=6.5.0', npm: '>=3'} + + is-hexadecimal@2.0.1: + resolution: {integrity: sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==} + + is-inside-container@1.0.0: + resolution: {integrity: sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==} + engines: {node: '>=14.16'} + hasBin: true + + is-installed-globally@0.4.0: + resolution: {integrity: sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==} + engines: {node: '>=10'} + + is-network-error@1.3.0: + resolution: {integrity: sha512-6oIwpsgRfnDiyEDLMay/GqCl3HoAtH5+RUKW29gYkL0QA+ipzpDLA16yQs7/RHCSu+BwgbJaOUqa4A99qNVQVw==} + engines: {node: '>=16'} + + is-npm@6.1.0: + resolution: {integrity: sha512-O2z4/kNgyjhQwVR1Wpkbfc19JIhggF97NZNCpWTnjH7kVcZMUrnut9XSN7txI7VdyIYk5ZatOq3zvSuWpU8hoA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + + is-obj@1.0.1: + resolution: {integrity: sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==} + engines: {node: '>=0.10.0'} + + is-obj@2.0.0: + resolution: {integrity: sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==} + engines: {node: '>=8'} + + is-path-inside@3.0.3: + resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} + engines: {node: '>=8'} + + is-plain-obj@2.1.0: + resolution: {integrity: sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==} + engines: {node: '>=8'} + + is-plain-obj@3.0.0: + resolution: {integrity: sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==} + engines: {node: '>=10'} + + is-plain-obj@4.1.0: + resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==} + engines: {node: '>=12'} + + is-plain-object@2.0.4: + resolution: {integrity: sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==} + engines: {node: '>=0.10.0'} + + is-regex@1.2.1: + resolution: {integrity: sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==} + engines: {node: '>= 0.4'} + + is-regexp@1.0.0: + resolution: {integrity: sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==} + engines: {node: '>=0.10.0'} + + 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-typed-array@1.1.15: + resolution: {integrity: sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==} + engines: {node: '>= 0.4'} + + is-typedarray@1.0.0: + resolution: {integrity: sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==} + + is-unicode-supported@0.1.0: + resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} + engines: {node: '>=10'} + + is-wsl@2.2.0: + resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==} + engines: {node: '>=8'} + + is-wsl@3.1.0: + resolution: {integrity: sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==} + engines: {node: '>=16'} + + is-yarn-global@0.4.1: + resolution: {integrity: sha512-/kppl+R+LO5VmhYSEWARUFjodS25D68gvj8W7z0I7OWhUla5xWu8KL6CtB2V0R6yqhnRgbcaREMr4EEM6htLPQ==} + engines: {node: '>=12'} + + isarray@0.0.1: + resolution: {integrity: sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==} + + 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==} + + isobject@3.0.1: + resolution: {integrity: sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==} + engines: {node: '>=0.10.0'} + + isomorphic-unfetch@3.1.0: + resolution: {integrity: sha512-geDJjpoZ8N0kWexiwkX8F9NkTsXhetLPVbZFQ+JTW239QNOwvB0gniuR1Wc6f0AMTn7/mFGyXvHTifrCp/GH8Q==} + + isomorphic-ws@4.0.1: + resolution: {integrity: sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w==} + 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: + ws: '*' + + jayson@4.2.0: + resolution: {integrity: sha512-VfJ9t1YLwacIubLhONk0KFeosUBwstRWQ0IRT1KDjEjnVnSOVHC3uwugyV7L0c7R9lpVyrUGT2XWiBA1UTtpyg==} + engines: {node: '>=8'} + hasBin: true + + jest-util@29.7.0: + resolution: {integrity: sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-worker@27.5.1: + resolution: {integrity: sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==} + engines: {node: '>= 10.13.0'} + + jest-worker@29.7.0: + resolution: {integrity: sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jiti@1.21.7: + resolution: {integrity: sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==} + hasBin: true + + joi@17.13.3: + resolution: {integrity: sha512-otDA4ldcIx+ZXsKHWmp0YizCweVRZG96J10b0FevjfuncLO1oX59THoAmHkNubYJ+9gWsYsp5k8v4ib6oDv1fA==} + + jose@6.1.3: + resolution: {integrity: sha512-0TpaTfihd4QMNwrz/ob2Bp7X04yuxJkjRGi4aKmOqwhov54i6u79oCv7T+C7lo70MKH6BesI3vscD1yb/yzKXQ==} + + js-cookie@2.2.1: + resolution: {integrity: sha512-HvdH2LzI/EAZcUwA8+0nKNtWHqS+ZmijLA30RwZA0bo7ToCckjK5MkGhjED9KoRcXO6BaGI3I9UIzSA1FKFPOQ==} + + js-sha3@0.8.0: + resolution: {integrity: sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==} + + js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + + js-tokens@9.0.1: + resolution: {integrity: sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==} + + js-yaml@3.14.2: + resolution: {integrity: sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==} + hasBin: true + + js-yaml@4.1.1: + resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==} + hasBin: true + + jsesc@3.1.0: + resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} + engines: {node: '>=6'} + hasBin: true + + json-buffer@3.0.1: + resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + + json-parse-even-better-errors@2.3.1: + resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} + + json-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==} + + json-schema-traverse@1.0.0: + resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} + + json-stream-stringify@3.1.6: + resolution: {integrity: sha512-x7fpwxOkbhFCaJDJ8vb1fBY3DdSa4AlITaz+HHILQJzdPMnHEFjxPwVUi1ALIbcIxDE0PNe/0i7frnY8QnBQog==} + engines: {node: '>=7.10.1'} + + json-stringify-safe@5.0.1: + resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==} + + json5@2.2.3: + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} + engines: {node: '>=6'} + hasBin: true + + jsonfile@4.0.0: + resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} + + jsonfile@6.2.0: + resolution: {integrity: sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==} + + jsonschema@1.5.0: + resolution: {integrity: sha512-K+A9hhqbn0f3pJX17Q/7H6yQfD/5OXgdrR5UE12gMXCiN9D5Xq2o5mddV2QEcX/bjla99ASsAAQUyMCCRWAEhw==} + + 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==} + + kind-of@6.0.3: + resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} + engines: {node: '>=0.10.0'} + + kleur@3.0.3: + resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} + engines: {node: '>=6'} + + latest-version@7.0.0: + resolution: {integrity: sha512-KvNT4XqAMzdcL6ka6Tl3i2lYeFDgXNCuIX+xNx6ZMVR1dFq+idXd9FLKNMOIx0t9mJ9/HudyX4oZWXZQ0UJHeg==} + engines: {node: '>=14.16'} + + launch-editor@2.12.0: + resolution: {integrity: sha512-giOHXoOtifjdHqUamwKq6c49GzBdLjvxrd2D+Q4V6uOHopJv7p9VJxikDsQ/CBXZbEITgUqSVHXLTG3VhPP1Dg==} + + leven@3.1.0: + resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==} + engines: {node: '>=6'} + + levn@0.3.0: + resolution: {integrity: sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==} + engines: {node: '>= 0.8.0'} + + lilconfig@3.1.3: + resolution: {integrity: sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==} + engines: {node: '>=14'} + + lines-and-columns@1.2.4: + resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + + lit-element@4.2.1: + resolution: {integrity: sha512-WGAWRGzirAgyphK2urmYOV72tlvnxw7YfyLDgQ+OZnM9vQQBQnumQ7jUJe6unEzwGU3ahFOjuz1iz1jjrpCPuw==} + + lit-html@3.3.1: + resolution: {integrity: sha512-S9hbyDu/vs1qNrithiNyeyv64c9yqiW9l+DBgI18fL+MTvOtWoFR0FWiyq1TxaYef5wNlpEmzlXoBlZEO+WjoA==} + + lit@3.3.0: + resolution: {integrity: sha512-DGVsqsOIHBww2DqnuZzW7QsuCdahp50ojuDaBPC7jUDRpYoH0z7kHBBYZewRzer75FwtrkmkKk7iOAwSaWdBmw==} + + loader-runner@4.3.1: + resolution: {integrity: sha512-IWqP2SCPhyVFTBtRcgMHdzlf9ul25NwaFx4wCEH/KjAXuuHY4yNjvPXsBokp8jCB936PyWRaPKUNh8NvylLp2Q==} + engines: {node: '>=6.11.5'} + + loader-utils@2.0.4: + resolution: {integrity: sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==} + engines: {node: '>=8.9.0'} + + 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'} + + locate-path@7.2.0: + resolution: {integrity: sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + lodash.camelcase@4.3.0: + resolution: {integrity: sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==} + + lodash.clonedeep@4.5.0: + resolution: {integrity: sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==} + + lodash.debounce@4.0.8: + resolution: {integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==} + + lodash.isequal@4.5.0: + resolution: {integrity: sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==} + deprecated: This package is deprecated. Use require('node:util').isDeepStrictEqual instead. + + lodash.memoize@4.1.2: + resolution: {integrity: sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==} + + lodash.truncate@4.4.2: + resolution: {integrity: sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==} + + lodash.uniq@4.5.0: + resolution: {integrity: sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==} + + lodash@4.17.21: + resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + + log-symbols@4.1.0: + resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} + engines: {node: '>=10'} + + longest-streak@3.1.0: + resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==} + + loose-envify@1.4.0: + resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} + hasBin: true + + loupe@2.3.7: + resolution: {integrity: sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==} + + loupe@3.2.1: + resolution: {integrity: sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==} + + lower-case@2.0.2: + resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==} + + lowercase-keys@3.0.0: + resolution: {integrity: sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + lru-cache@10.4.3: + resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} + + lru-cache@5.1.1: + resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + + lru_map@0.3.3: + resolution: {integrity: sha512-Pn9cox5CsMYngeDbmChANltQl+5pi6XmTrraMSzhPmMBbmgcxmqWry0U3PGapCU1yB4/LqCcom7qhHZiF/jGfQ==} + + lucide-react@0.525.0: + resolution: {integrity: sha512-Tm1txJ2OkymCGkvwoHt33Y2JpN5xucVq1slHcgE6Lk0WjDfjgKWor5CdVER8U6DvcfMwh4M8XxmpTiyzfmfDYQ==} + peerDependencies: + react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0 + + magic-string@0.30.21: + resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} + + make-error@1.3.6: + resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} + + markdown-extensions@2.0.0: + resolution: {integrity: sha512-o5vL7aDWatOTX8LzaS1WMoaoxIiLRQJuIKKe2wAw6IeULDHaqbiqiggmx+pKvZDb1Sj+pE46Sn1T7lCqfFtg1Q==} + engines: {node: '>=16'} + + markdown-table@1.1.3: + resolution: {integrity: sha512-1RUZVgQlpJSPWYbFSpmudq5nHY1doEIv89gBtF0s4gW1GF2XorxcA/70M5vq7rLv0a6mhOUccRsqkwhwLCIQ2Q==} + + markdown-table@2.0.0: + resolution: {integrity: sha512-Ezda85ToJUBhM6WGaG6veasyym+Tbs3cMAw/ZhOPqXiYsr0jgocBV3j3nx+4lk47plLlIqjwuTm/ywVI+zjJ/A==} + + markdown-table@3.0.4: + resolution: {integrity: sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==} + + math-intrinsics@1.1.0: + resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} + engines: {node: '>= 0.4'} + + md5.js@1.3.5: + resolution: {integrity: sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==} + + md5@2.3.0: + resolution: {integrity: sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g==} + + mdast-util-directive@3.1.0: + resolution: {integrity: sha512-I3fNFt+DHmpWCYAT7quoM6lHf9wuqtI+oCOfvILnoicNIqjh5E3dEJWiXuYME2gNe8vl1iMQwyUHa7bgFmak6Q==} + + mdast-util-find-and-replace@3.0.2: + resolution: {integrity: sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==} + + mdast-util-from-markdown@2.0.2: + resolution: {integrity: sha512-uZhTV/8NBuw0WHkPTrCqDOl0zVe1BIng5ZtHoDk49ME1qqcjYmmLmOf0gELgcRMxN4w2iuIeVso5/6QymSrgmA==} + + mdast-util-frontmatter@2.0.1: + resolution: {integrity: sha512-LRqI9+wdgC25P0URIJY9vwocIzCcksduHQ9OF2joxQoyTNVduwLAFUzjoopuRJbJAReaKrNQKAZKL3uCMugWJA==} + + mdast-util-gfm-autolink-literal@2.0.1: + resolution: {integrity: sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==} + + mdast-util-gfm-footnote@2.1.0: + resolution: {integrity: sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ==} + + mdast-util-gfm-strikethrough@2.0.0: + resolution: {integrity: sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==} + + mdast-util-gfm-table@2.0.0: + resolution: {integrity: sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==} + + mdast-util-gfm-task-list-item@2.0.0: + resolution: {integrity: sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==} + + mdast-util-gfm@3.1.0: + resolution: {integrity: sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==} + + mdast-util-mdx-expression@2.0.1: + resolution: {integrity: sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ==} + + mdast-util-mdx-jsx@3.2.0: + resolution: {integrity: sha512-lj/z8v0r6ZtsN/cGNNtemmmfoLAFZnjMbNyLzBafjzikOM+glrjNHPlf6lQDOTccj9n5b0PPihEBbhneMyGs1Q==} + + mdast-util-mdx@3.0.0: + resolution: {integrity: sha512-JfbYLAW7XnYTTbUsmpu0kdBUVe+yKVJZBItEjwyYJiDJuZ9w4eeaqks4HQO+R7objWgS2ymV60GYpI14Ug554w==} + + mdast-util-mdxjs-esm@2.0.1: + resolution: {integrity: sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==} + + mdast-util-phrasing@4.1.0: + resolution: {integrity: sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==} + + mdast-util-to-hast@13.2.1: + resolution: {integrity: sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA==} + + mdast-util-to-markdown@2.1.2: + resolution: {integrity: sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==} + + mdast-util-to-string@4.0.0: + resolution: {integrity: sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==} + + mdn-data@2.0.28: + resolution: {integrity: sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==} + + mdn-data@2.0.30: + resolution: {integrity: sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==} + + media-query-parser@2.0.2: + resolution: {integrity: sha512-1N4qp+jE0pL5Xv4uEcwVUhIkwdUO3S/9gML90nqKA7v7FcOS5vUtatfzok9S9U1EJU8dHWlcv95WLnKmmxZI9w==} + + media-typer@0.3.0: + resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==} + engines: {node: '>= 0.6'} + + memfs@4.56.4: + resolution: {integrity: sha512-GKqmHEFyFwccco9NmTEY38AemzpNLs5tKKxGfNpnLI/5D92NAr7STItdzTMeUlKdd3FjkE5w18TPLyKTb6MDVA==} + peerDependencies: + tslib: '2' + + memorystream@0.3.1: + resolution: {integrity: sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==} + engines: {node: '>= 0.10.0'} + + merge-descriptors@1.0.3: + resolution: {integrity: sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==} + + merge-stream@2.0.0: + resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} + + merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + + methods@1.1.2: + resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==} + engines: {node: '>= 0.6'} + + micro-eth-signer@0.14.0: + resolution: {integrity: sha512-5PLLzHiVYPWClEvZIXXFu5yutzpadb73rnQCpUqIHu3No3coFuWQNfE5tkBQJ7djuLYl6aRLaS0MgWJYGoqiBw==} + + micro-ftch@0.3.1: + resolution: {integrity: sha512-/0LLxhzP0tfiR5hcQebtudP56gUurs2CLkGarnCiB/OqEyUFQ6U3paQi/tgLv0hBJYt2rnr9MNpxz4fiiugstg==} + + micro-packed@0.7.3: + resolution: {integrity: sha512-2Milxs+WNC00TRlem41oRswvw31146GiSaoCT7s3Xi2gMUglW5QBeqlQaZeHr5tJx9nm3i57LNXPqxOOaWtTYg==} + + micromark-core-commonmark@2.0.3: + resolution: {integrity: sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==} + + micromark-extension-directive@3.0.2: + resolution: {integrity: sha512-wjcXHgk+PPdmvR58Le9d7zQYWy+vKEU9Se44p2CrCDPiLr2FMyiT4Fyb5UFKFC66wGB3kPlgD7q3TnoqPS7SZA==} + + micromark-extension-frontmatter@2.0.0: + resolution: {integrity: sha512-C4AkuM3dA58cgZha7zVnuVxBhDsbttIMiytjgsM2XbHAB2faRVaHRle40558FBN+DJcrLNCoqG5mlrpdU4cRtg==} + + micromark-extension-gfm-autolink-literal@2.1.0: + resolution: {integrity: sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==} + + micromark-extension-gfm-footnote@2.1.0: + resolution: {integrity: sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==} + + micromark-extension-gfm-strikethrough@2.1.0: + resolution: {integrity: sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==} + + micromark-extension-gfm-table@2.1.1: + resolution: {integrity: sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==} + + micromark-extension-gfm-tagfilter@2.0.0: + resolution: {integrity: sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==} + + micromark-extension-gfm-task-list-item@2.1.0: + resolution: {integrity: sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==} + + micromark-extension-gfm@3.0.0: + resolution: {integrity: sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==} + + micromark-extension-mdx-expression@3.0.1: + resolution: {integrity: sha512-dD/ADLJ1AeMvSAKBwO22zG22N4ybhe7kFIZ3LsDI0GlsNr2A3KYxb0LdC1u5rj4Nw+CHKY0RVdnHX8vj8ejm4Q==} + + micromark-extension-mdx-jsx@3.0.2: + resolution: {integrity: sha512-e5+q1DjMh62LZAJOnDraSSbDMvGJ8x3cbjygy2qFEi7HCeUT4BDKCvMozPozcD6WmOt6sVvYDNBKhFSz3kjOVQ==} + + micromark-extension-mdx-md@2.0.0: + resolution: {integrity: sha512-EpAiszsB3blw4Rpba7xTOUptcFeBFi+6PY8VnJ2hhimH+vCQDirWgsMpz7w1XcZE7LVrSAUGb9VJpG9ghlYvYQ==} + + micromark-extension-mdxjs-esm@3.0.0: + resolution: {integrity: sha512-DJFl4ZqkErRpq/dAPyeWp15tGrcrrJho1hKK5uBS70BCtfrIFg81sqcTVu3Ta+KD1Tk5vAtBNElWxtAa+m8K9A==} + + micromark-extension-mdxjs@3.0.0: + resolution: {integrity: sha512-A873fJfhnJ2siZyUrJ31l34Uqwy4xIFmvPY1oj+Ean5PHcPBYzEsvqvWGaWcfEIr11O5Dlw3p2y0tZWpKHDejQ==} + + micromark-factory-destination@2.0.1: + resolution: {integrity: sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==} + + micromark-factory-label@2.0.1: + resolution: {integrity: sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==} + + micromark-factory-mdx-expression@2.0.3: + resolution: {integrity: sha512-kQnEtA3vzucU2BkrIa8/VaSAsP+EJ3CKOvhMuJgOEGg9KDC6OAY6nSnNDVRiVNRqj7Y4SlSzcStaH/5jge8JdQ==} + + micromark-factory-space@1.1.0: + resolution: {integrity: sha512-cRzEj7c0OL4Mw2v6nwzttyOZe8XY/Z8G0rzmWQZTBi/jjwyw/U4uqKtUORXQrR5bAZZnbTI/feRV/R7hc4jQYQ==} + + micromark-factory-space@2.0.1: + resolution: {integrity: sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==} + + micromark-factory-title@2.0.1: + resolution: {integrity: sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==} + + micromark-factory-whitespace@2.0.1: + resolution: {integrity: sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==} + + micromark-util-character@1.2.0: + resolution: {integrity: sha512-lXraTwcX3yH/vMDaFWCQJP1uIszLVebzUa3ZHdrgxr7KEU/9mL4mVgCpGbyhvNLNlauROiNUq7WN5u7ndbY6xg==} + + micromark-util-character@2.1.1: + resolution: {integrity: sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==} + + micromark-util-chunked@2.0.1: + resolution: {integrity: sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==} + + micromark-util-classify-character@2.0.1: + resolution: {integrity: sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==} + + micromark-util-combine-extensions@2.0.1: + resolution: {integrity: sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==} + + micromark-util-decode-numeric-character-reference@2.0.2: + resolution: {integrity: sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==} + + micromark-util-decode-string@2.0.1: + resolution: {integrity: sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==} + + micromark-util-encode@2.0.1: + resolution: {integrity: sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==} + + micromark-util-events-to-acorn@2.0.3: + resolution: {integrity: sha512-jmsiEIiZ1n7X1Rr5k8wVExBQCg5jy4UXVADItHmNk1zkwEVhBuIUKRu3fqv+hs4nxLISi2DQGlqIOGiFxgbfHg==} + + micromark-util-html-tag-name@2.0.1: + resolution: {integrity: sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==} + + micromark-util-normalize-identifier@2.0.1: + resolution: {integrity: sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==} + + micromark-util-resolve-all@2.0.1: + resolution: {integrity: sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==} + + micromark-util-sanitize-uri@2.0.1: + resolution: {integrity: sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==} + + micromark-util-subtokenize@2.1.0: + resolution: {integrity: sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==} + + micromark-util-symbol@1.1.0: + resolution: {integrity: sha512-uEjpEYY6KMs1g7QfJ2eX1SQEV+ZT4rUD3UcF6l57acZvLNK7PBZL+ty82Z1qhK1/yXIY4bdx04FKMgR0g4IAag==} + + micromark-util-symbol@2.0.1: + resolution: {integrity: sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==} + + micromark-util-types@1.1.0: + resolution: {integrity: sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==} + + micromark-util-types@2.0.2: + resolution: {integrity: sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==} + + micromark@4.0.2: + resolution: {integrity: sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==} + + micromatch@4.0.8: + resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} + engines: {node: '>=8.6'} + + mime-db@1.33.0: + resolution: {integrity: sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==} + engines: {node: '>= 0.6'} + + mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + + mime-db@1.54.0: + resolution: {integrity: sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==} + engines: {node: '>= 0.6'} + + mime-types@2.1.18: + resolution: {integrity: sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==} + engines: {node: '>= 0.6'} + + mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + + mime-types@3.0.2: + resolution: {integrity: sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==} + engines: {node: '>=18'} + + mime@1.6.0: + resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==} + engines: {node: '>=4'} + hasBin: true + + mimic-fn@2.1.0: + resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} + engines: {node: '>=6'} + + mimic-response@3.1.0: + resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==} + engines: {node: '>=10'} + + mimic-response@4.0.0: + resolution: {integrity: sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + mini-css-extract-plugin@2.10.0: + resolution: {integrity: sha512-540P2c5dYnJlyJxTaSloliZexv8rji6rY8FhQN+WF/82iHQfA23j/xtJx97L+mXOML27EqksSek/g4eK7jaL3g==} + engines: {node: '>= 12.13.0'} + peerDependencies: + webpack: ^5.0.0 + + minimalistic-assert@1.0.1: + resolution: {integrity: sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==} + + minimalistic-crypto-utils@1.0.1: + resolution: {integrity: sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==} + + minimatch@10.1.1: + resolution: {integrity: sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==} + engines: {node: 20 || >=22} + + minimatch@3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + + minimatch@5.1.6: + resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==} + engines: {node: '>=10'} + + minimatch@9.0.5: + resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} + engines: {node: '>=16 || 14 >=14.17'} + + minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + + mipd@0.0.7: + resolution: {integrity: sha512-aAPZPNDQ3uMTdKbuO2YmAw2TxLHO0moa4YKAyETM/DTj5FloZo+a+8tU+iv4GmW+sOxKLSRwcSFuczk+Cpt6fg==} + peerDependencies: + typescript: '>=5.0.4' + peerDependenciesMeta: + typescript: + optional: true + + mkdirp@0.5.6: + resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==} + hasBin: true + + mkdirp@1.0.4: + resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} + engines: {node: '>=10'} + hasBin: true + + mnemonist@0.38.5: + resolution: {integrity: sha512-bZTFT5rrPKtPJxj8KSV0WkPyNxl72vQepqqVUAW2ARUpUSF2qXMB6jZj7hW5/k7C1rtpzqbD/IIbJwLXUjCHeg==} + + mocha@10.8.2: + resolution: {integrity: sha512-VZlYo/WE8t1tstuRmqgeyBgCbJc/lEdopaa+axcKzTBJ+UIdlAB9XnmvTCAH4pwR4ElNInaedhEBmZD8iCSVEg==} + engines: {node: '>= 14.0.0'} + hasBin: true + + modern-ahocorasick@1.1.0: + resolution: {integrity: sha512-sEKPVl2rM+MNVkGQt3ChdmD8YsigmXdn5NifZn6jiwn9LRJpWm8F3guhaqrJT/JOat6pwpbXEk6kv+b9DMIjsQ==} + + motion-dom@12.23.23: + resolution: {integrity: sha512-n5yolOs0TQQBRUFImrRfs/+6X4p3Q4n1dUEqt/H58Vx7OW6RF+foWEgmTVDhIWJIMXOuNNL0apKH2S16en9eiA==} + + motion-utils@12.23.6: + resolution: {integrity: sha512-eAWoPgr4eFEOFfg2WjIsMoqJTW6Z8MTUCgn/GZ3VRpClWBdnbjryiA3ZSNLyxCTmCQx4RmYX6jX1iWHbenUPNQ==} + + mrmime@2.0.1: + resolution: {integrity: sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==} + engines: {node: '>=10'} + + ms@2.0.0: + resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} + + ms@2.1.2: + resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + multicast-dns@7.2.5: + resolution: {integrity: sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==} + hasBin: true + + multiformats@9.9.0: + resolution: {integrity: sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg==} + + mz@2.7.0: + resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} + + nanoid@3.3.11: + resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + ndjson@2.0.0: + resolution: {integrity: sha512-nGl7LRGrzugTtaFcJMhLbpzJM6XdivmbkdlaGcrk/LXg2KL/YBC6z1g70xh0/al+oFuVFP8N8kiWRucmeEH/qQ==} + engines: {node: '>=10'} + hasBin: true + + negotiator@0.6.3: + resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==} + engines: {node: '>= 0.6'} + + negotiator@0.6.4: + resolution: {integrity: sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==} + engines: {node: '>= 0.6'} + + neo-async@2.6.2: + resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} + + no-case@3.0.4: + resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==} + + node-addon-api@2.0.2: + resolution: {integrity: sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==} + + node-addon-api@5.1.0: + resolution: {integrity: sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA==} + + node-emoji@1.11.0: + resolution: {integrity: sha512-wo2DpQkQp7Sjm2A0cq+sN7EHKO6Sl0ctXeBdFZrL9T9+UywORbufTcTZxom8YqpLQt/FqNMUkOpkZrJVYSKD3A==} + + node-emoji@2.2.0: + resolution: {integrity: sha512-Z3lTE9pLaJF47NyMhd4ww1yFTAP8YhYI8SleJiHzM46Fgpm5cnNzSl9XfzFNqbaz+VlJrIj3fXQ4DeN1Rjm6cw==} + engines: {node: '>=18'} + + 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} + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + + node-gyp-build@4.8.4: + resolution: {integrity: sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==} + hasBin: true + + node-mock-http@1.0.4: + resolution: {integrity: sha512-8DY+kFsDkNXy1sJglUfuODx1/opAGJGyrTuFqEoN90oRc2Vk0ZbD4K2qmKXBBEhZQzdKHIVfEJpDU8Ak2NJEvQ==} + + node-releases@2.0.27: + resolution: {integrity: sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==} + + nofilter@3.1.0: + resolution: {integrity: sha512-l2NNj07e9afPnhAhvgVrCD/oy2Ai1yfLpuo3EpiO1jFTsB4sFz6oIfAfSZyQzVpkZQ9xS8ZS5g1jCBgq4Hwo0g==} + engines: {node: '>=12.19'} + + nopt@3.0.6: + resolution: {integrity: sha512-4GUt3kSEYmk4ITxzB/b9vaIDfUVWN/Ml1Fwl11IlnIG2iaJ9O6WXZ9SrYM9NLI8OCBieN2Y8SWC2oJV0RQ7qYg==} + hasBin: true + + normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + + normalize-url@8.1.1: + resolution: {integrity: sha512-JYc0DPlpGWB40kH5g07gGTrYuMqV653k3uBKY6uITPWds3M0ov3GaWGp9lbE3Bzngx8+XkfzgvASb9vk9JDFXQ==} + engines: {node: '>=14.16'} + + npm-run-path@4.0.1: + resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} + engines: {node: '>=8'} + + nprogress@0.2.0: + resolution: {integrity: sha512-I19aIingLgR1fmhftnbWWO3dXc0hSxqHQHQb3H8m+K3TnEn/iSeTZZOyvKXWqQESMwuUVnatlCnZdLBZZt2VSA==} + + nth-check@2.1.1: + resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} + + null-loader@4.0.1: + resolution: {integrity: sha512-pxqVbi4U6N26lq+LmgIbB5XATP0VdZKOG25DhHi8btMmJJefGArFyDg1yc4U3hWCJbMqSrw0qyrz1UQX+qYXqg==} + engines: {node: '>= 10.13.0'} + peerDependencies: + webpack: ^4.0.0 || ^5.0.0 + + number-to-bn@1.7.0: + resolution: {integrity: sha512-wsJ9gfSz1/s4ZsJN01lyonwuxA1tml6X1yBDnfpMglypcBRFZZkus26EdPSlqS5GJfYddVZa22p3VNb3z5m5Ig==} + engines: {node: '>=6.5.0', npm: '>=3'} + + 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'} + + object-hash@3.0.0: + resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==} + engines: {node: '>= 6'} + + object-inspect@1.13.4: + resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} + engines: {node: '>= 0.4'} + + object-keys@1.1.1: + resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} + engines: {node: '>= 0.4'} + + object.assign@4.1.7: + resolution: {integrity: sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==} + engines: {node: '>= 0.4'} + + obliterator@2.0.5: + resolution: {integrity: sha512-42CPE9AhahZRsMNslczq0ctAEtqk8Eka26QofnqC346BZdHDySk3LWka23LI7ULIw11NmltpiLagIq8gBozxTw==} + + obuf@1.1.2: + resolution: {integrity: sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==} + + ofetch@1.5.1: + resolution: {integrity: sha512-2W4oUZlVaqAPAil6FUg/difl6YhqhUR7x2eZY4bQCko22UXg3hptq9KLQdqFClV+Wu85UX7hNtdGTngi/1BxcA==} + + on-exit-leak-free@0.2.0: + resolution: {integrity: sha512-dqaz3u44QbRXQooZLTUKU41ZrzYrcvLISVgbrzbyCMxpmSLJvZ3ZamIJIZ29P6OhZIkNIQKosdeM6t1LYbA9hg==} + + on-finished@2.4.1: + resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} + engines: {node: '>= 0.8'} + + on-headers@1.1.0: + resolution: {integrity: sha512-737ZY3yNnXy37FHkQxPzt4UZ2UWPWiCZWLvFZ4fu5cueciegX0zGPnrlY6bwRg4FdQOe9YU8MkmJwGhoMybl8A==} + engines: {node: '>= 0.8'} + + once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + + onetime@5.1.2: + resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} + engines: {node: '>=6'} + + open@10.2.0: + resolution: {integrity: sha512-YgBpdJHPyQ2UE5x+hlSXcnejzAvD0b22U2OuAP+8OnlJT+PjWPxtgmGqKKc+RgTM63U9gN0YzrYc71R2WT/hTA==} + engines: {node: '>=18'} + + open@8.4.2: + resolution: {integrity: sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==} + 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==} + + opener@1.5.2: + resolution: {integrity: sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==} + hasBin: true + + optionator@0.8.3: + resolution: {integrity: sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==} + engines: {node: '>= 0.8.0'} + + ordinal@1.0.3: + resolution: {integrity: sha512-cMddMgb2QElm8G7vdaa02jhUNbTSrhsgAGUz1OokD83uJTwSUn+nKoNoKVVaRa08yF6sgfO7Maou1+bgLd9rdQ==} + + os-tmpdir@1.0.2: + resolution: {integrity: sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==} + engines: {node: '>=0.10.0'} + + ox@0.10.5: + resolution: {integrity: sha512-mXJRiZswmX46abrzNkJpTN9sPJ/Rhevsp5Dfg0z80D55aoLNmEV4oN+/+feSNW593c2CnHavMqSVBanpJ0lUkQ==} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + 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-cancelable@3.0.0: + resolution: {integrity: sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==} + engines: {node: '>=12.20'} + + p-finally@1.0.0: + resolution: {integrity: sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==} + engines: {node: '>=4'} + + p-limit@2.3.0: + resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} + engines: {node: '>=6'} + + p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + + p-limit@4.0.0: + resolution: {integrity: sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + 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-locate@6.0.0: + resolution: {integrity: sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + p-map@4.0.0: + resolution: {integrity: sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==} + engines: {node: '>=10'} + + p-queue@6.6.2: + resolution: {integrity: sha512-RwFpb72c/BhQLEXIZ5K2e+AhgNVmIejGlTgiB9MzZ0e93GRvqZ7uSi0dvRF7/XIXDeNkra2fNHBxTyPDGySpjQ==} + engines: {node: '>=8'} + + p-retry@6.2.1: + resolution: {integrity: sha512-hEt02O4hUct5wtwg4H4KcWgDdm+l1bOaEy/hWzd8xtXB9BqxTWBBhb+2ImAtH4Cv4rPjV76xN3Zumqk3k3AhhQ==} + engines: {node: '>=16.17'} + + p-timeout@3.2.0: + resolution: {integrity: sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==} + engines: {node: '>=8'} + + p-try@2.2.0: + resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} + engines: {node: '>=6'} + + package-json@8.1.1: + resolution: {integrity: sha512-cbH9IAIJHNj9uXi196JVsRlt7cHKak6u/e6AkL/bkRelZ7rlL3X1YKxsZwa36xipOEKAsdtmaG6aAJoM1fx2zA==} + engines: {node: '>=14.16'} + + param-case@3.0.4: + resolution: {integrity: sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==} + + parent-module@1.0.1: + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} + engines: {node: '>=6'} + + parse-cache-control@1.0.1: + resolution: {integrity: sha512-60zvsJReQPX5/QP0Kzfd/VrpjScIQ7SHBW6bFCYfEP+fp0Eppr1SHhIO5nd1PjZtvclzSzES9D/p5nFJurwfWg==} + + parse-entities@4.0.2: + resolution: {integrity: sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==} + + parse-json@5.2.0: + resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} + engines: {node: '>=8'} + + parse-numeric-range@1.3.0: + resolution: {integrity: sha512-twN+njEipszzlMJd4ONUYgSfZPDxgHhT9Ahed5uTigpQn90FggW4SA/AIPq/6a149fTbE9qBEcSwE3FAEp6wQQ==} + + parse5-htmlparser2-tree-adapter@7.1.0: + resolution: {integrity: sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g==} + + parse5@7.3.0: + resolution: {integrity: sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==} + + parseurl@1.3.3: + resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} + engines: {node: '>= 0.8'} + + pascal-case@3.1.2: + resolution: {integrity: sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==} + + path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + + path-exists@5.0.0: + resolution: {integrity: sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + path-is-absolute@1.0.1: + resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} + engines: {node: '>=0.10.0'} + + path-is-inside@1.0.2: + resolution: {integrity: sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + path-parse@1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + + path-to-regexp@0.1.12: + resolution: {integrity: sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==} + + path-to-regexp@1.9.0: + resolution: {integrity: sha512-xIp7/apCFJuUHdDLWe8O1HIkb0kQrOMb/0u6FXQjemHn/ii5LrIzU6bdECnsiTF/GjZkMEKg1xdiZwNqDYlZ6g==} + + path-to-regexp@3.3.0: + resolution: {integrity: sha512-qyCH421YQPS2WFDxDjftfc1ZR5WKQzVzqsp4n9M2kQhVOo/ByahFoUNJfl58kOcEGfQ//7weFTDhm+ss8Ecxgw==} + + path-type@4.0.0: + resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} + engines: {node: '>=8'} + + pathe@2.0.3: + resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} + + pathval@1.1.1: + resolution: {integrity: sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==} + + pathval@2.0.1: + resolution: {integrity: sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==} + engines: {node: '>= 14.16'} + + pbkdf2@3.1.5: + resolution: {integrity: sha512-Q3CG/cYvCO1ye4QKkuH7EXxs3VC/rI1/trd+qX2+PolbaKG0H+bgcZzrTt96mMyRtejk+JMCiLUn3y29W8qmFQ==} + engines: {node: '>= 0.10'} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + + picomatch@4.0.3: + resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} + engines: {node: '>=12'} + + pify@2.3.0: + resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==} + engines: {node: '>=0.10.0'} + + pify@3.0.0: + resolution: {integrity: sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==} + engines: {node: '>=4'} + + pify@4.0.1: + resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==} + engines: {node: '>=6'} + + 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'} + + pkg-dir@7.0.0: + resolution: {integrity: sha512-Ie9z/WINcxxLp27BKOCHGde4ITq9UklYKDzVo1nhk5sqGEXU3FpkwP5GM2voTGJkGd9B3Otl+Q4uwSOeSUtOBA==} + engines: {node: '>=14.16'} + + pkijs@3.3.3: + resolution: {integrity: sha512-+KD8hJtqQMYoTuL1bbGOqxb4z+nZkTAwVdNtWwe8Tc2xNbEmdJYIYoc6Qt0uF55e6YW6KuTHw1DjQ18gMhzepw==} + engines: {node: '>=16.0.0'} + + 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'} + + 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-attribute-case-insensitive@7.0.1: + resolution: {integrity: sha512-Uai+SupNSqzlschRyNx3kbCTWgY/2hcwtHEI/ej2LJWc9JJ77qKgGptd8DHwY1mXtZ7Aoh4z4yxfwMBue9eNgw==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + postcss-calc@9.0.1: + resolution: {integrity: sha512-TipgjGyzP5QzEhsOZUaIkeO5mKeMFpebWzRogWG/ysonUlnHcq5aJe0jOjpfzUU8PeSaBQnrE8ehR0QA5vs8PQ==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.2.2 + + postcss-clamp@4.1.0: + resolution: {integrity: sha512-ry4b1Llo/9zz+PKC+030KUnPITTJAHeOwjfAyyB60eT0AorGLdzp52s31OsPRHRf8NchkgFoG2y6fCfn1IV1Ow==} + engines: {node: '>=7.6.0'} + peerDependencies: + postcss: ^8.4.6 + + postcss-color-functional-notation@7.0.12: + resolution: {integrity: sha512-TLCW9fN5kvO/u38/uesdpbx3e8AkTYhMvDZYa9JpmImWuTE99bDQ7GU7hdOADIZsiI9/zuxfAJxny/khknp1Zw==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + postcss-color-hex-alpha@10.0.0: + resolution: {integrity: sha512-1kervM2cnlgPs2a8Vt/Qbe5cQ++N7rkYo/2rz2BkqJZIHQwaVuJgQH38REHrAi4uM0b1fqxMkWYmese94iMp3w==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + postcss-color-rebeccapurple@10.0.0: + resolution: {integrity: sha512-JFta737jSP+hdAIEhk1Vs0q0YF5P8fFcj+09pweS8ktuGuZ8pPlykHsk6mPxZ8awDl4TrcxUqJo9l1IhVr/OjQ==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + postcss-colormin@6.1.0: + resolution: {integrity: sha512-x9yX7DOxeMAR+BgGVnNSAxmAj98NX/YxEMNFP+SDCEeNLb2r3i6Hh1ksMsnW8Ub5SLCpbescQqn9YEbE9554Sw==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-convert-values@6.1.0: + resolution: {integrity: sha512-zx8IwP/ts9WvUM6NkVSkiU902QZL1bwPhaVaLynPtCsOTqp+ZKbNi+s6XJg3rfqpKGA/oc7Oxk5t8pOQJcwl/w==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-custom-media@11.0.6: + resolution: {integrity: sha512-C4lD4b7mUIw+RZhtY7qUbf4eADmb7Ey8BFA2px9jUbwg7pjTZDl4KY4bvlUV+/vXQvzQRfiGEVJyAbtOsCMInw==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + postcss-custom-properties@14.0.6: + resolution: {integrity: sha512-fTYSp3xuk4BUeVhxCSJdIPhDLpJfNakZKoiTDx7yRGCdlZrSJR7mWKVOBS4sBF+5poPQFMj2YdXx1VHItBGihQ==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + postcss-custom-selectors@8.0.5: + resolution: {integrity: sha512-9PGmckHQswiB2usSO6XMSswO2yFWVoCAuih1yl9FVcwkscLjRKjwsjM3t+NIWpSU2Jx3eOiK2+t4vVTQaoCHHg==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + postcss-dir-pseudo-class@9.0.1: + resolution: {integrity: sha512-tRBEK0MHYvcMUrAuYMEOa0zg9APqirBcgzi6P21OhxtJyJADo/SWBwY1CAwEohQ/6HDaa9jCjLRG7K3PVQYHEA==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + postcss-discard-comments@6.0.2: + resolution: {integrity: sha512-65w/uIqhSBBfQmYnG92FO1mWZjJ4GL5b8atm5Yw2UgrwD7HiNiSSNwJor1eCFGzUgYnN/iIknhNRVqjrrpuglw==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-discard-duplicates@6.0.3: + resolution: {integrity: sha512-+JA0DCvc5XvFAxwx6f/e68gQu/7Z9ud584VLmcgto28eB8FqSFZwtrLwB5Kcp70eIoWP/HXqz4wpo8rD8gpsTw==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-discard-empty@6.0.3: + resolution: {integrity: sha512-znyno9cHKQsK6PtxL5D19Fj9uwSzC2mB74cpT66fhgOadEUPyXFkbgwm5tvc3bt3NAy8ltE5MrghxovZRVnOjQ==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-discard-overridden@6.0.2: + resolution: {integrity: sha512-j87xzI4LUggC5zND7KdjsI25APtyMuynXZSujByMaav2roV6OZX+8AaCUcZSWqckZpjAjRyFDdpqybgjFO0HJQ==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-discard-unused@6.0.5: + resolution: {integrity: sha512-wHalBlRHkaNnNwfC8z+ppX57VhvS+HWgjW508esjdaEYr3Mx7Gnn2xA4R/CKf5+Z9S5qsqC+Uzh4ueENWwCVUA==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-double-position-gradients@6.0.4: + resolution: {integrity: sha512-m6IKmxo7FxSP5nF2l63QbCC3r+bWpFUWmZXZf096WxG0m7Vl1Q1+ruFOhpdDRmKrRS+S3Jtk+TVk/7z0+BVK6g==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + postcss-focus-visible@10.0.1: + resolution: {integrity: sha512-U58wyjS/I1GZgjRok33aE8juW9qQgQUNwTSdxQGuShHzwuYdcklnvK/+qOWX1Q9kr7ysbraQ6ht6r+udansalA==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + postcss-focus-within@9.0.1: + resolution: {integrity: sha512-fzNUyS1yOYa7mOjpci/bR+u+ESvdar6hk8XNK/TRR0fiGTp2QT5N+ducP0n3rfH/m9I7H/EQU6lsa2BrgxkEjw==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + postcss-font-variant@5.0.0: + resolution: {integrity: sha512-1fmkBaCALD72CK2a9i468mA/+tr9/1cBxRRMXOUaZqO43oWPR5imcyPjXwuv7PXbCid4ndlP5zWhidQVVa3hmA==} + peerDependencies: + postcss: ^8.1.0 + + postcss-gap-properties@6.0.0: + resolution: {integrity: sha512-Om0WPjEwiM9Ru+VhfEDPZJAKWUd0mV1HmNXqp2C29z80aQ2uP9UVhLc7e3aYMIor/S5cVhoPgYQ7RtfeZpYTRw==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + postcss-image-set-function@7.0.0: + resolution: {integrity: sha512-QL7W7QNlZuzOwBTeXEmbVckNt1FSmhQtbMRvGGqqU4Nf4xk6KUEQhAoWuMzwbSv5jxiRiSZ5Tv7eiDB9U87znA==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + postcss-import@15.1.0: + resolution: {integrity: sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==} + engines: {node: '>=14.0.0'} + peerDependencies: + postcss: ^8.0.0 + + postcss-js@4.1.0: + resolution: {integrity: sha512-oIAOTqgIo7q2EOwbhb8UalYePMvYoIeRY2YKntdpFQXNosSu3vLrniGgmH9OKs/qAkfoj5oB3le/7mINW1LCfw==} + engines: {node: ^12 || ^14 || >= 16} + peerDependencies: + postcss: ^8.4.21 + + postcss-lab-function@7.0.12: + resolution: {integrity: sha512-tUcyRk1ZTPec3OuKFsqtRzW2Go5lehW29XA21lZ65XmzQkz43VY2tyWEC202F7W3mILOjw0voOiuxRGTsN+J9w==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + postcss-load-config@6.0.1: + resolution: {integrity: sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==} + engines: {node: '>= 18'} + peerDependencies: + jiti: '>=1.21.0' + postcss: '>=8.0.9' + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + jiti: + optional: true + postcss: + optional: true + tsx: + optional: true + yaml: + optional: true + + postcss-loader@7.3.4: + resolution: {integrity: sha512-iW5WTTBSC5BfsBJ9daFMPVrLT36MrNiC6fqOZTTaHjBNX6Pfd5p+hSBqe/fEeNd7pc13QiAyGt7VdGMw4eRC4A==} + engines: {node: '>= 14.15.0'} + peerDependencies: + postcss: ^7.0.0 || ^8.0.1 + webpack: ^5.0.0 + + postcss-logical@8.1.0: + resolution: {integrity: sha512-pL1hXFQ2fEXNKiNiAgtfA005T9FBxky5zkX6s4GZM2D8RkVgRqz3f4g1JUoq925zXv495qk8UNldDwh8uGEDoA==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + postcss-merge-idents@6.0.3: + resolution: {integrity: sha512-1oIoAsODUs6IHQZkLQGO15uGEbK3EAl5wi9SS8hs45VgsxQfMnxvt+L+zIr7ifZFIH14cfAeVe2uCTa+SPRa3g==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-merge-longhand@6.0.5: + resolution: {integrity: sha512-5LOiordeTfi64QhICp07nzzuTDjNSO8g5Ksdibt44d+uvIIAE1oZdRn8y/W5ZtYgRH/lnLDlvi9F8btZcVzu3w==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-merge-rules@6.1.1: + resolution: {integrity: sha512-KOdWF0gju31AQPZiD+2Ar9Qjowz1LTChSjFFbS+e2sFgc4uHOp3ZvVX4sNeTlk0w2O31ecFGgrFzhO0RSWbWwQ==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-minify-font-values@6.1.0: + resolution: {integrity: sha512-gklfI/n+9rTh8nYaSJXlCo3nOKqMNkxuGpTn/Qm0gstL3ywTr9/WRKznE+oy6fvfolH6dF+QM4nCo8yPLdvGJg==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-minify-gradients@6.0.3: + resolution: {integrity: sha512-4KXAHrYlzF0Rr7uc4VrfwDJ2ajrtNEpNEuLxFgwkhFZ56/7gaE4Nr49nLsQDZyUe+ds+kEhf+YAUolJiYXF8+Q==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-minify-params@6.1.0: + resolution: {integrity: sha512-bmSKnDtyyE8ujHQK0RQJDIKhQ20Jq1LYiez54WiaOoBtcSuflfK3Nm596LvbtlFcpipMjgClQGyGr7GAs+H1uA==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-minify-selectors@6.0.4: + resolution: {integrity: sha512-L8dZSwNLgK7pjTto9PzWRoMbnLq5vsZSTu8+j1P/2GB8qdtGQfn+K1uSvFgYvgh83cbyxT5m43ZZhUMTJDSClQ==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-modules-extract-imports@3.1.0: + resolution: {integrity: sha512-k3kNe0aNFQDAZGbin48pL2VNidTF0w4/eASDsxlyspobzU3wZQLOGj7L9gfRe0Jo9/4uud09DsjFNH7winGv8Q==} + engines: {node: ^10 || ^12 || >= 14} + peerDependencies: + postcss: ^8.1.0 + + postcss-modules-local-by-default@4.2.0: + resolution: {integrity: sha512-5kcJm/zk+GJDSfw+V/42fJ5fhjL5YbFDl8nVdXkJPLLW+Vf9mTD5Xe0wqIaDnLuL2U6cDNpTr+UQ+v2HWIBhzw==} + engines: {node: ^10 || ^12 || >= 14} + peerDependencies: + postcss: ^8.1.0 + + postcss-modules-scope@3.2.1: + resolution: {integrity: sha512-m9jZstCVaqGjTAuny8MdgE88scJnCiQSlSrOWcTQgM2t32UBe+MUmFSO5t7VMSfAf/FJKImAxBav8ooCHJXCJA==} + engines: {node: ^10 || ^12 || >= 14} + peerDependencies: + postcss: ^8.1.0 + + postcss-modules-values@4.0.0: + resolution: {integrity: sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==} + engines: {node: ^10 || ^12 || >= 14} + peerDependencies: + postcss: ^8.1.0 + + postcss-nested@6.2.0: + resolution: {integrity: sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==} + engines: {node: '>=12.0'} + peerDependencies: + postcss: ^8.2.14 + + postcss-nesting@13.0.2: + resolution: {integrity: sha512-1YCI290TX+VP0U/K/aFxzHzQWHWURL+CtHMSbex1lCdpXD1SoR2sYuxDu5aNI9lPoXpKTCggFZiDJbwylU0LEQ==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + postcss-normalize-charset@6.0.2: + resolution: {integrity: sha512-a8N9czmdnrjPHa3DeFlwqst5eaL5W8jYu3EBbTTkI5FHkfMhFZh1EGbku6jhHhIzTA6tquI2P42NtZ59M/H/kQ==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-normalize-display-values@6.0.2: + resolution: {integrity: sha512-8H04Mxsb82ON/aAkPeq8kcBbAtI5Q2a64X/mnRRfPXBq7XeogoQvReqxEfc0B4WPq1KimjezNC8flUtC3Qz6jg==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-normalize-positions@6.0.2: + resolution: {integrity: sha512-/JFzI441OAB9O7VnLA+RtSNZvQ0NCFZDOtp6QPFo1iIyawyXg0YI3CYM9HBy1WvwCRHnPep/BvI1+dGPKoXx/Q==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-normalize-repeat-style@6.0.2: + resolution: {integrity: sha512-YdCgsfHkJ2jEXwR4RR3Tm/iOxSfdRt7jplS6XRh9Js9PyCR/aka/FCb6TuHT2U8gQubbm/mPmF6L7FY9d79VwQ==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-normalize-string@6.0.2: + resolution: {integrity: sha512-vQZIivlxlfqqMp4L9PZsFE4YUkWniziKjQWUtsxUiVsSSPelQydwS8Wwcuw0+83ZjPWNTl02oxlIvXsmmG+CiQ==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-normalize-timing-functions@6.0.2: + resolution: {integrity: sha512-a+YrtMox4TBtId/AEwbA03VcJgtyW4dGBizPl7e88cTFULYsprgHWTbfyjSLyHeBcK/Q9JhXkt2ZXiwaVHoMzA==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-normalize-unicode@6.1.0: + resolution: {integrity: sha512-QVC5TQHsVj33otj8/JD869Ndr5Xcc/+fwRh4HAsFsAeygQQXm+0PySrKbr/8tkDKzW+EVT3QkqZMfFrGiossDg==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-normalize-url@6.0.2: + resolution: {integrity: sha512-kVNcWhCeKAzZ8B4pv/DnrU1wNh458zBNp8dh4y5hhxih5RZQ12QWMuQrDgPRw3LRl8mN9vOVfHl7uhvHYMoXsQ==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-normalize-whitespace@6.0.2: + resolution: {integrity: sha512-sXZ2Nj1icbJOKmdjXVT9pnyHQKiSAyuNQHSgRCUgThn2388Y9cGVDR+E9J9iAYbSbLHI+UUwLVl1Wzco/zgv0Q==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-opacity-percentage@3.0.0: + resolution: {integrity: sha512-K6HGVzyxUxd/VgZdX04DCtdwWJ4NGLG212US4/LA1TLAbHgmAsTWVR86o+gGIbFtnTkfOpb9sCRBx8K7HO66qQ==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + postcss-ordered-values@6.0.2: + resolution: {integrity: sha512-VRZSOB+JU32RsEAQrO94QPkClGPKJEL/Z9PCBImXMhIeK5KAYo6slP/hBYlLgrCjFxyqvn5VC81tycFEDBLG1Q==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-overflow-shorthand@6.0.0: + resolution: {integrity: sha512-BdDl/AbVkDjoTofzDQnwDdm/Ym6oS9KgmO7Gr+LHYjNWJ6ExORe4+3pcLQsLA9gIROMkiGVjjwZNoL/mpXHd5Q==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + postcss-page-break@3.0.4: + resolution: {integrity: sha512-1JGu8oCjVXLa9q9rFTo4MbeeA5FMe00/9C7lN4va606Rdb+HkxXtXsmEDrIraQ11fGz/WvKWa8gMuCKkrXpTsQ==} + peerDependencies: + postcss: ^8 + + postcss-place@10.0.0: + resolution: {integrity: sha512-5EBrMzat2pPAxQNWYavwAfoKfYcTADJ8AXGVPcUZ2UkNloUTWzJQExgrzrDkh3EKzmAx1evfTAzF9I8NGcc+qw==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + postcss-preset-env@10.6.1: + resolution: {integrity: sha512-yrk74d9EvY+W7+lO9Aj1QmjWY9q5NsKjK2V9drkOPZB/X6KZ0B3igKsHUYakb7oYVhnioWypQX3xGuePf89f3g==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + postcss-pseudo-class-any-link@10.0.1: + resolution: {integrity: sha512-3el9rXlBOqTFaMFkWDOkHUTQekFIYnaQY55Rsp8As8QQkpiSgIYEcF/6Ond93oHiDsGb4kad8zjt+NPlOC1H0Q==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + postcss-reduce-idents@6.0.3: + resolution: {integrity: sha512-G3yCqZDpsNPoQgbDUy3T0E6hqOQ5xigUtBQyrmq3tn2GxlyiL0yyl7H+T8ulQR6kOcHJ9t7/9H4/R2tv8tJbMA==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-reduce-initial@6.1.0: + resolution: {integrity: sha512-RarLgBK/CrL1qZags04oKbVbrrVK2wcxhvta3GCxrZO4zveibqbRPmm2VI8sSgCXwoUHEliRSbOfpR0b/VIoiw==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-reduce-transforms@6.0.2: + resolution: {integrity: sha512-sB+Ya++3Xj1WaT9+5LOOdirAxP7dJZms3GRcYheSPi1PiTMigsxHAdkrbItHxwYHr4kt1zL7mmcHstgMYT+aiA==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-replace-overflow-wrap@4.0.0: + resolution: {integrity: sha512-KmF7SBPphT4gPPcKZc7aDkweHiKEEO8cla/GjcBK+ckKxiZslIu3C4GCRW3DNfL0o7yW7kMQu9xlZ1kXRXLXtw==} + peerDependencies: + postcss: ^8.0.3 + + postcss-selector-not@8.0.1: + resolution: {integrity: sha512-kmVy/5PYVb2UOhy0+LqUYAhKj7DUGDpSWa5LZqlkWJaaAV+dxxsOG3+St0yNLu6vsKD7Dmqx+nWQt0iil89+WA==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + postcss-selector-parser@6.1.2: + resolution: {integrity: sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==} + engines: {node: '>=4'} + + postcss-selector-parser@7.1.1: + resolution: {integrity: sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==} + engines: {node: '>=4'} + + postcss-sort-media-queries@5.2.0: + resolution: {integrity: sha512-AZ5fDMLD8SldlAYlvi8NIqo0+Z8xnXU2ia0jxmuhxAU+Lqt9K+AlmLNJ/zWEnE9x+Zx3qL3+1K20ATgNOr3fAA==} + engines: {node: '>=14.0.0'} + peerDependencies: + postcss: ^8.4.23 + + postcss-svgo@6.0.3: + resolution: {integrity: sha512-dlrahRmxP22bX6iKEjOM+c8/1p+81asjKT+V5lrgOH944ryx/OHpclnIbGsKVd3uWOXFLYJwCVf0eEkJGvO96g==} + engines: {node: ^14 || ^16 || >= 18} + peerDependencies: + postcss: ^8.4.31 + + postcss-unique-selectors@6.0.4: + resolution: {integrity: sha512-K38OCaIrO8+PzpArzkLKB42dSARtC2tmG6PvD4b1o1Q2E9Os8jzfWFfSy/rixsHwohtsDdFtAWGjFVFUdwYaMg==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-value-parser@4.2.0: + resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} + + postcss-zindex@6.0.2: + resolution: {integrity: sha512-5BxW9l1evPB/4ZIc+2GobEBoKC+h8gPGCMi+jxsYvd2x0mjq7wazk6DrP71pStqxE9Foxh5TVnonbWpFZzXaYg==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + 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.0: + resolution: {integrity: sha512-rytDAoiXr3+t6OIP3WGlDd0ouCUG1iCWzkcY3++Nreuoi17y6T5i/zRhe6uYfoVcxq6YU+sBtJouuRDsq8vvqA==} + + prelude-ls@1.1.2: + resolution: {integrity: sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==} + engines: {node: '>= 0.8.0'} + + prettier@2.8.8: + resolution: {integrity: sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==} + engines: {node: '>=10.13.0'} + hasBin: true + + pretty-error@4.0.0: + resolution: {integrity: sha512-AoJ5YMAcXKYxKhuJGdcvse+Voc6v1RgnsR3nWcYU7q4t6z0Q6T86sv5Zq8VIRbOWWFpvdGE83LtdSMNd+6Y0xw==} + + pretty-time@1.1.0: + resolution: {integrity: sha512-28iF6xPQrP8Oa6uxE6a1biz+lWeTOAPKggvjB8HAs6nVMKZwf5bG++632Dx614hIWgUPkgivRfG+a8uAXGTIbA==} + engines: {node: '>=4'} + + prism-react-renderer@2.4.1: + resolution: {integrity: sha512-ey8Ls/+Di31eqzUxC46h8MksNuGx/n0AAC8uKpwFau4RPDYLuE3EXTp8N8G2vX2N7UC/+IXeNUnlWBGGcAG+Ig==} + peerDependencies: + react: '>=16.0.0' + + prismjs@1.30.0: + resolution: {integrity: sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw==} + engines: {node: '>=6'} + + 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==} + + promise@8.3.0: + resolution: {integrity: sha512-rZPNPKTOYVNEEKFaq1HqTgOwZD+4/YHS5ukLzQCypkj+OkYx7iv0mA91lJlpPPZ8vMau3IIGj5Qlwrx+8iiSmg==} + + prompts@2.4.2: + resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} + engines: {node: '>= 6'} + + prop-types@15.8.1: + resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} + + proper-lockfile@4.1.2: + resolution: {integrity: sha512-TjNPblN4BwAWMXU8s9AEz4JmQxnD1NNL7bNOY/AKUzyamc379FWASUhc/K1pL2noVb+XmZKLL68cjzLsiOAMaA==} + + property-information@7.1.0: + resolution: {integrity: sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==} + + proto-list@1.2.4: + resolution: {integrity: sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==} + + proxy-addr@2.0.7: + resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} + engines: {node: '>= 0.10'} + + 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'} + + pupa@3.3.0: + resolution: {integrity: sha512-LjgDO2zPtoXP2wJpDjZrGdojii1uqO0cnwKoIoUzkfS98HDmbeiGmYiXo3lXeFlq2xvne1QFQhwYXSUCLKtEuA==} + engines: {node: '>=12.20'} + + pvtsutils@1.3.6: + resolution: {integrity: sha512-PLgQXQ6H2FWCaeRak8vvk1GW462lMxB5s3Jm673N82zI4vqtVUPuZdffdZbPDFRoU8kAhItWFtPCWiPpp4/EDg==} + + pvutils@1.1.5: + resolution: {integrity: sha512-KTqnxsgGiQ6ZAzZCVlJH5eOjSnvlyEgx1m8bkRJfOhmGRqfo5KLvmAlACQkrjEtOQ4B7wF9TdSLIs9O90MX9xA==} + engines: {node: '>=16.0.0'} + + qr@0.5.3: + resolution: {integrity: sha512-BSrGdNXa8z6PfEYWtvITV21mQ4asR4UCj38Fa3MUUoFAtYzFK/swEQXF+OeBuNbHPFfs3PzpZuK0BXizWXgFOQ==} + engines: {node: '>= 20.19.0'} + + qrcode@1.5.3: + resolution: {integrity: sha512-puyri6ApkEHYiVl4CFzo1tDkAZ+ATcnbJrJ6RiBM1Fhctdn/ix9MTE3hRph33omisEbC/2fcfemsseiKgBPKZg==} + engines: {node: '>=10.13.0'} + hasBin: true + + qs@6.14.0: + resolution: {integrity: sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==} + engines: {node: '>=0.6'} + + 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==} + + quick-lru@5.1.1: + resolution: {integrity: sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==} + engines: {node: '>=10'} + + radix3@1.1.2: + resolution: {integrity: sha512-b484I/7b8rDEdSDKckSSBA8knMpcdsXudlE/LNL639wFoHKwLbEkQFZHWEYwDC0wa0FKUcCY+GAF73Z7wxNVFA==} + + randombytes@2.1.0: + resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} + + range-parser@1.2.0: + resolution: {integrity: sha512-kA5WQoNVo4t9lNx2kQNFCxKeBl5IbbSNBl1M/tLkw9WCn+hxNBAW5Qh8gdhs63CJnhjJ2zQWFoqPJP2sK1AV5A==} + engines: {node: '>= 0.6'} + + range-parser@1.2.1: + resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} + engines: {node: '>= 0.6'} + + raw-body@2.5.3: + resolution: {integrity: sha512-s4VSOf6yN0rvbRZGxs8Om5CWj6seneMwK3oDb4lWDH0UPhWcxwOWw5+qk24bxq87szX1ydrwylIOp2uG1ojUpA==} + engines: {node: '>= 0.8'} + + rc@1.2.8: + resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==} + hasBin: true + + react-dom@18.3.1: + resolution: {integrity: sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==} + peerDependencies: + react: ^18.3.1 + + react-dom@19.2.3: + resolution: {integrity: sha512-yELu4WmLPw5Mr/lmeEpox5rw3RETacE++JgHqQzd2dg+YbJuat3jH4ingc+WPZhxaoFzdv9y33G+F7Nl5O0GBg==} + peerDependencies: + react: ^19.2.3 + + react-fast-compare@3.2.2: + resolution: {integrity: sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==} + + react-is@16.13.1: + resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} + + react-json-view-lite@2.5.0: + resolution: {integrity: sha512-tk7o7QG9oYyELWHL8xiMQ8x4WzjCzbWNyig3uexmkLb54r8jO0yH3WCWx8UZS0c49eSA4QUmG5caiRJ8fAn58g==} + engines: {node: '>=18'} + peerDependencies: + react: ^18.0.0 || ^19.0.0 + + react-loadable-ssr-addon-v5-slorber@1.0.1: + resolution: {integrity: sha512-lq3Lyw1lGku8zUEJPDxsNm1AfYHBrO9Y1+olAYwpUJ2IGFBskM0DMKok97A6LWUpHm+o7IvQBOWu9MLenp9Z+A==} + engines: {node: '>=10.13.0'} + peerDependencies: + react-loadable: '*' + webpack: '>=4.41.1 || 5.x' + + react-refresh@0.17.0: + resolution: {integrity: sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ==} + engines: {node: '>=0.10.0'} + + react-remove-scroll-bar@2.3.8: + resolution: {integrity: sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + + react-remove-scroll@2.6.2: + resolution: {integrity: sha512-KmONPx5fnlXYJQqC62Q+lwIeAk64ws/cUw6omIumRzMRPqgnYqhSSti99nbj0Ry13bv7dF+BKn7NB+OqkdZGTw==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + react-router-config@5.1.1: + resolution: {integrity: sha512-DuanZjaD8mQp1ppHjgnnUnyOlqYXZVjnov/JzFhjLEwd3Z4dYjMSnqrEzzGThH47vpCOqPPwJM2FtthLeJ8Pbg==} + peerDependencies: + react: '>=15' + react-router: '>=5' + + react-router-dom@5.3.4: + resolution: {integrity: sha512-m4EqFMHv/Ih4kpcBCONHbkT68KoAeHN4p3lAGoNryfHi0dMy0kCzEZakiKRsvg5wHZ/JLrLW8o8KomWiz/qbYQ==} + peerDependencies: + react: '>=15' + + react-router@5.3.4: + resolution: {integrity: sha512-Ys9K+ppnJah3QuaRiLxk+jDWOR1MekYQrlytiXxC1RyfbdsZkS5pvKAzCCr031xHixZwpnsYNT5xysdFHQaYsA==} + peerDependencies: + react: '>=15' + + react-style-singleton@2.2.3: + resolution: {integrity: sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + react@18.3.1: + resolution: {integrity: sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==} + engines: {node: '>=0.10.0'} + + react@19.2.3: + resolution: {integrity: sha512-Ku/hhYbVjOQnXDZFv2+RibmLFGwFdeeKHFcOTlrt7xplBnya5OGn/hIRDsqDiSUcfORsDC7MPxwork8jBwsIWA==} + engines: {node: '>=0.10.0'} + + read-cache@1.0.0: + resolution: {integrity: sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==} + + 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@3.6.0: + resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} + engines: {node: '>=8.10.0'} + + readdirp@4.1.2: + resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} + engines: {node: '>= 14.18.0'} + + real-require@0.1.0: + resolution: {integrity: sha512-r/H9MzAWtrv8aSVjPCMFpDMl5q66GqtmmRkRjpHTsp4zBAa+snZyiQNlMONiUmEJcsnaw0wCauJ2GWODr/aFkg==} + engines: {node: '>= 12.13.0'} + + rechoir@0.6.2: + resolution: {integrity: sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==} + engines: {node: '>= 0.10'} + + recma-build-jsx@1.0.0: + resolution: {integrity: sha512-8GtdyqaBcDfva+GUKDr3nev3VpKAhup1+RvkMvUxURHpW7QyIvk9F5wz7Vzo06CEMSilw6uArgRqhpiUcWp8ew==} + + recma-jsx@1.0.1: + resolution: {integrity: sha512-huSIy7VU2Z5OLv6oFLosQGGDqPqdO1iq6bWNAdhzMxSJP7RAso4fCZ1cKu8j9YHCZf3TPrq4dw3okhrylgcd7w==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + + recma-parse@1.0.0: + resolution: {integrity: sha512-OYLsIGBB5Y5wjnSnQW6t3Xg7q3fQ7FWbw/vcXtORTnyaSFscOtABg+7Pnz6YZ6c27fG1/aN8CjfwoUEUIdwqWQ==} + + recma-stringify@1.0.0: + resolution: {integrity: sha512-cjwII1MdIIVloKvC9ErQ+OgAtwHBmcZ0Bg4ciz78FtbT8In39aAYbaA7zvxQ61xVMSPE8WxhLwLbhif4Js2C+g==} + + recursive-readdir@2.2.3: + resolution: {integrity: sha512-8HrF5ZsXk5FAH9dgsx3BlUer73nIhuj+9OrQwEbLTPOBzGkL1lsFCR01am+v+0m2Cmbs1nP12hLDl5FA7EszKA==} + engines: {node: '>=6.0.0'} + + reduce-flatten@2.0.0: + resolution: {integrity: sha512-EJ4UNY/U1t2P/2k6oqotuX2Cc3T6nxJwsM0N0asT7dhrtH1ltUxDn4NalSYmPE2rCkVpcf/X6R0wDwcFpzhd4w==} + engines: {node: '>=6'} + + reflect-metadata@0.2.2: + resolution: {integrity: sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==} + + regenerate-unicode-properties@10.2.2: + resolution: {integrity: sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g==} + engines: {node: '>=4'} + + regenerate@1.4.2: + resolution: {integrity: sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==} + + regexpu-core@6.4.0: + resolution: {integrity: sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA==} + engines: {node: '>=4'} + + registry-auth-token@5.1.1: + resolution: {integrity: sha512-P7B4+jq8DeD2nMsAcdfaqHbssgHtZ7Z5+++a5ask90fvmJ8p5je4mOa+wzu+DB4vQ5tdJV/xywY+UnVFeQLV5Q==} + engines: {node: '>=14'} + + registry-url@6.0.1: + resolution: {integrity: sha512-+crtS5QjFRqFCoQmvGduwYWEBng99ZvmFvF+cUJkGYF1L1BfU8C6Zp9T7f5vPAwyLkUExpvK+ANVZmGU49qi4Q==} + engines: {node: '>=12'} + + regjsgen@0.8.0: + resolution: {integrity: sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==} + + regjsparser@0.13.0: + resolution: {integrity: sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q==} + hasBin: true + + rehype-raw@7.0.0: + resolution: {integrity: sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww==} + + rehype-recma@1.0.0: + resolution: {integrity: sha512-lqA4rGUf1JmacCNWWZx0Wv1dHqMwxzsDWYMTowuplHF3xH0N/MmrZ/G3BDZnzAkRmxDadujCjaKM2hqYdCBOGw==} + + relateurl@0.2.7: + resolution: {integrity: sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==} + engines: {node: '>= 0.10'} + + remark-directive@3.0.1: + resolution: {integrity: sha512-gwglrEQEZcZYgVyG1tQuA+h58EZfq5CSULw7J90AFuCTyib1thgHPoqQ+h9iFvU6R+vnZ5oNFQR5QKgGpk741A==} + + remark-emoji@4.0.1: + resolution: {integrity: sha512-fHdvsTR1dHkWKev9eNyhTo4EFwbUvJ8ka9SgeWkMPYFX4WoI7ViVBms3PjlQYgw5TLvNQso3GUB/b/8t3yo+dg==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + remark-frontmatter@5.0.0: + resolution: {integrity: sha512-XTFYvNASMe5iPN0719nPrdItC9aU0ssC4v14mH1BCi1u0n1gAocqcujWUrByftZTbLhRtiKRyjYTSIOcr69UVQ==} + + remark-gfm@4.0.1: + resolution: {integrity: sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==} + + remark-mdx@3.1.1: + resolution: {integrity: sha512-Pjj2IYlUY3+D8x00UJsIOg5BEvfMyeI+2uLPn9VO9Wg4MEtN/VTIq2NEJQfde9PnX15KgtHyl9S0BcTnWrIuWg==} + + remark-parse@11.0.0: + resolution: {integrity: sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==} + + remark-rehype@11.1.2: + resolution: {integrity: sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw==} + + remark-stringify@11.0.0: + resolution: {integrity: sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==} + + renderkid@3.0.0: + resolution: {integrity: sha512-q/7VIQA8lmM1hF+jn+sFSPWGlMkSAeNYcPLmDQx2zzuiDfaLrOmumR8iaUKlenFgh0XRPIUeSPlH3A+AW3Z5pg==} + + repeat-string@1.6.1: + resolution: {integrity: sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==} + engines: {node: '>=0.10'} + + req-cwd@2.0.0: + resolution: {integrity: sha512-ueoIoLo1OfB6b05COxAA9UpeoscNpYyM+BqYlA7H6LVF4hKGPXQQSSaD2YmvDVJMkk4UDpAHIeU1zG53IqjvlQ==} + engines: {node: '>=4'} + + req-from@2.0.0: + resolution: {integrity: sha512-LzTfEVDVQHBRfjOUMgNBA+V6DWsSnoeKzf42J7l0xa/B4jyPOuuF5MlNSmomLNGemWTnV2TIdjSSLnEn95fOQA==} + engines: {node: '>=4'} + + require-directory@2.1.1: + resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} + engines: {node: '>=0.10.0'} + + require-from-string@2.0.2: + resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} + engines: {node: '>=0.10.0'} + + require-like@0.1.2: + resolution: {integrity: sha512-oyrU88skkMtDdauHDuKVrgR+zuItqr6/c//FXzvmxRGMexSDc6hNvJInGW3LL46n+8b50RykrvwSUIIQH2LQ5A==} + + require-main-filename@2.0.0: + resolution: {integrity: sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==} + + requires-port@1.0.0: + resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==} + + resolve-alpn@1.2.1: + resolution: {integrity: sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==} + + resolve-from@3.0.0: + resolution: {integrity: sha512-GnlH6vxLymXJNMBo7XP1fJIzBFbdYt49CuTwmB/6N53t+kMPRMFKz783LlQ4tv28XoQfMWinAJX6WCGf2IlaIw==} + engines: {node: '>=4'} + + resolve-from@4.0.0: + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} + engines: {node: '>=4'} + + resolve-pathname@3.0.0: + resolution: {integrity: sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng==} + + resolve@1.1.7: + resolution: {integrity: sha512-9znBF0vBcaSN3W2j7wKvdERPwqTxSpCq+if5C0WoTCyV9n24rua28jeuQ2pL/HOf+yUe/Mef+H/5p60K0Id3bg==} + + resolve@1.17.0: + resolution: {integrity: sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==} + + resolve@1.22.11: + resolution: {integrity: sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==} + engines: {node: '>= 0.4'} + hasBin: true + + responselike@3.0.0: + resolution: {integrity: sha512-40yHxbNcl2+rzXvZuVkrYohathsSJlMTXKryG5y8uciHv1+xDLHQpgjG64JUO9nrEq2jGLH6IZ8BcZyw3wrweg==} + engines: {node: '>=14.16'} + + retry@0.12.0: + resolution: {integrity: sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==} + engines: {node: '>= 4'} + + retry@0.13.1: + resolution: {integrity: sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==} + engines: {node: '>= 4'} + + reusify@1.1.0: + resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + + ripemd160@2.0.3: + resolution: {integrity: sha512-5Di9UC0+8h1L6ZD2d7awM7E/T4uA1fJRlx6zk/NvdCCVEoAnFqvHmCuNeIKoCeIixBX/q8uM+6ycDvF8woqosA==} + engines: {node: '>= 0.8'} + + rlp@2.2.7: + resolution: {integrity: sha512-d5gdPmgQ0Z+AklL2NVXr/IoSjNZFfTVvQWzL/AM2AOcSzYP2xjlb0AC8YyCLc41MSNf6P6QVtjgPdmVtzb+4lQ==} + hasBin: true + + rollup@4.53.5: + resolution: {integrity: sha512-iTNAbFSlRpcHeeWu73ywU/8KuU/LZmNCSxp6fjQkJBD3ivUb8tpDrXhIxEzA05HlYMEwmtaUnb3RP+YNv162OQ==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + + rpc-websockets@9.3.2: + resolution: {integrity: sha512-VuW2xJDnl1k8n8kjbdRSWawPRkwaVqUQNjE1TdeTawf0y0abGhtVJFTXCLfgpgGDBkO/Fj6kny8Dc/nvOW78MA==} + + rtlcss@4.3.0: + resolution: {integrity: sha512-FI+pHEn7Wc4NqKXMXFM+VAYKEj/mRIcW4h24YVwVtyjI+EqGrLc2Hx/Ny0lrZ21cBWU2goLy36eqMcNj3AQJig==} + engines: {node: '>=12.0.0'} + hasBin: true + + run-applescript@7.1.0: + resolution: {integrity: sha512-DPe5pVFaAsinSaV6QjQ6gdiedWDcRCbUuiQfQa2wmWV7+xC9bGulGI8+TdRmoFkAPaBXk8CrAbnlY2ISniJ47Q==} + engines: {node: '>=18'} + + 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'} + + safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + + sax@1.4.4: + resolution: {integrity: sha512-1n3r/tGXO6b6VXMdFT54SHzT9ytu9yr7TaELowdYpMqY/Ao7EnlQGmAQ1+RatX7Tkkdm6hONI2owqNx2aZj5Sw==} + engines: {node: '>=11.0.0'} + + sc-istanbul@0.4.6: + resolution: {integrity: sha512-qJFF/8tW/zJsbyfh/iT/ZM5QNHE3CXxtLJbZsL+CzdJLBsPD7SedJZoUA4d8iAcN2IoMp/Dx80shOOd2x96X/g==} + hasBin: true + + scheduler@0.23.2: + resolution: {integrity: sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==} + + scheduler@0.27.0: + resolution: {integrity: sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==} + + schema-dts@1.1.5: + resolution: {integrity: sha512-RJr9EaCmsLzBX2NDiO5Z3ux2BVosNZN5jo0gWgsyKvxKIUL5R3swNvoorulAeL9kLB0iTSX7V6aokhla2m7xbg==} + + schema-utils@3.3.0: + resolution: {integrity: sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==} + engines: {node: '>= 10.13.0'} + + schema-utils@4.3.3: + resolution: {integrity: sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA==} + engines: {node: '>= 10.13.0'} + + scrypt-js@3.0.1: + resolution: {integrity: sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==} + + secp256k1@4.0.4: + resolution: {integrity: sha512-6JfvwvjUOn8F/jUoBY2Q1v5WY5XS+rj8qSe0v8Y4ezH4InLgTEeOOPQsRll9OV429Pvo6BCHGavIyJfr3TAhsw==} + engines: {node: '>=18.0.0'} + + section-matter@1.0.0: + resolution: {integrity: sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==} + engines: {node: '>=4'} + + select-hose@2.0.0: + resolution: {integrity: sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==} + + selfsigned@5.5.0: + resolution: {integrity: sha512-ftnu3TW4+3eBfLRFnDEkzGxSF/10BJBkaLJuBHZX0kiPS7bRdlpZGu6YGt4KngMkdTwJE6MbjavFpqHvqVt+Ew==} + engines: {node: '>=18'} + + semver-diff@4.0.0: + resolution: {integrity: sha512-0Ju4+6A8iOnpL/Thra7dZsSlOHYAHIeMxfhWQRI1/VLcT3WDBZKKtQt/QkBOsiIN9ZpuvHE6cGZ0x4glCMmfiA==} + engines: {node: '>=12'} + + semver@5.7.2: + resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==} + hasBin: true + + semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + hasBin: true + + semver@7.7.3: + resolution: {integrity: sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==} + engines: {node: '>=10'} + hasBin: true + + send@0.19.2: + resolution: {integrity: sha512-VMbMxbDeehAxpOtWJXlcUS5E8iXh6QmN+BkRX1GARS3wRaXEEgzCcB10gTQazO42tpNIya8xIyNx8fll1OFPrg==} + engines: {node: '>= 0.8.0'} + + serialize-javascript@6.0.2: + resolution: {integrity: sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==} + + serve-handler@6.1.6: + resolution: {integrity: sha512-x5RL9Y2p5+Sh3D38Fh9i/iQ5ZK+e4xuXRd/pGbM4D13tgo/MGwbttUk8emytcr1YYzBYs+apnUngBDFYfpjPuQ==} + + serve-index@1.9.1: + resolution: {integrity: sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==} + engines: {node: '>= 0.8.0'} + + serve-static@1.16.3: + resolution: {integrity: sha512-x0RTqQel6g5SY7Lg6ZreMmsOzncHFU7nhnRWkKgWuMTu5NN0DR5oruckMqRvacAN9d5w6ARnRBXl9xhDCgfMeA==} + engines: {node: '>= 0.8.0'} + + 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'} + + setimmediate@1.0.5: + resolution: {integrity: sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==} + + setprototypeof@1.1.0: + resolution: {integrity: sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==} + + setprototypeof@1.2.0: + resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} + + sha.js@2.4.12: + resolution: {integrity: sha512-8LzC5+bvI45BjpfXU8V5fdU2mfeKiQe1D1gIMn7XUlF3OTUrpdJpPPH4EMAnF0DsHHdSZqCdSss5qCmJKuiO3w==} + engines: {node: '>= 0.10'} + hasBin: true + + sha1@1.1.1: + resolution: {integrity: sha512-dZBS6OrMjtgVkopB1Gmo4RQCDKiZsqcpAQpkV/aaj+FCrCg8r4I4qMkDPQjBgLIxlmu9k4nUbWq6ohXahOneYA==} + + shallow-clone@3.0.1: + resolution: {integrity: sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==} + engines: {node: '>=8'} + + 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'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + shell-quote@1.8.3: + resolution: {integrity: sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==} + engines: {node: '>= 0.4'} + + shelljs@0.8.5: + resolution: {integrity: sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==} + engines: {node: '>=4'} + hasBin: true + + side-channel-list@1.0.0: + resolution: {integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==} + engines: {node: '>= 0.4'} + + side-channel-map@1.0.1: + resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==} + engines: {node: '>= 0.4'} + + side-channel-weakmap@1.0.2: + resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==} + engines: {node: '>= 0.4'} + + side-channel@1.1.0: + resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==} + engines: {node: '>= 0.4'} + + siginfo@2.0.0: + resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} + + signal-exit@3.0.7: + resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + + sirv@2.0.4: + resolution: {integrity: sha512-94Bdh3cC2PKrbgSOUqTiGPWVZeSiXfKOVZNJniWoqrWrRkB1CJzBU3NEbiTsPcYy1lDsANA/THzS+9WBiy5nfQ==} + engines: {node: '>= 10'} + + sisteransi@1.0.5: + resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} + + sitemap@7.1.2: + resolution: {integrity: sha512-ARCqzHJ0p4gWt+j7NlU5eDlIO9+Rkr/JhPFZKKQ1l5GCus7rJH4UdrlVAh0xC/gDS/Qir2UMxqYNHtsKr2rpCw==} + engines: {node: '>=12.0.0', npm: '>=5.6.0'} + hasBin: true + + skin-tone@2.0.0: + resolution: {integrity: sha512-kUMbT1oBJCpgrnKoSr0o6wPtvRWT9W9UKvGLwfJYO2WuahZRHOpEyL1ckyMGgMWh0UdpmaoFqKKD29WTomNEGA==} + engines: {node: '>=8'} + + slash@3.0.0: + resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} + engines: {node: '>=8'} + + slash@4.0.0: + resolution: {integrity: sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==} + engines: {node: '>=12'} + + slice-ansi@4.0.0: + resolution: {integrity: sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==} + engines: {node: '>=10'} + + snake-case@3.0.4: + resolution: {integrity: sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==} + + socket.io-client@4.8.1: + resolution: {integrity: sha512-hJVXfu3E28NmzGk8o1sHhN3om52tRvwYeidbj7xKy2eIIse5IoKX3USlS6Tqt3BHAtflLIkCQBkzVrEEfWUyYQ==} + engines: {node: '>=10.0.0'} + + socket.io-parser@4.2.4: + resolution: {integrity: sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==} + engines: {node: '>=10.0.0'} + + sockjs@0.3.24: + resolution: {integrity: sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==} + + solc@0.8.26: + resolution: {integrity: sha512-yiPQNVf5rBFHwN6SIf3TUUvVAFKcQqmSUFeq+fb6pNRCo0ZCgpYOZDi3BVoezCPIAcKrVYd/qXlBLUP9wVrZ9g==} + engines: {node: '>=10.0.0'} + hasBin: true + + solidity-ast@0.4.61: + resolution: {integrity: sha512-OYBJYcYyG7gLV0VuXl9CUrvgJXjV/v0XnR4+1YomVe3q+QyENQXJJxAEASUz4vN6lMAl+C8RSRSr5MBAz09f6w==} + + solidity-coverage@0.8.17: + resolution: {integrity: sha512-5P8vnB6qVX9tt1MfuONtCTEaEGO/O4WuEidPHIAJjx4sktHHKhO3rFvnE0q8L30nWJPTrcqGQMT7jpE29B2qow==} + hasBin: true + peerDependencies: + hardhat: ^2.11.0 + + sonic-boom@2.8.0: + resolution: {integrity: sha512-kuonw1YOYYNOve5iHdSahXPOK49GqwA+LZhI6Wz/l0rP57iKyXXIHaRagOBHAPmGwJC6od2Z9zgvZ5loSgMlVg==} + + sort-css-media-queries@2.2.0: + resolution: {integrity: sha512-0xtkGhWCC9MGt/EzgnvbbbKhqWjl1+/rncmhTh5qCpbYguXh6S/qwePfv/JQ8jePXXmqingylxoC49pCkSPIbA==} + engines: {node: '>= 6.3.0'} + + source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} + engines: {node: '>=0.10.0'} + + source-map-support@0.5.21: + resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} + + source-map@0.2.0: + resolution: {integrity: sha512-CBdZ2oa/BHhS4xj5DlhjWNHcan57/5YuvfdLf17iVmIpd9KRm+DFLmC6nBNj+6Ua7Kt3TmOjDpQT1aTYOQtoUA==} + engines: {node: '>=0.8.0'} + + source-map@0.6.1: + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + engines: {node: '>=0.10.0'} + + source-map@0.7.6: + resolution: {integrity: sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==} + engines: {node: '>= 12'} + + space-separated-tokens@2.0.2: + resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==} + + spdy-transport@3.0.0: + resolution: {integrity: sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==} + + spdy@4.0.2: + resolution: {integrity: sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==} + engines: {node: '>=6.0.0'} + + split-on-first@1.1.0: + resolution: {integrity: sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw==} + engines: {node: '>=6'} + + split2@3.2.2: + resolution: {integrity: sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==} + + split2@4.2.0: + resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==} + engines: {node: '>= 10.x'} + + sprintf-js@1.0.3: + resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} + + srcset@4.0.0: + resolution: {integrity: sha512-wvLeHgcVHKO8Sc/H/5lkGreJQVeYMm9rlmt8PuR1xE31rIuXhuzznUUqAt8MqLhB3MqJdFzlNAfpcWnxiFUcPw==} + engines: {node: '>=12'} + + stackback@0.0.2: + resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} + + stacktrace-parser@0.1.11: + resolution: {integrity: sha512-WjlahMgHmCJpqzU8bIBy4qtsZdU9lRlcZE3Lvyej6t4tuOuv1vk57OW3MBrj6hXBFx/nNoC9MPMTcr5YA7NQbg==} + engines: {node: '>=6'} + + statuses@1.5.0: + resolution: {integrity: sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==} + engines: {node: '>= 0.6'} + + statuses@2.0.2: + resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==} + engines: {node: '>= 0.8'} + + std-env@3.10.0: + resolution: {integrity: sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==} + + stream-chain@2.2.5: + resolution: {integrity: sha512-1TJmBx6aSWqZ4tx7aTpBDXK0/e2hhcNSTV8+CbFJtDjbb+I1mZ8lHit0Grw9GRT+6JbIrrDd8esncgBi8aBXGA==} + + stream-json@1.9.1: + resolution: {integrity: sha512-uWkjJ+2Nt/LO9Z/JyKZbMusL8Dkh97uUBTv3AJQ74y07lVahLY4eEFsPsE97pxYBwr8nnjMAIch5eqI0gPShyw==} + + stream-shift@1.0.3: + resolution: {integrity: sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ==} + + strict-uri-encode@2.0.0: + resolution: {integrity: sha512-QwiXZgpRcKkhTj2Scnn++4PKtWsH0kpzZ62L2R6c/LUVYv7hVnZqcg2+sMuT6R7Jusu1vviK/MFsu6kNJfWlEQ==} + engines: {node: '>=4'} + + string-format@2.0.0: + resolution: {integrity: sha512-bbEs3scLeYNXLecRRuk6uJxdXUSj6le/8rNPHChIJTn2V79aXVTR1EH2OH5zLKKoz0V02fOUKZZcw01pLUShZA==} + + string-width@2.1.1: + resolution: {integrity: sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==} + engines: {node: '>=4'} + + string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + + string-width@5.1.2: + resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} + engines: {node: '>=12'} + + 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==} + + stringify-entities@4.0.4: + resolution: {integrity: sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==} + + stringify-object@3.3.0: + resolution: {integrity: sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==} + engines: {node: '>=4'} + + strip-ansi@4.0.0: + resolution: {integrity: sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==} + engines: {node: '>=4'} + + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + + strip-ansi@7.1.2: + resolution: {integrity: sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==} + engines: {node: '>=12'} + + strip-bom-string@1.0.0: + resolution: {integrity: sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==} + engines: {node: '>=0.10.0'} + + strip-final-newline@2.0.0: + resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} + engines: {node: '>=6'} + + strip-hex-prefix@1.0.0: + resolution: {integrity: sha512-q8d4ue7JGEiVcypji1bALTos+0pWtyGlivAWyPuTkHzuTCJqrK9sWxYQZUq6Nq3cuyv3bm734IhHvHtGGURU6A==} + engines: {node: '>=6.5.0', npm: '>=3'} + + strip-json-comments@2.0.1: + resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==} + engines: {node: '>=0.10.0'} + + strip-json-comments@3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + + strip-literal@3.1.0: + resolution: {integrity: sha512-8r3mkIM/2+PpjHoOtiAW8Rg3jJLHaV7xPwG+YRGrv6FP0wwk/toTpATxWYOW0BKdWwl82VT2tFYi5DlROa0Mxg==} + + strnum@2.1.2: + resolution: {integrity: sha512-l63NF9y/cLROq/yqKXSLtcMeeyOfnSQlfMSlzFt/K73oIaD8DGaQWd7Z34X9GPiKqP5rbSh84Hl4bOlLcjiSrQ==} + + style-to-js@1.1.21: + resolution: {integrity: sha512-RjQetxJrrUJLQPHbLku6U/ocGtzyjbJMP9lCNK7Ag0CNh690nSH8woqWH9u16nMjYBAok+i7JO1NP2pOy8IsPQ==} + + style-to-object@1.0.14: + resolution: {integrity: sha512-LIN7rULI0jBscWQYaSswptyderlarFkjQ+t79nzty8tcIAceVomEVlLzH5VP4Cmsv6MtKhs7qaAiwlcp+Mgaxw==} + + stylehacks@6.1.1: + resolution: {integrity: sha512-gSTTEQ670cJNoaeIp9KX6lZmm8LJ3jPB5yJmX8Zq/wQxOsAFXV3qjWzHas3YYk1qesuVIyYWWUpZ0vSE/dTSGg==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + 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@3.2.3: + resolution: {integrity: sha512-Jds2VIYDrlp5ui7t8abHN2bjAu4LV/q4N2KivFPpGH0lrka0BMq/33AmECUXlKPcHigkNaqfXRENFju+rlcy+A==} + engines: {node: '>=0.8.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'} + + supports-color@8.1.1: + resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} + engines: {node: '>=10'} + + supports-preserve-symlinks-flag@1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + + svg-parser@2.0.4: + resolution: {integrity: sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==} + + svgo@3.3.2: + resolution: {integrity: sha512-OoohrmuUlBs8B8o6MB2Aevn+pRIH9zDALSR+6hhqVfa6fRwG/Qw9VUMSMW9VNg2CFc/MTIfabtdOVl9ODIJjpw==} + engines: {node: '>=14.0.0'} + hasBin: true + + sync-request@6.1.0: + resolution: {integrity: sha512-8fjNkrNlNCrVc/av+Jn+xxqfCjYaBoHqCsDz6mt030UMxJGr+GSfCV1dQt2gRtlL63+VPidwDVLr7V2OcTSdRw==} + engines: {node: '>=8.0.0'} + + sync-rpc@1.3.6: + resolution: {integrity: sha512-J8jTXuZzRlvU7HemDgHi3pGnh/rkoqR/OZSjhTyyZrEkkYQbk7Z33AXp37mkPfPpfdOuj7Ex3H/TJM1z48uPQw==} + + table-layout@1.0.2: + resolution: {integrity: sha512-qd/R7n5rQTRFi+Zf2sk5XVVd9UQl6ZkduPFC3S7WEGJAmetDTjY3qPN50eSKzwuzEyQKy5TN2TiZdkIjos2L6A==} + engines: {node: '>=8.0.0'} + + table@6.9.0: + resolution: {integrity: sha512-9kY+CygyYM6j02t5YFHbNz2FN5QmYGv9zAjVp4lCDjlCw7amdckXlEt/bjMhUIfj4ThGRE4gCUH5+yGnNuPo5A==} + engines: {node: '>=10.0.0'} + + tailwindcss@3.4.19: + resolution: {integrity: sha512-3ofp+LL8E+pK/JuPLPggVAIaEuhvIz4qNcf3nA1Xn2o/7fb7s/TYpHhwGDv1ZU3PkBluUVaF8PyCHcm48cKLWQ==} + engines: {node: '>=14.0.0'} + hasBin: true + + tapable@2.3.0: + resolution: {integrity: sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==} + engines: {node: '>=6'} + + terser-webpack-plugin@5.3.16: + resolution: {integrity: sha512-h9oBFCWrq78NyWWVcSwZarJkZ01c2AyGrzs1crmHZO3QUg9D61Wu4NPjBy69n7JqylFF5y+CsUZYmYEIZ3mR+Q==} + engines: {node: '>= 10.13.0'} + peerDependencies: + '@swc/core': '*' + esbuild: '*' + uglify-js: '*' + webpack: ^5.1.0 + peerDependenciesMeta: + '@swc/core': + optional: true + esbuild: + optional: true + uglify-js: + optional: true + + terser@5.46.0: + resolution: {integrity: sha512-jTwoImyr/QbOWFFso3YoU3ik0jBBDJ6JTOQiy/J2YxVJdZCc+5u7skhNwiOR3FQIygFqVUPHl7qbbxtjW2K3Qg==} + engines: {node: '>=10'} + hasBin: true + + text-encoding-utf-8@1.0.2: + resolution: {integrity: sha512-8bw4MY9WjdsD2aMtO0OzOCY3pXGYNx2d2FfHRVUKkiCPDWjKuOlhLVASS+pD7VkLTVjW268LYJHwsnPFlBpbAg==} + + then-request@6.0.2: + resolution: {integrity: sha512-3ZBiG7JvP3wbDzA9iNY5zJQcHL4jn/0BWtXIkagfz7QgOL/LqjCEOBQuJNZfu0XYnv5JhKh+cDxCPM4ILrqruA==} + engines: {node: '>=6.0.0'} + + thenify-all@1.6.0: + resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} + engines: {node: '>=0.8'} + + thenify@3.3.1: + resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} + + thingies@2.5.0: + resolution: {integrity: sha512-s+2Bwztg6PhWUD7XMfeYm5qliDdSiZm7M7n8KjTkIsm3l/2lgVRc2/Gx/v+ZX8lT4FMA+i8aQvhcWylldc+ZNw==} + engines: {node: '>=10.18'} + peerDependencies: + tslib: ^2 + + thread-stream@0.15.2: + resolution: {integrity: sha512-UkEhKIg2pD+fjkHQKyJO3yoIvAP3N6RlNFt2dUhcS1FGvCD1cQa1M/PGknCLFIyZdtJOWQjejp7bdNqmN7zwdA==} + + through2@4.0.2: + resolution: {integrity: sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==} + + thunky@1.1.0: + resolution: {integrity: sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==} + + tiny-invariant@1.3.3: + resolution: {integrity: sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==} + + tiny-warning@1.0.3: + resolution: {integrity: sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==} + + tinybench@2.9.0: + resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} + + tinyexec@0.3.2: + resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==} + + tinyglobby@0.2.15: + resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} + engines: {node: '>=12.0.0'} + + tinypool@1.1.1: + resolution: {integrity: sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg==} + engines: {node: ^18.0.0 || >=20.0.0} + + tinyrainbow@2.0.0: + resolution: {integrity: sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==} + engines: {node: '>=14.0.0'} + + tinyspy@4.0.4: + resolution: {integrity: sha512-azl+t0z7pw/z958Gy9svOTuzqIk6xq+NSheJzn5MMWtWTFywIacg2wUlzKFGtt3cthx0r2SxMK0yzJOR0IES7Q==} + engines: {node: '>=14.0.0'} + + tmp@0.0.33: + resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==} + engines: {node: '>=0.6.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'} + + toidentifier@1.0.1: + resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} + engines: {node: '>=0.6'} + + totalist@3.0.1: + resolution: {integrity: sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==} + engines: {node: '>=6'} + + tr46@0.0.3: + resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} + + tree-dump@1.1.0: + resolution: {integrity: sha512-rMuvhU4MCDbcbnleZTFezWsaZXRFemSqAM+7jPnzUl1fo9w3YEKOxAeui0fz3OI4EU4hf23iyA7uQRVko+UaBA==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + trim-lines@3.0.1: + resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==} + + trough@2.2.0: + resolution: {integrity: sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==} + + ts-command-line-args@2.5.1: + resolution: {integrity: sha512-H69ZwTw3rFHb5WYpQya40YAX2/w7Ut75uUECbgBIsLmM+BNuYnxsltfyyLMxy6sEeKxgijLTnQtLd0nKd6+IYw==} + hasBin: true + + ts-essentials@7.0.3: + resolution: {integrity: sha512-8+gr5+lqO3G84KdiTSMRLtuyJ+nTBVRKuCrK4lidMPdVeEp0uqC875uE5NMcaA7YYMN7XsNiFQuMvasF8HT/xQ==} + peerDependencies: + typescript: '>=3.7.0' + + ts-interface-checker@0.1.13: + resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} + + ts-node@10.9.2: + resolution: {integrity: sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==} + hasBin: true + peerDependencies: + '@swc/core': '>=1.2.50' + '@swc/wasm': '>=1.2.50' + '@types/node': '*' + typescript: '>=2.7' + peerDependenciesMeta: + '@swc/core': + optional: true + '@swc/wasm': + optional: true + + tslib@1.14.1: + resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} + + tslib@2.7.0: + resolution: {integrity: sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==} + + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + + tsort@0.0.1: + resolution: {integrity: sha512-Tyrf5mxF8Ofs1tNoxA13lFeZ2Zrbd6cKbuH3V+MQ5sb6DtBj5FjrXVsRWT8YvNAQTqNoz66dz1WsbigI22aEnw==} + + tsyringe@4.10.0: + resolution: {integrity: sha512-axr3IdNuVIxnaK5XGEUFTu3YmAQ6lllgrvqfEoR16g/HGnYY/6We4oWENtAnzK6/LpJ2ur9PAb80RBt7/U4ugw==} + engines: {node: '>= 6.0.0'} + + tweetnacl@1.0.3: + resolution: {integrity: sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==} + + type-check@0.3.2: + resolution: {integrity: sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==} + engines: {node: '>= 0.8.0'} + + type-detect@4.1.0: + resolution: {integrity: sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==} + engines: {node: '>=4'} + + type-fest@0.20.2: + resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} + engines: {node: '>=10'} + + type-fest@0.21.3: + resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} + engines: {node: '>=10'} + + type-fest@0.7.1: + resolution: {integrity: sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg==} + engines: {node: '>=8'} + + type-fest@1.4.0: + resolution: {integrity: sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==} + engines: {node: '>=10'} + + type-fest@2.19.0: + resolution: {integrity: sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==} + engines: {node: '>=12.20'} + + type-is@1.6.18: + resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} + engines: {node: '>= 0.6'} + + typechain@8.3.2: + resolution: {integrity: sha512-x/sQYr5w9K7yv3es7jo4KTX05CLxOf7TRWwoHlrjRh8H82G64g+k7VuWPJlgMo6qrjfCulOdfBjiaDtmhFYD/Q==} + hasBin: true + peerDependencies: + typescript: '>=4.3.0' + + typed-array-buffer@1.0.3: + resolution: {integrity: sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==} + engines: {node: '>= 0.4'} + + typedarray-to-buffer@3.1.5: + resolution: {integrity: sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==} + + typedarray@0.0.6: + resolution: {integrity: sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==} + + typescript@5.6.3: + resolution: {integrity: sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==} + engines: {node: '>=14.17'} + hasBin: true + + typical@4.0.0: + resolution: {integrity: sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw==} + engines: {node: '>=8'} + + typical@5.2.0: + resolution: {integrity: sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg==} + engines: {node: '>=8'} + + ua-parser-js@1.0.41: + resolution: {integrity: sha512-LbBDqdIC5s8iROCUjMbW1f5dJQTEFB1+KO9ogbvlb3nm9n4YHa5p4KTvFPWvh2Hs8gZMBuiB1/8+pdfe/tDPug==} + hasBin: true + + ufo@1.6.1: + resolution: {integrity: sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==} + + uglify-js@3.19.3: + resolution: {integrity: sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==} + engines: {node: '>=0.8.0'} + hasBin: true + + 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==} + + undici-types@6.21.0: + resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} + + undici-types@7.16.0: + resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==} + + undici@5.29.0: + resolution: {integrity: sha512-raqeBD6NQK4SkWhQzeYKd1KmIG6dllBOTt55Rmkt4HtI9mwdWtJljnrXjAFUBLTSN67HWrOIZ3EPF4kjUw80Bg==} + engines: {node: '>=14.0'} + + undici@6.22.0: + resolution: {integrity: sha512-hU/10obOIu62MGYjdskASR3CUAiYaFTtC9Pa6vHyf//mAipSvSQg6od2CnJswq7fvzNS3zJhxoRkgNVaHurWKw==} + engines: {node: '>=18.17'} + + unfetch@4.2.0: + resolution: {integrity: sha512-F9p7yYCn6cIW9El1zi0HI6vqpeIvBsr3dSuRO6Xuppb1u5rXpCPmMvLSyECLhybr9isec8Ohl0hPekMVrEinDA==} + + unicode-canonical-property-names-ecmascript@2.0.1: + resolution: {integrity: sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==} + engines: {node: '>=4'} + + unicode-emoji-modifier-base@1.0.0: + resolution: {integrity: sha512-yLSH4py7oFH3oG/9K+XWrz1pSi3dfUrWEnInbxMfArOfc1+33BlGPQtLsOYwvdMy11AwUBetYuaRxSPqgkq+8g==} + engines: {node: '>=4'} + + unicode-match-property-ecmascript@2.0.0: + resolution: {integrity: sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==} + engines: {node: '>=4'} + + unicode-match-property-value-ecmascript@2.2.1: + resolution: {integrity: sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg==} + engines: {node: '>=4'} + + unicode-property-aliases-ecmascript@2.2.0: + resolution: {integrity: sha512-hpbDzxUY9BFwX+UeBnxv3Sh1q7HFxj48DTmXchNgRa46lO8uj3/1iEn3MiNUYTg1g9ctIqXCCERn8gYZhHC5lQ==} + engines: {node: '>=4'} + + unified@11.0.5: + resolution: {integrity: sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==} + + unique-string@3.0.0: + resolution: {integrity: sha512-VGXBUVwxKMBUznyffQweQABPRRW1vHZAbadFZud4pLFAqRGvv/96vafgjWFqzourzr8YonlQiPgH0YCJfawoGQ==} + engines: {node: '>=12'} + + unist-util-is@6.0.1: + resolution: {integrity: sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g==} + + unist-util-position-from-estree@2.0.0: + resolution: {integrity: sha512-KaFVRjoqLyF6YXCbVLNad/eS4+OfPQQn2yOd7zF/h5T/CSL2v8NpN6a5TPvtbXthAGw5nG+PuTtq+DdIZr+cRQ==} + + unist-util-position@5.0.0: + resolution: {integrity: sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==} + + unist-util-stringify-position@4.0.0: + resolution: {integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==} + + unist-util-visit-parents@6.0.2: + resolution: {integrity: sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ==} + + unist-util-visit@5.0.0: + resolution: {integrity: sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==} + + universalify@0.1.2: + resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} + engines: {node: '>= 4.0.0'} + + universalify@2.0.1: + resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} + engines: {node: '>= 10.0.0'} + + unpipe@1.0.0: + resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} + engines: {node: '>= 0.8'} + + unstorage@1.17.3: + resolution: {integrity: sha512-i+JYyy0DoKmQ3FximTHbGadmIYb8JEpq7lxUjnjeB702bCPum0vzo6oy5Mfu0lpqISw7hCyMW2yj4nWC8bqJ3Q==} + 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.0.3 || ^7.0.0 + '@deno/kv': '>=0.9.0' + '@netlify/blobs': ^6.5.0 || ^7.0.0 || ^8.1.0 || ^9.0.0 || ^10.0.0 + '@planetscale/database': ^1.19.0 + '@upstash/redis': ^1.34.3 + '@vercel/blob': '>=0.27.1' + '@vercel/functions': ^2.2.12 || ^3.0.0 + '@vercel/kv': ^1.0.1 + aws4fetch: ^1.0.20 + db0: '>=0.2.1' + 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 + peerDependencies: + browserslist: '>= 4.21.0' + + update-notifier@6.0.2: + resolution: {integrity: sha512-EDxhTEVPZZRLWYcJ4ZXjGFN0oP7qYvbXWzEgRm/Yql4dHX5wDbvh89YHP6PK1lzZJYrMtXUuZZz8XGK+U6U1og==} + engines: {node: '>=14.16'} + + uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + + url-loader@4.1.1: + resolution: {integrity: sha512-3BTV812+AVHHOJQO8O5MkWgZ5aosP7GnROJwvzLS9hWDj00lZ6Z0wNak423Lp9PBZN05N+Jk/N5Si8jRAlGyWA==} + engines: {node: '>= 10.13.0'} + peerDependencies: + file-loader: '*' + webpack: ^4.0.0 || ^5.0.0 + peerDependenciesMeta: + file-loader: + optional: true + + use-callback-ref@1.3.3: + resolution: {integrity: sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + use-sidecar@1.1.3: + resolution: {integrity: sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + use-sync-external-store@1.2.0: + resolution: {integrity: sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==} + 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'} + + utf8@3.0.0: + resolution: {integrity: sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ==} + + util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + + util@0.12.5: + resolution: {integrity: sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==} + + utila@0.4.0: + resolution: {integrity: sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA==} + + utility-types@3.11.0: + resolution: {integrity: sha512-6Z7Ma2aVEWisaL6TvBCy7P8rm2LQoPv6dJ7ecIaIixHcwfbJ0x7mWdbcwlIM5IGQxPZSFYeqRCqlOOeKoJYMkw==} + engines: {node: '>= 4'} + + utils-merge@1.0.1: + resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==} + engines: {node: '>= 0.4.0'} + + 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 + + v8-compile-cache-lib@3.0.1: + resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} + + valtio@1.13.2: + resolution: {integrity: sha512-Qik0o+DSy741TmkqmRfjq+0xpZBXi/Y6+fXZLn0xNF1z/waFMbE3rkivv5Zcf9RrMUp6zswf2J7sbh2KBlba5A==} + engines: {node: '>=12.20.0'} + peerDependencies: + '@types/react': '>=16.8' + react: '>=16.8' + peerDependenciesMeta: + '@types/react': + optional: true + react: + optional: true + + value-equal@1.0.1: + resolution: {integrity: sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw==} + + vary@1.1.2: + resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} + engines: {node: '>= 0.8'} + + vfile-location@5.0.3: + resolution: {integrity: sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg==} + + vfile-message@4.0.3: + resolution: {integrity: sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==} + + vfile@6.0.3: + resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==} + + viem@2.23.2: + resolution: {integrity: sha512-NVmW/E0c5crMOtbEAqMF0e3NmvQykFXhLOc/CkLIXOlzHSA6KXVz3CYVmaKqBF8/xtjsjHAGjdJN3Ru1kFJLaA==} + peerDependencies: + typescript: '>=5.0.4' + peerDependenciesMeta: + typescript: + optional: true + + viem@2.43.1: + resolution: {integrity: sha512-S33pBNlRvOlVv4+L94Z8ydCMDB1j0cuHFUvaC28i6OTxw3uY1P4M3h1YDFK8YC1H9/lIbeBTTvCRhi0FqU/2iw==} + peerDependencies: + typescript: '>=5.0.4' + peerDependenciesMeta: + typescript: + optional: true + + vite-node@3.2.4: + resolution: {integrity: sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg==} + engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} + hasBin: true + + vite-plugin-wasm@3.5.0: + resolution: {integrity: sha512-X5VWgCnqiQEGb+omhlBVsvTfxikKtoOgAzQ95+BZ8gQ+VfMHIjSHr0wyvXFQCa0eKQ0fKyaL0kWcEnYqBac4lQ==} + peerDependencies: + vite: ^2 || ^3 || ^4 || ^5 || ^6 || ^7 + + vite@5.4.21: + resolution: {integrity: sha512-o5a9xKjbtuhY6Bi5S3+HvbRERmouabWbyUcpXXUA1u+GNUKoROi9byOJ8M0nHbHYHkYICiMlqxkg1KkYmm25Sw==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@types/node': ^18.0.0 || >=20.0.0 + less: '*' + lightningcss: ^1.21.0 + sass: '*' + sass-embedded: '*' + stylus: '*' + sugarss: '*' + terser: ^5.4.0 + peerDependenciesMeta: + '@types/node': + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + + vitest@3.2.4: + resolution: {integrity: sha512-LUCP5ev3GURDysTWiP47wRRUpLKMOfPh+yKTx3kVIEiu5KOMeqzpnYNsKyOoVrULivR8tLcks4+lga33Whn90A==} + engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} + hasBin: true + peerDependencies: + '@edge-runtime/vm': '*' + '@types/debug': ^4.1.12 + '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0 + '@vitest/browser': 3.2.4 + '@vitest/ui': 3.2.4 + happy-dom: '*' + jsdom: '*' + peerDependenciesMeta: + '@edge-runtime/vm': + optional: true + '@types/debug': + optional: true + '@types/node': + optional: true + '@vitest/browser': + optional: true + '@vitest/ui': + optional: true + happy-dom: + optional: true + jsdom: + optional: true + + 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 + + watchpack@2.5.1: + resolution: {integrity: sha512-Zn5uXdcFNIA1+1Ei5McRd+iRzfhENPCe7LeABkJtNulSxjma+l7ltNx55BWZkRlwRnpOgHqxnjyaDgJnNXnqzg==} + engines: {node: '>=10.13.0'} + + wbuf@1.7.3: + resolution: {integrity: sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==} + + web-namespaces@2.0.1: + resolution: {integrity: sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==} + + web3-utils@1.10.4: + resolution: {integrity: sha512-tsu8FiKJLk2PzhDl9fXbGUWTkkVXYhtTA+SmEFkKft+9BgwLxfCRpU96sWv7ICC8zixBNd3JURVoiR3dUXgP8A==} + engines: {node: '>=8.0.0'} + + webextension-polyfill@0.10.0: + resolution: {integrity: sha512-c5s35LgVa5tFaHhrZDnr3FpQpjj1BB+RXhLTYUxGqBVN460HkbM8TBtEqdXWbpTKfzwCcjAZVF7zXCYSKtcp9g==} + + webidl-conversions@3.0.1: + resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} + + webpack-bundle-analyzer@4.10.2: + resolution: {integrity: sha512-vJptkMm9pk5si4Bv922ZbKLV8UTT4zib4FPgXMhgzUny0bfDDkLXAVQs3ly3fS4/TN9ROFtb0NFrm04UXFE/Vw==} + engines: {node: '>= 10.13.0'} + hasBin: true + + webpack-dev-middleware@7.4.5: + resolution: {integrity: sha512-uxQ6YqGdE4hgDKNf7hUiPXOdtkXvBJXrfEGYSx7P7LC8hnUYGK70X6xQXUvXeNyBDDcsiQXpG2m3G9vxowaEuA==} + engines: {node: '>= 18.12.0'} + peerDependencies: + webpack: ^5.0.0 + peerDependenciesMeta: + webpack: + optional: true + + webpack-dev-server@5.2.3: + resolution: {integrity: sha512-9Gyu2F7+bg4Vv+pjbovuYDhHX+mqdqITykfzdM9UyKqKHlsE5aAjRhR+oOEfXW5vBeu8tarzlJFIZva4ZjAdrQ==} + engines: {node: '>= 18.12.0'} + hasBin: true + peerDependencies: + webpack: ^5.0.0 + webpack-cli: '*' + peerDependenciesMeta: + webpack: + optional: true + webpack-cli: + optional: true + + webpack-merge@5.10.0: + resolution: {integrity: sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA==} + engines: {node: '>=10.0.0'} + + webpack-merge@6.0.1: + resolution: {integrity: sha512-hXXvrjtx2PLYx4qruKl+kyRSLc52V+cCvMxRjmKwoA+CBbbF5GfIBtR6kCvl0fYGqTUPKB+1ktVmTHqMOzgCBg==} + engines: {node: '>=18.0.0'} + + webpack-sources@3.3.3: + resolution: {integrity: sha512-yd1RBzSGanHkitROoPFd6qsrxt+oFhg/129YzheDGqeustzX0vTZJZsSsQjVQC4yzBQ56K55XU8gaNCtIzOnTg==} + engines: {node: '>=10.13.0'} + + webpack@5.104.1: + resolution: {integrity: sha512-Qphch25abbMNtekmEGJmeRUhLDbe+QfiWTiqpKYkpCOWY64v9eyl+KRRLmqOFA2AvKPpc9DC6+u2n76tQLBoaA==} + engines: {node: '>=10.13.0'} + hasBin: true + peerDependencies: + webpack-cli: '*' + peerDependenciesMeta: + webpack-cli: + optional: true + + webpackbar@6.0.1: + resolution: {integrity: sha512-TnErZpmuKdwWBdMoexjio3KKX6ZtoKHRVvLIU0A47R0VVBDtx3ZyOJDktgYixhoJokZTYTt1Z37OkO9pnGJa9Q==} + engines: {node: '>=14.21.3'} + peerDependencies: + webpack: 3 || 4 || 5 + + websocket-driver@0.7.4: + resolution: {integrity: sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==} + engines: {node: '>=0.8.0'} + + websocket-extensions@0.1.4: + resolution: {integrity: sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==} + engines: {node: '>=0.8.0'} + + 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.19: + resolution: {integrity: sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==} + engines: {node: '>= 0.4'} + + which@1.3.1: + resolution: {integrity: sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==} + hasBin: true + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + why-is-node-running@2.3.0: + resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==} + engines: {node: '>=8'} + hasBin: true + + widest-line@3.1.0: + resolution: {integrity: sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==} + engines: {node: '>=8'} + + widest-line@4.0.1: + resolution: {integrity: sha512-o0cyEG0e8GPzT4iGHphIOh0cJOV8fivsXxddQasHPHfoZf1ZexrfeA21w2NaEN1RHE+fXlfISmOE8R9N3u3Qig==} + engines: {node: '>=12'} + + wildcard@2.0.1: + resolution: {integrity: sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==} + + word-wrap@1.2.5: + resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} + engines: {node: '>=0.10.0'} + + wordwrap@1.0.0: + resolution: {integrity: sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==} + + wordwrapjs@4.0.1: + resolution: {integrity: sha512-kKlNACbvHrkpIw6oPeYDSmdCTu2hdMHoyXLTcUKala++lx5Y+wjJ/e474Jqv5abnVmwxw08DiTuHmw69lJGksA==} + engines: {node: '>=8.0.0'} + + workerpool@6.5.1: + resolution: {integrity: sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA==} + + wrap-ansi@6.2.0: + resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} + engines: {node: '>=8'} + + wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + + wrap-ansi@8.1.0: + resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} + engines: {node: '>=12'} + + wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + + write-file-atomic@3.0.3: + resolution: {integrity: sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==} + + ws@7.5.10: + resolution: {integrity: sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==} + engines: {node: '>=8.3.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ^5.0.2 + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + ws@8.17.1: + resolution: {integrity: sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==} + 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.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'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + wsl-utils@0.1.0: + resolution: {integrity: sha512-h3Fbisa2nKGPxCpm89Hk33lBLsnaGBvctQopaBSOW/uIs6FTe1ATyAnKFJrzVs9vpGdsTe73WF3V4lIsk4Gacw==} + engines: {node: '>=18'} + + xdg-basedir@5.1.0: + resolution: {integrity: sha512-GCPAHLvrIH13+c0SuacwvRYj2SxJXQ4kaVTT5xgL3kPrz56XxkF21IGhjSE1+W0aw7gpBWRGXLCPnPby6lSpmQ==} + engines: {node: '>=12'} + + xml-js@1.6.11: + resolution: {integrity: sha512-7rVi2KMfwfWFl+GpPg6m80IVMWXLRjO+PxTq7V2CDhoGak0wzYzFgUY2m4XJ47OGdXd8eLE8EmwfAmdjw7lC1g==} + hasBin: 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==} + + y18n@5.0.8: + resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} + engines: {node: '>=10'} + + yallist@3.1.1: + resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + + yargs-parser@18.1.3: + resolution: {integrity: sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==} + engines: {node: '>=6'} + + yargs-parser@20.2.9: + resolution: {integrity: sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==} + engines: {node: '>=10'} + + yargs-unparser@2.0.0: + resolution: {integrity: sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==} + engines: {node: '>=10'} + + yargs@15.4.1: + resolution: {integrity: sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==} + engines: {node: '>=8'} + + yargs@16.2.0: + resolution: {integrity: sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==} + engines: {node: '>=10'} + + yn@3.1.1: + resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==} + engines: {node: '>=6'} + + yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + + yocto-queue@1.2.2: + 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.2.1: + resolution: {integrity: sha512-0wZ1IRqGGhMP76gLqz8EyfBXKk0J2qo2+H3fi4mcUP/KtTocoX08nmIAHl1Z2kJIZbZee8KOpBCSNPRgauucjw==} + + 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.3: + resolution: {integrity: sha512-14fwWQtU3pH4dE0dOpdMiWjddcH+QzKIgk1cl8epwSE7yag43k/AD/m4L6+K7DytAOr9gGBe3/EXj9g7cdostg==} + engines: {node: '>=12.20.0'} + peerDependencies: + '@types/react': '>=18.0.0' + immer: '>=9.0.6' + react: '>=18.0.0' + use-sync-external-store: '>=1.2.0' + peerDependenciesMeta: + '@types/react': + optional: true + immer: + optional: true + react: + optional: true + use-sync-external-store: + optional: true + + zustand@5.0.9: + resolution: {integrity: sha512-ALBtUj0AfjJt3uNRQoL1tL2tMvj6Gp/6e39dnfT6uzpelGru8v1tPOGBzayOWbPJvujM8JojDk3E1LxeFisBNg==} + 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 + + zwitch@2.0.4: + resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} + +snapshots: + + '@account-abstraction/contracts@0.8.0': + dependencies: + '@openzeppelin/contracts': 5.4.0 + '@uniswap/v3-periphery': 1.4.4 + + '@adraffy/ens-normalize@1.10.1': {} + + '@adraffy/ens-normalize@1.11.1': {} + + '@algolia/abtesting@1.13.0': + dependencies: + '@algolia/client-common': 5.47.0 + '@algolia/requester-browser-xhr': 5.47.0 + '@algolia/requester-fetch': 5.47.0 + '@algolia/requester-node-http': 5.47.0 + + '@algolia/client-abtesting@5.47.0': + dependencies: + '@algolia/client-common': 5.47.0 + '@algolia/requester-browser-xhr': 5.47.0 + '@algolia/requester-fetch': 5.47.0 + '@algolia/requester-node-http': 5.47.0 + + '@algolia/client-analytics@5.47.0': + dependencies: + '@algolia/client-common': 5.47.0 + '@algolia/requester-browser-xhr': 5.47.0 + '@algolia/requester-fetch': 5.47.0 + '@algolia/requester-node-http': 5.47.0 + + '@algolia/client-common@5.47.0': {} + + '@algolia/client-insights@5.47.0': + dependencies: + '@algolia/client-common': 5.47.0 + '@algolia/requester-browser-xhr': 5.47.0 + '@algolia/requester-fetch': 5.47.0 + '@algolia/requester-node-http': 5.47.0 + + '@algolia/client-personalization@5.47.0': + dependencies: + '@algolia/client-common': 5.47.0 + '@algolia/requester-browser-xhr': 5.47.0 + '@algolia/requester-fetch': 5.47.0 + '@algolia/requester-node-http': 5.47.0 + + '@algolia/client-query-suggestions@5.47.0': + dependencies: + '@algolia/client-common': 5.47.0 + '@algolia/requester-browser-xhr': 5.47.0 + '@algolia/requester-fetch': 5.47.0 + '@algolia/requester-node-http': 5.47.0 + + '@algolia/client-search@5.47.0': + dependencies: + '@algolia/client-common': 5.47.0 + '@algolia/requester-browser-xhr': 5.47.0 + '@algolia/requester-fetch': 5.47.0 + '@algolia/requester-node-http': 5.47.0 + + '@algolia/events@4.0.1': {} + + '@algolia/ingestion@1.47.0': + dependencies: + '@algolia/client-common': 5.47.0 + '@algolia/requester-browser-xhr': 5.47.0 + '@algolia/requester-fetch': 5.47.0 + '@algolia/requester-node-http': 5.47.0 + + '@algolia/monitoring@1.47.0': + dependencies: + '@algolia/client-common': 5.47.0 + '@algolia/requester-browser-xhr': 5.47.0 + '@algolia/requester-fetch': 5.47.0 + '@algolia/requester-node-http': 5.47.0 + + '@algolia/recommend@5.47.0': + dependencies: + '@algolia/client-common': 5.47.0 + '@algolia/requester-browser-xhr': 5.47.0 + '@algolia/requester-fetch': 5.47.0 + '@algolia/requester-node-http': 5.47.0 + + '@algolia/requester-browser-xhr@5.47.0': + dependencies: + '@algolia/client-common': 5.47.0 + + '@algolia/requester-fetch@5.47.0': + dependencies: + '@algolia/client-common': 5.47.0 + + '@algolia/requester-node-http@5.47.0': + dependencies: + '@algolia/client-common': 5.47.0 + + '@alloc/quick-lru@5.2.0': {} + + '@aws-crypto/crc32@5.2.0': + dependencies: + '@aws-crypto/util': 5.2.0 + '@aws-sdk/types': 3.953.0 + tslib: 2.8.1 + + '@aws-crypto/sha256-browser@5.2.0': + dependencies: + '@aws-crypto/sha256-js': 5.2.0 + '@aws-crypto/supports-web-crypto': 5.2.0 + '@aws-crypto/util': 5.2.0 + '@aws-sdk/types': 3.953.0 + '@aws-sdk/util-locate-window': 3.953.0 + '@smithy/util-utf8': 2.3.0 + tslib: 2.8.1 + + '@aws-crypto/sha256-js@1.2.2': + dependencies: + '@aws-crypto/util': 1.2.2 + '@aws-sdk/types': 3.953.0 + tslib: 1.14.1 + + '@aws-crypto/sha256-js@5.2.0': + dependencies: + '@aws-crypto/util': 5.2.0 + '@aws-sdk/types': 3.953.0 + tslib: 2.8.1 + + '@aws-crypto/supports-web-crypto@5.2.0': + dependencies: + tslib: 2.8.1 + + '@aws-crypto/util@1.2.2': + dependencies: + '@aws-sdk/types': 3.953.0 + '@aws-sdk/util-utf8-browser': 3.259.0 + tslib: 1.14.1 + + '@aws-crypto/util@5.2.0': + dependencies: + '@aws-sdk/types': 3.953.0 + '@smithy/util-utf8': 2.3.0 + tslib: 2.8.1 + + '@aws-sdk/client-lambda@3.954.0': + dependencies: + '@aws-crypto/sha256-browser': 5.2.0 + '@aws-crypto/sha256-js': 5.2.0 + '@aws-sdk/core': 3.954.0 + '@aws-sdk/credential-provider-node': 3.954.0 + '@aws-sdk/middleware-host-header': 3.953.0 + '@aws-sdk/middleware-logger': 3.953.0 + '@aws-sdk/middleware-recursion-detection': 3.953.0 + '@aws-sdk/middleware-user-agent': 3.954.0 + '@aws-sdk/region-config-resolver': 3.953.0 + '@aws-sdk/types': 3.953.0 + '@aws-sdk/util-endpoints': 3.953.0 + '@aws-sdk/util-user-agent-browser': 3.953.0 + '@aws-sdk/util-user-agent-node': 3.954.0 + '@smithy/config-resolver': 4.4.4 + '@smithy/core': 3.19.0 + '@smithy/eventstream-serde-browser': 4.2.6 + '@smithy/eventstream-serde-config-resolver': 4.3.6 + '@smithy/eventstream-serde-node': 4.2.6 + '@smithy/fetch-http-handler': 5.3.7 + '@smithy/hash-node': 4.2.6 + '@smithy/invalid-dependency': 4.2.6 + '@smithy/middleware-content-length': 4.2.6 + '@smithy/middleware-endpoint': 4.4.0 + '@smithy/middleware-retry': 4.4.16 + '@smithy/middleware-serde': 4.2.7 + '@smithy/middleware-stack': 4.2.6 + '@smithy/node-config-provider': 4.3.6 + '@smithy/node-http-handler': 4.4.6 + '@smithy/protocol-http': 5.3.6 + '@smithy/smithy-client': 4.10.1 + '@smithy/types': 4.10.0 + '@smithy/url-parser': 4.2.6 + '@smithy/util-base64': 4.3.0 + '@smithy/util-body-length-browser': 4.2.0 + '@smithy/util-body-length-node': 4.2.1 + '@smithy/util-defaults-mode-browser': 4.3.15 + '@smithy/util-defaults-mode-node': 4.2.18 + '@smithy/util-endpoints': 3.2.6 + '@smithy/util-middleware': 4.2.6 + '@smithy/util-retry': 4.2.6 + '@smithy/util-stream': 4.5.7 + '@smithy/util-utf8': 4.2.0 + '@smithy/util-waiter': 4.2.6 + tslib: 2.8.1 + transitivePeerDependencies: + - aws-crt + + '@aws-sdk/client-sso@3.954.0': + dependencies: + '@aws-crypto/sha256-browser': 5.2.0 + '@aws-crypto/sha256-js': 5.2.0 + '@aws-sdk/core': 3.954.0 + '@aws-sdk/middleware-host-header': 3.953.0 + '@aws-sdk/middleware-logger': 3.953.0 + '@aws-sdk/middleware-recursion-detection': 3.953.0 + '@aws-sdk/middleware-user-agent': 3.954.0 + '@aws-sdk/region-config-resolver': 3.953.0 + '@aws-sdk/types': 3.953.0 + '@aws-sdk/util-endpoints': 3.953.0 + '@aws-sdk/util-user-agent-browser': 3.953.0 + '@aws-sdk/util-user-agent-node': 3.954.0 + '@smithy/config-resolver': 4.4.4 + '@smithy/core': 3.19.0 + '@smithy/fetch-http-handler': 5.3.7 + '@smithy/hash-node': 4.2.6 + '@smithy/invalid-dependency': 4.2.6 + '@smithy/middleware-content-length': 4.2.6 + '@smithy/middleware-endpoint': 4.4.0 + '@smithy/middleware-retry': 4.4.16 + '@smithy/middleware-serde': 4.2.7 + '@smithy/middleware-stack': 4.2.6 + '@smithy/node-config-provider': 4.3.6 + '@smithy/node-http-handler': 4.4.6 + '@smithy/protocol-http': 5.3.6 + '@smithy/smithy-client': 4.10.1 + '@smithy/types': 4.10.0 + '@smithy/url-parser': 4.2.6 + '@smithy/util-base64': 4.3.0 + '@smithy/util-body-length-browser': 4.2.0 + '@smithy/util-body-length-node': 4.2.1 + '@smithy/util-defaults-mode-browser': 4.3.15 + '@smithy/util-defaults-mode-node': 4.2.18 + '@smithy/util-endpoints': 3.2.6 + '@smithy/util-middleware': 4.2.6 + '@smithy/util-retry': 4.2.6 + '@smithy/util-utf8': 4.2.0 + tslib: 2.8.1 + transitivePeerDependencies: + - aws-crt + + '@aws-sdk/core@3.954.0': + dependencies: + '@aws-sdk/types': 3.953.0 + '@aws-sdk/xml-builder': 3.953.0 + '@smithy/core': 3.19.0 + '@smithy/node-config-provider': 4.3.6 + '@smithy/property-provider': 4.2.6 + '@smithy/protocol-http': 5.3.6 + '@smithy/signature-v4': 5.3.6 + '@smithy/smithy-client': 4.10.1 + '@smithy/types': 4.10.0 + '@smithy/util-base64': 4.3.0 + '@smithy/util-middleware': 4.2.6 + '@smithy/util-utf8': 4.2.0 + tslib: 2.8.1 + + '@aws-sdk/credential-provider-env@3.954.0': + dependencies: + '@aws-sdk/core': 3.954.0 + '@aws-sdk/types': 3.953.0 + '@smithy/property-provider': 4.2.6 + '@smithy/types': 4.10.0 + tslib: 2.8.1 + + '@aws-sdk/credential-provider-http@3.954.0': + dependencies: + '@aws-sdk/core': 3.954.0 + '@aws-sdk/types': 3.953.0 + '@smithy/fetch-http-handler': 5.3.7 + '@smithy/node-http-handler': 4.4.6 + '@smithy/property-provider': 4.2.6 + '@smithy/protocol-http': 5.3.6 + '@smithy/smithy-client': 4.10.1 + '@smithy/types': 4.10.0 + '@smithy/util-stream': 4.5.7 + tslib: 2.8.1 + + '@aws-sdk/credential-provider-ini@3.954.0': + dependencies: + '@aws-sdk/core': 3.954.0 + '@aws-sdk/credential-provider-env': 3.954.0 + '@aws-sdk/credential-provider-http': 3.954.0 + '@aws-sdk/credential-provider-login': 3.954.0 + '@aws-sdk/credential-provider-process': 3.954.0 + '@aws-sdk/credential-provider-sso': 3.954.0 + '@aws-sdk/credential-provider-web-identity': 3.954.0 + '@aws-sdk/nested-clients': 3.954.0 + '@aws-sdk/types': 3.953.0 + '@smithy/credential-provider-imds': 4.2.6 + '@smithy/property-provider': 4.2.6 + '@smithy/shared-ini-file-loader': 4.4.1 + '@smithy/types': 4.10.0 + tslib: 2.8.1 + transitivePeerDependencies: + - aws-crt + + '@aws-sdk/credential-provider-login@3.954.0': + dependencies: + '@aws-sdk/core': 3.954.0 + '@aws-sdk/nested-clients': 3.954.0 + '@aws-sdk/types': 3.953.0 + '@smithy/property-provider': 4.2.6 + '@smithy/protocol-http': 5.3.6 + '@smithy/shared-ini-file-loader': 4.4.1 + '@smithy/types': 4.10.0 + tslib: 2.8.1 + transitivePeerDependencies: + - aws-crt + + '@aws-sdk/credential-provider-node@3.954.0': + dependencies: + '@aws-sdk/credential-provider-env': 3.954.0 + '@aws-sdk/credential-provider-http': 3.954.0 + '@aws-sdk/credential-provider-ini': 3.954.0 + '@aws-sdk/credential-provider-process': 3.954.0 + '@aws-sdk/credential-provider-sso': 3.954.0 + '@aws-sdk/credential-provider-web-identity': 3.954.0 + '@aws-sdk/types': 3.953.0 + '@smithy/credential-provider-imds': 4.2.6 + '@smithy/property-provider': 4.2.6 + '@smithy/shared-ini-file-loader': 4.4.1 + '@smithy/types': 4.10.0 + tslib: 2.8.1 + transitivePeerDependencies: + - aws-crt + + '@aws-sdk/credential-provider-process@3.954.0': + dependencies: + '@aws-sdk/core': 3.954.0 + '@aws-sdk/types': 3.953.0 + '@smithy/property-provider': 4.2.6 + '@smithy/shared-ini-file-loader': 4.4.1 + '@smithy/types': 4.10.0 + tslib: 2.8.1 + + '@aws-sdk/credential-provider-sso@3.954.0': + dependencies: + '@aws-sdk/client-sso': 3.954.0 + '@aws-sdk/core': 3.954.0 + '@aws-sdk/token-providers': 3.954.0 + '@aws-sdk/types': 3.953.0 + '@smithy/property-provider': 4.2.6 + '@smithy/shared-ini-file-loader': 4.4.1 + '@smithy/types': 4.10.0 + tslib: 2.8.1 + transitivePeerDependencies: + - aws-crt + + '@aws-sdk/credential-provider-web-identity@3.954.0': + dependencies: + '@aws-sdk/core': 3.954.0 + '@aws-sdk/nested-clients': 3.954.0 + '@aws-sdk/types': 3.953.0 + '@smithy/property-provider': 4.2.6 + '@smithy/shared-ini-file-loader': 4.4.1 + '@smithy/types': 4.10.0 + tslib: 2.8.1 + transitivePeerDependencies: + - aws-crt + + '@aws-sdk/middleware-host-header@3.953.0': + dependencies: + '@aws-sdk/types': 3.953.0 + '@smithy/protocol-http': 5.3.6 + '@smithy/types': 4.10.0 + tslib: 2.8.1 + + '@aws-sdk/middleware-logger@3.953.0': + dependencies: + '@aws-sdk/types': 3.953.0 + '@smithy/types': 4.10.0 + tslib: 2.8.1 + + '@aws-sdk/middleware-recursion-detection@3.953.0': + dependencies: + '@aws-sdk/types': 3.953.0 + '@aws/lambda-invoke-store': 0.2.2 + '@smithy/protocol-http': 5.3.6 + '@smithy/types': 4.10.0 + tslib: 2.8.1 + + '@aws-sdk/middleware-user-agent@3.954.0': + dependencies: + '@aws-sdk/core': 3.954.0 + '@aws-sdk/types': 3.953.0 + '@aws-sdk/util-endpoints': 3.953.0 + '@smithy/core': 3.19.0 + '@smithy/protocol-http': 5.3.6 + '@smithy/types': 4.10.0 + tslib: 2.8.1 + + '@aws-sdk/nested-clients@3.954.0': + dependencies: + '@aws-crypto/sha256-browser': 5.2.0 + '@aws-crypto/sha256-js': 5.2.0 + '@aws-sdk/core': 3.954.0 + '@aws-sdk/middleware-host-header': 3.953.0 + '@aws-sdk/middleware-logger': 3.953.0 + '@aws-sdk/middleware-recursion-detection': 3.953.0 + '@aws-sdk/middleware-user-agent': 3.954.0 + '@aws-sdk/region-config-resolver': 3.953.0 '@aws-sdk/types': 3.953.0 '@aws-sdk/util-endpoints': 3.953.0 '@aws-sdk/util-user-agent-browser': 3.953.0 '@aws-sdk/util-user-agent-node': 3.954.0 '@smithy/config-resolver': 4.4.4 '@smithy/core': 3.19.0 - '@smithy/eventstream-serde-browser': 4.2.6 - '@smithy/eventstream-serde-config-resolver': 4.3.6 - '@smithy/eventstream-serde-node': 4.2.6 - '@smithy/fetch-http-handler': 5.3.7 - '@smithy/hash-node': 4.2.6 - '@smithy/invalid-dependency': 4.2.6 - '@smithy/middleware-content-length': 4.2.6 + '@smithy/fetch-http-handler': 5.3.7 + '@smithy/hash-node': 4.2.6 + '@smithy/invalid-dependency': 4.2.6 + '@smithy/middleware-content-length': 4.2.6 + '@smithy/middleware-endpoint': 4.4.0 + '@smithy/middleware-retry': 4.4.16 + '@smithy/middleware-serde': 4.2.7 + '@smithy/middleware-stack': 4.2.6 + '@smithy/node-config-provider': 4.3.6 + '@smithy/node-http-handler': 4.4.6 + '@smithy/protocol-http': 5.3.6 + '@smithy/smithy-client': 4.10.1 + '@smithy/types': 4.10.0 + '@smithy/url-parser': 4.2.6 + '@smithy/util-base64': 4.3.0 + '@smithy/util-body-length-browser': 4.2.0 + '@smithy/util-body-length-node': 4.2.1 + '@smithy/util-defaults-mode-browser': 4.3.15 + '@smithy/util-defaults-mode-node': 4.2.18 + '@smithy/util-endpoints': 3.2.6 + '@smithy/util-middleware': 4.2.6 + '@smithy/util-retry': 4.2.6 + '@smithy/util-utf8': 4.2.0 + tslib: 2.8.1 + transitivePeerDependencies: + - aws-crt + + '@aws-sdk/region-config-resolver@3.953.0': + dependencies: + '@aws-sdk/types': 3.953.0 + '@smithy/config-resolver': 4.4.4 + '@smithy/node-config-provider': 4.3.6 + '@smithy/types': 4.10.0 + tslib: 2.8.1 + + '@aws-sdk/token-providers@3.954.0': + dependencies: + '@aws-sdk/core': 3.954.0 + '@aws-sdk/nested-clients': 3.954.0 + '@aws-sdk/types': 3.953.0 + '@smithy/property-provider': 4.2.6 + '@smithy/shared-ini-file-loader': 4.4.1 + '@smithy/types': 4.10.0 + tslib: 2.8.1 + transitivePeerDependencies: + - aws-crt + + '@aws-sdk/types@3.953.0': + dependencies: + '@smithy/types': 4.10.0 + tslib: 2.8.1 + + '@aws-sdk/util-endpoints@3.953.0': + dependencies: + '@aws-sdk/types': 3.953.0 + '@smithy/types': 4.10.0 + '@smithy/url-parser': 4.2.6 + '@smithy/util-endpoints': 3.2.6 + tslib: 2.8.1 + + '@aws-sdk/util-locate-window@3.953.0': + dependencies: + tslib: 2.8.1 + + '@aws-sdk/util-user-agent-browser@3.953.0': + dependencies: + '@aws-sdk/types': 3.953.0 + '@smithy/types': 4.10.0 + bowser: 2.13.1 + tslib: 2.8.1 + + '@aws-sdk/util-user-agent-node@3.954.0': + dependencies: + '@aws-sdk/middleware-user-agent': 3.954.0 + '@aws-sdk/types': 3.953.0 + '@smithy/node-config-provider': 4.3.6 + '@smithy/types': 4.10.0 + tslib: 2.8.1 + + '@aws-sdk/util-utf8-browser@3.259.0': + dependencies: + tslib: 2.8.1 + + '@aws-sdk/xml-builder@3.953.0': + dependencies: + '@smithy/types': 4.10.0 + fast-xml-parser: 5.2.5 + tslib: 2.8.1 + + '@aws/lambda-invoke-store@0.2.2': {} + + '@babel/code-frame@7.27.1': + dependencies: + '@babel/helper-validator-identifier': 7.28.5 + js-tokens: 4.0.0 + picocolors: 1.1.1 + + '@babel/code-frame@7.28.6': + dependencies: + '@babel/helper-validator-identifier': 7.28.5 + js-tokens: 4.0.0 + picocolors: 1.1.1 + + '@babel/compat-data@7.28.5': {} + + '@babel/compat-data@7.28.6': {} + + '@babel/core@7.28.5': + dependencies: + '@babel/code-frame': 7.27.1 + '@babel/generator': 7.28.5 + '@babel/helper-compilation-targets': 7.27.2 + '@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.5) + '@babel/helpers': 7.28.4 + '@babel/parser': 7.28.5 + '@babel/template': 7.27.2 + '@babel/traverse': 7.28.5 + '@babel/types': 7.28.5 + '@jridgewell/remapping': 2.3.5 + convert-source-map: 2.0.0 + debug: 4.4.3(supports-color@8.1.1) + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/generator@7.28.5': + dependencies: + '@babel/parser': 7.28.5 + '@babel/types': 7.28.5 + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + jsesc: 3.1.0 + + '@babel/generator@7.28.6': + dependencies: + '@babel/parser': 7.28.6 + '@babel/types': 7.28.6 + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + jsesc: 3.1.0 + + '@babel/helper-annotate-as-pure@7.27.3': + dependencies: + '@babel/types': 7.28.5 + + '@babel/helper-compilation-targets@7.27.2': + dependencies: + '@babel/compat-data': 7.28.5 + '@babel/helper-validator-option': 7.27.1 + browserslist: 4.28.1 + lru-cache: 5.1.1 + semver: 6.3.1 + + '@babel/helper-compilation-targets@7.28.6': + dependencies: + '@babel/compat-data': 7.28.6 + '@babel/helper-validator-option': 7.27.1 + browserslist: 4.28.1 + lru-cache: 5.1.1 + semver: 6.3.1 + + '@babel/helper-create-class-features-plugin@7.28.6(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-member-expression-to-functions': 7.28.5 + '@babel/helper-optimise-call-expression': 7.27.1 + '@babel/helper-replace-supers': 7.28.6(@babel/core@7.28.5) + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + '@babel/traverse': 7.28.6 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/helper-create-regexp-features-plugin@7.28.5(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-annotate-as-pure': 7.27.3 + regexpu-core: 6.4.0 + semver: 6.3.1 + + '@babel/helper-define-polyfill-provider@0.6.5(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-compilation-targets': 7.28.6 + '@babel/helper-plugin-utils': 7.28.6 + debug: 4.4.3(supports-color@8.1.1) + lodash.debounce: 4.0.8 + resolve: 1.22.11 + transitivePeerDependencies: + - supports-color + + '@babel/helper-globals@7.28.0': {} + + '@babel/helper-member-expression-to-functions@7.28.5': + dependencies: + '@babel/traverse': 7.28.6 + '@babel/types': 7.28.5 + transitivePeerDependencies: + - supports-color + + '@babel/helper-module-imports@7.27.1': + dependencies: + '@babel/traverse': 7.28.5 + '@babel/types': 7.28.5 + transitivePeerDependencies: + - supports-color + + '@babel/helper-module-imports@7.28.6': + dependencies: + '@babel/traverse': 7.28.6 + '@babel/types': 7.28.6 + transitivePeerDependencies: + - supports-color + + '@babel/helper-module-transforms@7.28.3(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-module-imports': 7.27.1 + '@babel/helper-validator-identifier': 7.28.5 + '@babel/traverse': 7.28.5 + transitivePeerDependencies: + - supports-color + + '@babel/helper-module-transforms@7.28.6(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-module-imports': 7.28.6 + '@babel/helper-validator-identifier': 7.28.5 + '@babel/traverse': 7.28.6 + transitivePeerDependencies: + - supports-color + + '@babel/helper-optimise-call-expression@7.27.1': + dependencies: + '@babel/types': 7.28.5 + + '@babel/helper-plugin-utils@7.27.1': {} + + '@babel/helper-plugin-utils@7.28.6': {} + + '@babel/helper-remap-async-to-generator@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-wrap-function': 7.28.6 + '@babel/traverse': 7.28.6 + transitivePeerDependencies: + - supports-color + + '@babel/helper-replace-supers@7.28.6(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-member-expression-to-functions': 7.28.5 + '@babel/helper-optimise-call-expression': 7.27.1 + '@babel/traverse': 7.28.6 + transitivePeerDependencies: + - supports-color + + '@babel/helper-skip-transparent-expression-wrappers@7.27.1': + dependencies: + '@babel/traverse': 7.28.5 + '@babel/types': 7.28.5 + transitivePeerDependencies: + - supports-color + + '@babel/helper-string-parser@7.27.1': {} + + '@babel/helper-validator-identifier@7.28.5': {} + + '@babel/helper-validator-option@7.27.1': {} + + '@babel/helper-wrap-function@7.28.6': + dependencies: + '@babel/template': 7.28.6 + '@babel/traverse': 7.28.6 + '@babel/types': 7.28.6 + transitivePeerDependencies: + - supports-color + + '@babel/helpers@7.28.4': + dependencies: + '@babel/template': 7.27.2 + '@babel/types': 7.28.5 + + '@babel/parser@7.28.5': + dependencies: + '@babel/types': 7.28.5 + + '@babel/parser@7.28.6': + dependencies: + '@babel/types': 7.28.6 + + '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.28.5(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/traverse': 7.28.5 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-bugfix-safari-class-field-initializer-scope@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + '@babel/plugin-transform-optional-chaining': 7.28.6(@babel/core@7.28.5) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.28.6(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/traverse': 7.28.6 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + + '@babel/plugin-syntax-dynamic-import@7.8.3(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-import-assertions@7.28.6(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-syntax-import-attributes@7.28.6(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-syntax-typescript@7.28.6(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-syntax-unicode-sets-regex@7.18.6(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.28.5) + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-arrow-functions@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-async-generator-functions@7.28.6(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-remap-async-to-generator': 7.27.1(@babel/core@7.28.5) + '@babel/traverse': 7.28.6 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-async-to-generator@7.28.6(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-module-imports': 7.28.6 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-remap-async-to-generator': 7.27.1(@babel/core@7.28.5) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-block-scoped-functions@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-block-scoping@7.28.6(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-class-properties@7.28.6(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.28.5) + '@babel/helper-plugin-utils': 7.28.6 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-class-static-block@7.28.6(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.28.5) + '@babel/helper-plugin-utils': 7.28.6 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-classes@7.28.6(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-compilation-targets': 7.28.6 + '@babel/helper-globals': 7.28.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-replace-supers': 7.28.6(@babel/core@7.28.5) + '@babel/traverse': 7.28.6 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-computed-properties@7.28.6(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/template': 7.28.6 + + '@babel/plugin-transform-destructuring@7.28.5(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/traverse': 7.28.5 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-dotall-regex@7.28.6(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.28.5) + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-duplicate-keys@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.28.6(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.28.5) + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-dynamic-import@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-explicit-resource-management@7.28.6(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/plugin-transform-destructuring': 7.28.5(@babel/core@7.28.5) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-exponentiation-operator@7.28.6(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-export-namespace-from@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-for-of@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-function-name@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-compilation-targets': 7.28.6 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/traverse': 7.28.5 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-json-strings@7.28.6(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-literals@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-logical-assignment-operators@7.28.6(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-member-expression-literals@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-modules-amd@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.5) + '@babel/helper-plugin-utils': 7.28.6 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-modules-commonjs@7.28.6(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-module-transforms': 7.28.6(@babel/core@7.28.5) + '@babel/helper-plugin-utils': 7.28.6 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-modules-systemjs@7.28.5(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.5) + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-validator-identifier': 7.28.5 + '@babel/traverse': 7.28.5 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-modules-umd@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.5) + '@babel/helper-plugin-utils': 7.28.6 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-named-capturing-groups-regex@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.28.5) + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-new-target@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-nullish-coalescing-operator@7.28.6(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-numeric-separator@7.28.6(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-object-rest-spread@7.28.6(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-compilation-targets': 7.28.6 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/plugin-transform-destructuring': 7.28.5(@babel/core@7.28.5) + '@babel/plugin-transform-parameters': 7.27.7(@babel/core@7.28.5) + '@babel/traverse': 7.28.6 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-object-super@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-replace-supers': 7.28.6(@babel/core@7.28.5) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-optional-catch-binding@7.28.6(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-optional-chaining@7.28.6(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-parameters@7.27.7(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-private-methods@7.28.6(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.28.5) + '@babel/helper-plugin-utils': 7.28.6 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-private-property-in-object@7.28.6(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.28.5) + '@babel/helper-plugin-utils': 7.28.6 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-property-literals@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-react-constant-elements@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-react-display-name@7.28.0(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-react-jsx-development@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/plugin-transform-react-jsx': 7.28.6(@babel/core@7.28.5) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-react-jsx-self@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-react-jsx-source@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-react-jsx@7.28.6(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-module-imports': 7.28.6 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/plugin-syntax-jsx': 7.28.6(@babel/core@7.28.5) + '@babel/types': 7.28.6 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-react-pure-annotations@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-regenerator@7.28.6(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-regexp-modifiers@7.28.6(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.28.5) + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-reserved-words@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-runtime@7.28.5(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-module-imports': 7.27.1 + '@babel/helper-plugin-utils': 7.27.1 + babel-plugin-polyfill-corejs2: 0.4.14(@babel/core@7.28.5) + babel-plugin-polyfill-corejs3: 0.13.0(@babel/core@7.28.5) + babel-plugin-polyfill-regenerator: 0.6.5(@babel/core@7.28.5) + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-shorthand-properties@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-spread@7.28.6(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-sticky-regex@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-template-literals@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-typeof-symbol@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-typescript@7.28.6(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.28.5) + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + '@babel/plugin-syntax-typescript': 7.28.6(@babel/core@7.28.5) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-unicode-escapes@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-unicode-property-regex@7.28.6(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.28.5) + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-unicode-regex@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.28.5) + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-unicode-sets-regex@7.28.6(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.28.5) + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/preset-env@7.28.6(@babel/core@7.28.5)': + dependencies: + '@babel/compat-data': 7.28.6 + '@babel/core': 7.28.5 + '@babel/helper-compilation-targets': 7.28.6 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-validator-option': 7.27.1 + '@babel/plugin-bugfix-firefox-class-in-computed-class-key': 7.28.5(@babel/core@7.28.5) + '@babel/plugin-bugfix-safari-class-field-initializer-scope': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly': 7.28.6(@babel/core@7.28.5) + '@babel/plugin-proposal-private-property-in-object': 7.21.0-placeholder-for-preset-env.2(@babel/core@7.28.5) + '@babel/plugin-syntax-import-assertions': 7.28.6(@babel/core@7.28.5) + '@babel/plugin-syntax-import-attributes': 7.28.6(@babel/core@7.28.5) + '@babel/plugin-syntax-unicode-sets-regex': 7.18.6(@babel/core@7.28.5) + '@babel/plugin-transform-arrow-functions': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-async-generator-functions': 7.28.6(@babel/core@7.28.5) + '@babel/plugin-transform-async-to-generator': 7.28.6(@babel/core@7.28.5) + '@babel/plugin-transform-block-scoped-functions': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-block-scoping': 7.28.6(@babel/core@7.28.5) + '@babel/plugin-transform-class-properties': 7.28.6(@babel/core@7.28.5) + '@babel/plugin-transform-class-static-block': 7.28.6(@babel/core@7.28.5) + '@babel/plugin-transform-classes': 7.28.6(@babel/core@7.28.5) + '@babel/plugin-transform-computed-properties': 7.28.6(@babel/core@7.28.5) + '@babel/plugin-transform-destructuring': 7.28.5(@babel/core@7.28.5) + '@babel/plugin-transform-dotall-regex': 7.28.6(@babel/core@7.28.5) + '@babel/plugin-transform-duplicate-keys': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-duplicate-named-capturing-groups-regex': 7.28.6(@babel/core@7.28.5) + '@babel/plugin-transform-dynamic-import': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-explicit-resource-management': 7.28.6(@babel/core@7.28.5) + '@babel/plugin-transform-exponentiation-operator': 7.28.6(@babel/core@7.28.5) + '@babel/plugin-transform-export-namespace-from': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-for-of': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-function-name': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-json-strings': 7.28.6(@babel/core@7.28.5) + '@babel/plugin-transform-literals': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-logical-assignment-operators': 7.28.6(@babel/core@7.28.5) + '@babel/plugin-transform-member-expression-literals': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-modules-amd': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-modules-commonjs': 7.28.6(@babel/core@7.28.5) + '@babel/plugin-transform-modules-systemjs': 7.28.5(@babel/core@7.28.5) + '@babel/plugin-transform-modules-umd': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-named-capturing-groups-regex': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-new-target': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-nullish-coalescing-operator': 7.28.6(@babel/core@7.28.5) + '@babel/plugin-transform-numeric-separator': 7.28.6(@babel/core@7.28.5) + '@babel/plugin-transform-object-rest-spread': 7.28.6(@babel/core@7.28.5) + '@babel/plugin-transform-object-super': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-optional-catch-binding': 7.28.6(@babel/core@7.28.5) + '@babel/plugin-transform-optional-chaining': 7.28.6(@babel/core@7.28.5) + '@babel/plugin-transform-parameters': 7.27.7(@babel/core@7.28.5) + '@babel/plugin-transform-private-methods': 7.28.6(@babel/core@7.28.5) + '@babel/plugin-transform-private-property-in-object': 7.28.6(@babel/core@7.28.5) + '@babel/plugin-transform-property-literals': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-regenerator': 7.28.6(@babel/core@7.28.5) + '@babel/plugin-transform-regexp-modifiers': 7.28.6(@babel/core@7.28.5) + '@babel/plugin-transform-reserved-words': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-shorthand-properties': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-spread': 7.28.6(@babel/core@7.28.5) + '@babel/plugin-transform-sticky-regex': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-template-literals': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-typeof-symbol': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-unicode-escapes': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-unicode-property-regex': 7.28.6(@babel/core@7.28.5) + '@babel/plugin-transform-unicode-regex': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-unicode-sets-regex': 7.28.6(@babel/core@7.28.5) + '@babel/preset-modules': 0.1.6-no-external-plugins(@babel/core@7.28.5) + babel-plugin-polyfill-corejs2: 0.4.14(@babel/core@7.28.5) + babel-plugin-polyfill-corejs3: 0.13.0(@babel/core@7.28.5) + babel-plugin-polyfill-regenerator: 0.6.5(@babel/core@7.28.5) + core-js-compat: 3.47.0 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/preset-modules@0.1.6-no-external-plugins(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/types': 7.28.5 + esutils: 2.0.3 + + '@babel/preset-react@7.28.5(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-validator-option': 7.27.1 + '@babel/plugin-transform-react-display-name': 7.28.0(@babel/core@7.28.5) + '@babel/plugin-transform-react-jsx': 7.28.6(@babel/core@7.28.5) + '@babel/plugin-transform-react-jsx-development': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-react-pure-annotations': 7.27.1(@babel/core@7.28.5) + transitivePeerDependencies: + - supports-color + + '@babel/preset-typescript@7.28.5(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-validator-option': 7.27.1 + '@babel/plugin-syntax-jsx': 7.28.6(@babel/core@7.28.5) + '@babel/plugin-transform-modules-commonjs': 7.28.6(@babel/core@7.28.5) + '@babel/plugin-transform-typescript': 7.28.6(@babel/core@7.28.5) + transitivePeerDependencies: + - supports-color + + '@babel/runtime-corejs3@7.28.6': + dependencies: + core-js-pure: 3.47.0 + + '@babel/runtime@7.28.4': {} + + '@babel/template@7.27.2': + dependencies: + '@babel/code-frame': 7.27.1 + '@babel/parser': 7.28.5 + '@babel/types': 7.28.5 + + '@babel/template@7.28.6': + dependencies: + '@babel/code-frame': 7.28.6 + '@babel/parser': 7.28.6 + '@babel/types': 7.28.6 + + '@babel/traverse@7.28.5': + dependencies: + '@babel/code-frame': 7.27.1 + '@babel/generator': 7.28.5 + '@babel/helper-globals': 7.28.0 + '@babel/parser': 7.28.5 + '@babel/template': 7.27.2 + '@babel/types': 7.28.5 + debug: 4.4.3(supports-color@8.1.1) + transitivePeerDependencies: + - supports-color + + '@babel/traverse@7.28.6': + dependencies: + '@babel/code-frame': 7.28.6 + '@babel/generator': 7.28.6 + '@babel/helper-globals': 7.28.0 + '@babel/parser': 7.28.6 + '@babel/template': 7.28.6 + '@babel/types': 7.28.6 + debug: 4.4.3(supports-color@8.1.1) + transitivePeerDependencies: + - supports-color + + '@babel/types@7.28.5': + dependencies: + '@babel/helper-string-parser': 7.27.1 + '@babel/helper-validator-identifier': 7.28.5 + + '@babel/types@7.28.6': + dependencies: + '@babel/helper-string-parser': 7.27.1 + '@babel/helper-validator-identifier': 7.28.5 + + '@base-org/account@2.4.0(@types/react@18.3.27)(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(immer@10.0.2)(react@18.3.1)(typescript@5.6.3)(use-sync-external-store@1.4.0(react@18.3.1))(utf-8-validate@5.0.10)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)': + dependencies: + '@coinbase/cdp-sdk': 1.40.1(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3)(utf-8-validate@5.0.10)(ws@8.18.0(bufferutil@4.0.9)(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.6.3)(zod@3.25.76) + preact: 10.24.2 + viem: 2.43.1(bufferutil@4.0.9)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.25.76) + zustand: 5.0.3(@types/react@18.3.27)(immer@10.0.2)(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 + - ws + - zod + + '@bytecodealliance/preview2-shim@0.17.0': {} + + '@coinbase/cdp-sdk@1.40.1(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3)(utf-8-validate@5.0.10)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))': + dependencies: + '@solana-program/system': 0.8.1(@solana/kit@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))) + '@solana-program/token': 0.6.0(@solana/kit@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))) + '@solana/kit': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@solana/web3.js': 1.98.4(bufferutil@4.0.9)(typescript@5.6.3)(utf-8-validate@5.0.10) + abitype: 1.0.6(typescript@5.6.3)(zod@3.25.76) + axios: 1.13.2(debug@4.4.3) + axios-retry: 4.5.0(axios@1.13.2) + jose: 6.1.3 + md5: 2.3.0 + uncrypto: 0.1.3 + viem: 2.43.1(bufferutil@4.0.9)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.25.76) + zod: 3.25.76 + transitivePeerDependencies: + - bufferutil + - debug + - encoding + - fastestsmallesttextencoderdecoder + - typescript + - utf-8-validate + - ws + + '@coinbase/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.1 + keccak: 3.0.4 + preact: 10.28.0 + sha.js: 2.4.12 + transitivePeerDependencies: + - supports-color + + '@coinbase/wallet-sdk@4.3.6(@types/react@18.3.27)(bufferutil@4.0.9)(immer@10.0.2)(react@18.3.1)(typescript@5.6.3)(use-sync-external-store@1.4.0(react@18.3.1))(utf-8-validate@5.0.10)(zod@3.25.76)': + dependencies: + '@noble/hashes': 1.4.0 + clsx: 1.2.1 + eventemitter3: 5.0.1 + idb-keyval: 6.2.1 + ox: 0.6.9(typescript@5.6.3)(zod@3.25.76) + preact: 10.24.2 + viem: 2.43.1(bufferutil@4.0.9)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.25.76) + zustand: 5.0.3(@types/react@18.3.27)(immer@10.0.2)(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 + + '@colors/colors@1.5.0': + optional: true + + '@cspotcode/source-map-support@0.8.1': + dependencies: + '@jridgewell/trace-mapping': 0.3.9 + + '@csstools/cascade-layer-name-parser@2.0.5(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4)': + dependencies: + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + + '@csstools/color-helpers@5.1.0': {} + + '@csstools/css-calc@2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4)': + dependencies: + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + + '@csstools/css-color-parser@3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4)': + dependencies: + '@csstools/color-helpers': 5.1.0 + '@csstools/css-calc': 2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + + '@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4)': + dependencies: + '@csstools/css-tokenizer': 3.0.4 + + '@csstools/css-tokenizer@3.0.4': {} + + '@csstools/media-query-list-parser@4.0.3(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4)': + dependencies: + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + + '@csstools/postcss-alpha-function@1.0.1(postcss@8.5.6)': + dependencies: + '@csstools/css-color-parser': 3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + '@csstools/postcss-progressive-custom-properties': 4.2.1(postcss@8.5.6) + '@csstools/utilities': 2.0.0(postcss@8.5.6) + postcss: 8.5.6 + + '@csstools/postcss-cascade-layers@5.0.2(postcss@8.5.6)': + dependencies: + '@csstools/selector-specificity': 5.0.0(postcss-selector-parser@7.1.1) + postcss: 8.5.6 + postcss-selector-parser: 7.1.1 + + '@csstools/postcss-color-function-display-p3-linear@1.0.1(postcss@8.5.6)': + dependencies: + '@csstools/css-color-parser': 3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + '@csstools/postcss-progressive-custom-properties': 4.2.1(postcss@8.5.6) + '@csstools/utilities': 2.0.0(postcss@8.5.6) + postcss: 8.5.6 + + '@csstools/postcss-color-function@4.0.12(postcss@8.5.6)': + dependencies: + '@csstools/css-color-parser': 3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + '@csstools/postcss-progressive-custom-properties': 4.2.1(postcss@8.5.6) + '@csstools/utilities': 2.0.0(postcss@8.5.6) + postcss: 8.5.6 + + '@csstools/postcss-color-mix-function@3.0.12(postcss@8.5.6)': + dependencies: + '@csstools/css-color-parser': 3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + '@csstools/postcss-progressive-custom-properties': 4.2.1(postcss@8.5.6) + '@csstools/utilities': 2.0.0(postcss@8.5.6) + postcss: 8.5.6 + + '@csstools/postcss-color-mix-variadic-function-arguments@1.0.2(postcss@8.5.6)': + dependencies: + '@csstools/css-color-parser': 3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + '@csstools/postcss-progressive-custom-properties': 4.2.1(postcss@8.5.6) + '@csstools/utilities': 2.0.0(postcss@8.5.6) + postcss: 8.5.6 + + '@csstools/postcss-content-alt-text@2.0.8(postcss@8.5.6)': + dependencies: + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + '@csstools/postcss-progressive-custom-properties': 4.2.1(postcss@8.5.6) + '@csstools/utilities': 2.0.0(postcss@8.5.6) + postcss: 8.5.6 + + '@csstools/postcss-contrast-color-function@2.0.12(postcss@8.5.6)': + dependencies: + '@csstools/css-color-parser': 3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + '@csstools/postcss-progressive-custom-properties': 4.2.1(postcss@8.5.6) + '@csstools/utilities': 2.0.0(postcss@8.5.6) + postcss: 8.5.6 + + '@csstools/postcss-exponential-functions@2.0.9(postcss@8.5.6)': + dependencies: + '@csstools/css-calc': 2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + postcss: 8.5.6 + + '@csstools/postcss-font-format-keywords@4.0.0(postcss@8.5.6)': + dependencies: + '@csstools/utilities': 2.0.0(postcss@8.5.6) + postcss: 8.5.6 + postcss-value-parser: 4.2.0 + + '@csstools/postcss-gamut-mapping@2.0.11(postcss@8.5.6)': + dependencies: + '@csstools/css-color-parser': 3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + postcss: 8.5.6 + + '@csstools/postcss-gradients-interpolation-method@5.0.12(postcss@8.5.6)': + dependencies: + '@csstools/css-color-parser': 3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + '@csstools/postcss-progressive-custom-properties': 4.2.1(postcss@8.5.6) + '@csstools/utilities': 2.0.0(postcss@8.5.6) + postcss: 8.5.6 + + '@csstools/postcss-hwb-function@4.0.12(postcss@8.5.6)': + dependencies: + '@csstools/css-color-parser': 3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + '@csstools/postcss-progressive-custom-properties': 4.2.1(postcss@8.5.6) + '@csstools/utilities': 2.0.0(postcss@8.5.6) + postcss: 8.5.6 + + '@csstools/postcss-ic-unit@4.0.4(postcss@8.5.6)': + dependencies: + '@csstools/postcss-progressive-custom-properties': 4.2.1(postcss@8.5.6) + '@csstools/utilities': 2.0.0(postcss@8.5.6) + postcss: 8.5.6 + postcss-value-parser: 4.2.0 + + '@csstools/postcss-initial@2.0.1(postcss@8.5.6)': + dependencies: + postcss: 8.5.6 + + '@csstools/postcss-is-pseudo-class@5.0.3(postcss@8.5.6)': + dependencies: + '@csstools/selector-specificity': 5.0.0(postcss-selector-parser@7.1.1) + postcss: 8.5.6 + postcss-selector-parser: 7.1.1 + + '@csstools/postcss-light-dark-function@2.0.11(postcss@8.5.6)': + dependencies: + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + '@csstools/postcss-progressive-custom-properties': 4.2.1(postcss@8.5.6) + '@csstools/utilities': 2.0.0(postcss@8.5.6) + postcss: 8.5.6 + + '@csstools/postcss-logical-float-and-clear@3.0.0(postcss@8.5.6)': + dependencies: + postcss: 8.5.6 + + '@csstools/postcss-logical-overflow@2.0.0(postcss@8.5.6)': + dependencies: + postcss: 8.5.6 + + '@csstools/postcss-logical-overscroll-behavior@2.0.0(postcss@8.5.6)': + dependencies: + postcss: 8.5.6 + + '@csstools/postcss-logical-resize@3.0.0(postcss@8.5.6)': + dependencies: + postcss: 8.5.6 + postcss-value-parser: 4.2.0 + + '@csstools/postcss-logical-viewport-units@3.0.4(postcss@8.5.6)': + dependencies: + '@csstools/css-tokenizer': 3.0.4 + '@csstools/utilities': 2.0.0(postcss@8.5.6) + postcss: 8.5.6 + + '@csstools/postcss-media-minmax@2.0.9(postcss@8.5.6)': + dependencies: + '@csstools/css-calc': 2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + '@csstools/media-query-list-parser': 4.0.3(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + postcss: 8.5.6 + + '@csstools/postcss-media-queries-aspect-ratio-number-values@3.0.5(postcss@8.5.6)': + dependencies: + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + '@csstools/media-query-list-parser': 4.0.3(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + postcss: 8.5.6 + + '@csstools/postcss-nested-calc@4.0.0(postcss@8.5.6)': + dependencies: + '@csstools/utilities': 2.0.0(postcss@8.5.6) + postcss: 8.5.6 + postcss-value-parser: 4.2.0 + + '@csstools/postcss-normalize-display-values@4.0.1(postcss@8.5.6)': + dependencies: + postcss: 8.5.6 + postcss-value-parser: 4.2.0 + + '@csstools/postcss-oklab-function@4.0.12(postcss@8.5.6)': + dependencies: + '@csstools/css-color-parser': 3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + '@csstools/postcss-progressive-custom-properties': 4.2.1(postcss@8.5.6) + '@csstools/utilities': 2.0.0(postcss@8.5.6) + postcss: 8.5.6 + + '@csstools/postcss-position-area-property@1.0.0(postcss@8.5.6)': + dependencies: + postcss: 8.5.6 + + '@csstools/postcss-progressive-custom-properties@4.2.1(postcss@8.5.6)': + dependencies: + postcss: 8.5.6 + postcss-value-parser: 4.2.0 + + '@csstools/postcss-property-rule-prelude-list@1.0.0(postcss@8.5.6)': + dependencies: + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + postcss: 8.5.6 + + '@csstools/postcss-random-function@2.0.1(postcss@8.5.6)': + dependencies: + '@csstools/css-calc': 2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + postcss: 8.5.6 + + '@csstools/postcss-relative-color-syntax@3.0.12(postcss@8.5.6)': + dependencies: + '@csstools/css-color-parser': 3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + '@csstools/postcss-progressive-custom-properties': 4.2.1(postcss@8.5.6) + '@csstools/utilities': 2.0.0(postcss@8.5.6) + postcss: 8.5.6 + + '@csstools/postcss-scope-pseudo-class@4.0.1(postcss@8.5.6)': + dependencies: + postcss: 8.5.6 + postcss-selector-parser: 7.1.1 + + '@csstools/postcss-sign-functions@1.1.4(postcss@8.5.6)': + dependencies: + '@csstools/css-calc': 2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + postcss: 8.5.6 + + '@csstools/postcss-stepped-value-functions@4.0.9(postcss@8.5.6)': + dependencies: + '@csstools/css-calc': 2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + postcss: 8.5.6 + + '@csstools/postcss-syntax-descriptor-syntax-production@1.0.1(postcss@8.5.6)': + dependencies: + '@csstools/css-tokenizer': 3.0.4 + postcss: 8.5.6 + + '@csstools/postcss-system-ui-font-family@1.0.0(postcss@8.5.6)': + dependencies: + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + postcss: 8.5.6 + + '@csstools/postcss-text-decoration-shorthand@4.0.3(postcss@8.5.6)': + dependencies: + '@csstools/color-helpers': 5.1.0 + postcss: 8.5.6 + postcss-value-parser: 4.2.0 + + '@csstools/postcss-trigonometric-functions@4.0.9(postcss@8.5.6)': + dependencies: + '@csstools/css-calc': 2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + postcss: 8.5.6 + + '@csstools/postcss-unset-value@4.0.0(postcss@8.5.6)': + dependencies: + postcss: 8.5.6 + + '@csstools/selector-resolve-nested@3.1.0(postcss-selector-parser@7.1.1)': + dependencies: + postcss-selector-parser: 7.1.1 + + '@csstools/selector-specificity@5.0.0(postcss-selector-parser@7.1.1)': + dependencies: + postcss-selector-parser: 7.1.1 + + '@csstools/utilities@2.0.0(postcss@8.5.6)': + dependencies: + postcss: 8.5.6 + + '@discoveryjs/json-ext@0.5.7': {} + + '@docsearch/css@4.5.2': {} + + '@docsearch/react@4.5.2(@types/react@18.3.27)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + dependencies: + '@docsearch/css': 4.5.2 + optionalDependencies: + '@types/react': 18.3.27 + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + + '@docusaurus/babel@3.9.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + dependencies: + '@babel/core': 7.28.5 + '@babel/generator': 7.28.5 + '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.28.5) + '@babel/plugin-transform-runtime': 7.28.5(@babel/core@7.28.5) + '@babel/preset-env': 7.28.6(@babel/core@7.28.5) + '@babel/preset-react': 7.28.5(@babel/core@7.28.5) + '@babel/preset-typescript': 7.28.5(@babel/core@7.28.5) + '@babel/runtime': 7.28.4 + '@babel/runtime-corejs3': 7.28.6 + '@babel/traverse': 7.28.5 + '@docusaurus/logger': 3.9.2 + '@docusaurus/utils': 3.9.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + babel-plugin-dynamic-import-node: 2.3.3 + fs-extra: 11.3.3 + tslib: 2.8.1 + transitivePeerDependencies: + - '@swc/core' + - esbuild + - react + - react-dom + - supports-color + - uglify-js + - webpack-cli + + '@docusaurus/bundler@3.9.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.6.3)': + dependencies: + '@babel/core': 7.28.5 + '@docusaurus/babel': 3.9.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@docusaurus/cssnano-preset': 3.9.2 + '@docusaurus/logger': 3.9.2 + '@docusaurus/types': 3.9.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@docusaurus/utils': 3.9.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + babel-loader: 9.2.1(@babel/core@7.28.5)(webpack@5.104.1) + clean-css: 5.3.3 + copy-webpack-plugin: 11.0.0(webpack@5.104.1) + css-loader: 6.11.0(webpack@5.104.1) + css-minimizer-webpack-plugin: 5.0.1(clean-css@5.3.3)(webpack@5.104.1) + cssnano: 6.1.2(postcss@8.5.6) + file-loader: 6.2.0(webpack@5.104.1) + html-minifier-terser: 7.2.0 + mini-css-extract-plugin: 2.10.0(webpack@5.104.1) + null-loader: 4.0.1(webpack@5.104.1) + postcss: 8.5.6 + postcss-loader: 7.3.4(postcss@8.5.6)(typescript@5.6.3)(webpack@5.104.1) + postcss-preset-env: 10.6.1(postcss@8.5.6) + terser-webpack-plugin: 5.3.16(webpack@5.104.1) + tslib: 2.8.1 + url-loader: 4.1.1(file-loader@6.2.0(webpack@5.104.1))(webpack@5.104.1) + webpack: 5.104.1 + webpackbar: 6.0.1(webpack@5.104.1) + transitivePeerDependencies: + - '@parcel/css' + - '@rspack/core' + - '@swc/core' + - '@swc/css' + - csso + - esbuild + - lightningcss + - react + - react-dom + - supports-color + - typescript + - uglify-js + - webpack-cli + + '@docusaurus/core@3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.27)(react@19.2.3))(bufferutil@4.0.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.6.3)(utf-8-validate@5.0.10)': + dependencies: + '@docusaurus/babel': 3.9.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@docusaurus/bundler': 3.9.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.6.3) + '@docusaurus/logger': 3.9.2 + '@docusaurus/mdx-loader': 3.9.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@docusaurus/utils': 3.9.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@docusaurus/utils-common': 3.9.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@docusaurus/utils-validation': 3.9.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@mdx-js/react': 3.1.1(@types/react@18.3.27)(react@19.2.3) + boxen: 6.2.1 + chalk: 4.1.2 + chokidar: 3.6.0 + cli-table3: 0.6.5 + combine-promises: 1.2.0 + commander: 5.1.0 + core-js: 3.47.0 + detect-port: 1.6.1 + escape-html: 1.0.3 + eta: 2.2.0 + eval: 0.1.8 + execa: 5.1.1 + fs-extra: 11.3.3 + html-tags: 3.3.1 + html-webpack-plugin: 5.6.6(webpack@5.104.1) + leven: 3.1.0 + lodash: 4.17.21 + open: 8.4.2 + p-map: 4.0.0 + prompts: 2.4.2 + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + react-helmet-async: '@slorber/react-helmet-async@1.3.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3)' + react-loadable: '@docusaurus/react-loadable@6.0.0(react@19.2.3)' + react-loadable-ssr-addon-v5-slorber: 1.0.1(@docusaurus/react-loadable@6.0.0(react@19.2.3))(webpack@5.104.1) + react-router: 5.3.4(react@19.2.3) + react-router-config: 5.1.1(react-router@5.3.4(react@19.2.3))(react@19.2.3) + react-router-dom: 5.3.4(react@19.2.3) + semver: 7.7.3 + serve-handler: 6.1.6 + tinypool: 1.1.1 + tslib: 2.8.1 + update-notifier: 6.0.2 + webpack: 5.104.1 + webpack-bundle-analyzer: 4.10.2(bufferutil@4.0.9)(utf-8-validate@5.0.10) + webpack-dev-server: 5.2.3(bufferutil@4.0.9)(tslib@2.8.1)(utf-8-validate@5.0.10)(webpack@5.104.1) + webpack-merge: 6.0.1 + transitivePeerDependencies: + - '@docusaurus/faster' + - '@parcel/css' + - '@rspack/core' + - '@swc/core' + - '@swc/css' + - bufferutil + - csso + - debug + - esbuild + - lightningcss + - supports-color + - typescript + - uglify-js + - utf-8-validate + - webpack-cli + + '@docusaurus/cssnano-preset@3.9.2': + dependencies: + cssnano-preset-advanced: 6.1.2(postcss@8.5.6) + postcss: 8.5.6 + postcss-sort-media-queries: 5.2.0(postcss@8.5.6) + tslib: 2.8.1 + + '@docusaurus/logger@3.9.2': + dependencies: + chalk: 4.1.2 + tslib: 2.8.1 + + '@docusaurus/mdx-loader@3.9.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + dependencies: + '@docusaurus/logger': 3.9.2 + '@docusaurus/utils': 3.9.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@docusaurus/utils-validation': 3.9.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@mdx-js/mdx': 3.1.1 + '@slorber/remark-comment': 1.0.0 + escape-html: 1.0.3 + estree-util-value-to-estree: 3.5.0 + file-loader: 6.2.0(webpack@5.104.1) + fs-extra: 11.3.3 + image-size: 2.0.2 + mdast-util-mdx: 3.0.0 + mdast-util-to-string: 4.0.0 + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + rehype-raw: 7.0.0 + remark-directive: 3.0.1 + remark-emoji: 4.0.1 + remark-frontmatter: 5.0.0 + remark-gfm: 4.0.1 + stringify-object: 3.3.0 + tslib: 2.8.1 + unified: 11.0.5 + unist-util-visit: 5.0.0 + url-loader: 4.1.1(file-loader@6.2.0(webpack@5.104.1))(webpack@5.104.1) + vfile: 6.0.3 + webpack: 5.104.1 + transitivePeerDependencies: + - '@swc/core' + - esbuild + - supports-color + - uglify-js + - webpack-cli + + '@docusaurus/module-type-aliases@3.9.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + dependencies: + '@docusaurus/types': 3.9.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@types/history': 4.7.11 + '@types/react': 18.3.27 + '@types/react-router-config': 5.0.11 + '@types/react-router-dom': 5.3.3 + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + react-helmet-async: '@slorber/react-helmet-async@1.3.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3)' + react-loadable: '@docusaurus/react-loadable@6.0.0(react@19.2.3)' + transitivePeerDependencies: + - '@swc/core' + - esbuild + - supports-color + - uglify-js + - webpack-cli + + '@docusaurus/plugin-content-blog@3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.27)(react@19.2.3))(bufferutil@4.0.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.6.3)(utf-8-validate@5.0.10))(@mdx-js/react@3.1.1(@types/react@18.3.27)(react@19.2.3))(bufferutil@4.0.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.6.3)(utf-8-validate@5.0.10)': + dependencies: + '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.27)(react@19.2.3))(bufferutil@4.0.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.6.3)(utf-8-validate@5.0.10) + '@docusaurus/logger': 3.9.2 + '@docusaurus/mdx-loader': 3.9.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@docusaurus/plugin-content-docs': 3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.27)(react@19.2.3))(bufferutil@4.0.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.6.3)(utf-8-validate@5.0.10) + '@docusaurus/theme-common': 3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.27)(react@19.2.3))(bufferutil@4.0.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.6.3)(utf-8-validate@5.0.10))(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@docusaurus/types': 3.9.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@docusaurus/utils': 3.9.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@docusaurus/utils-common': 3.9.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@docusaurus/utils-validation': 3.9.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + cheerio: 1.0.0-rc.12 + feed: 4.2.2 + fs-extra: 11.3.3 + lodash: 4.17.21 + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + schema-dts: 1.1.5 + srcset: 4.0.0 + tslib: 2.8.1 + unist-util-visit: 5.0.0 + utility-types: 3.11.0 + webpack: 5.104.1 + transitivePeerDependencies: + - '@docusaurus/faster' + - '@mdx-js/react' + - '@parcel/css' + - '@rspack/core' + - '@swc/core' + - '@swc/css' + - bufferutil + - csso + - debug + - esbuild + - lightningcss + - supports-color + - typescript + - uglify-js + - utf-8-validate + - webpack-cli + + '@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.27)(react@19.2.3))(bufferutil@4.0.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.6.3)(utf-8-validate@5.0.10)': + dependencies: + '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.27)(react@19.2.3))(bufferutil@4.0.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.6.3)(utf-8-validate@5.0.10) + '@docusaurus/logger': 3.9.2 + '@docusaurus/mdx-loader': 3.9.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@docusaurus/module-type-aliases': 3.9.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@docusaurus/theme-common': 3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.27)(react@19.2.3))(bufferutil@4.0.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.6.3)(utf-8-validate@5.0.10))(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@docusaurus/types': 3.9.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@docusaurus/utils': 3.9.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@docusaurus/utils-common': 3.9.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@docusaurus/utils-validation': 3.9.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@types/react-router-config': 5.0.11 + combine-promises: 1.2.0 + fs-extra: 11.3.3 + js-yaml: 4.1.1 + lodash: 4.17.21 + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + schema-dts: 1.1.5 + tslib: 2.8.1 + utility-types: 3.11.0 + webpack: 5.104.1 + transitivePeerDependencies: + - '@docusaurus/faster' + - '@mdx-js/react' + - '@parcel/css' + - '@rspack/core' + - '@swc/core' + - '@swc/css' + - bufferutil + - csso + - debug + - esbuild + - lightningcss + - supports-color + - typescript + - uglify-js + - utf-8-validate + - webpack-cli + + '@docusaurus/plugin-content-pages@3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.27)(react@19.2.3))(bufferutil@4.0.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.6.3)(utf-8-validate@5.0.10)': + dependencies: + '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.27)(react@19.2.3))(bufferutil@4.0.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.6.3)(utf-8-validate@5.0.10) + '@docusaurus/mdx-loader': 3.9.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@docusaurus/types': 3.9.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@docusaurus/utils': 3.9.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@docusaurus/utils-validation': 3.9.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + fs-extra: 11.3.3 + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + tslib: 2.8.1 + webpack: 5.104.1 + transitivePeerDependencies: + - '@docusaurus/faster' + - '@mdx-js/react' + - '@parcel/css' + - '@rspack/core' + - '@swc/core' + - '@swc/css' + - bufferutil + - csso + - debug + - esbuild + - lightningcss + - supports-color + - typescript + - uglify-js + - utf-8-validate + - webpack-cli + + '@docusaurus/plugin-css-cascade-layers@3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.27)(react@19.2.3))(bufferutil@4.0.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.6.3)(utf-8-validate@5.0.10)': + dependencies: + '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.27)(react@19.2.3))(bufferutil@4.0.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.6.3)(utf-8-validate@5.0.10) + '@docusaurus/types': 3.9.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@docusaurus/utils': 3.9.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@docusaurus/utils-validation': 3.9.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + tslib: 2.8.1 + transitivePeerDependencies: + - '@docusaurus/faster' + - '@mdx-js/react' + - '@parcel/css' + - '@rspack/core' + - '@swc/core' + - '@swc/css' + - bufferutil + - csso + - debug + - esbuild + - lightningcss + - react + - react-dom + - supports-color + - typescript + - uglify-js + - utf-8-validate + - webpack-cli + + '@docusaurus/plugin-debug@3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.27)(react@19.2.3))(bufferutil@4.0.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.6.3)(utf-8-validate@5.0.10)': + dependencies: + '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.27)(react@19.2.3))(bufferutil@4.0.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.6.3)(utf-8-validate@5.0.10) + '@docusaurus/types': 3.9.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@docusaurus/utils': 3.9.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + fs-extra: 11.3.3 + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + react-json-view-lite: 2.5.0(react@19.2.3) + tslib: 2.8.1 + transitivePeerDependencies: + - '@docusaurus/faster' + - '@mdx-js/react' + - '@parcel/css' + - '@rspack/core' + - '@swc/core' + - '@swc/css' + - bufferutil + - csso + - debug + - esbuild + - lightningcss + - supports-color + - typescript + - uglify-js + - utf-8-validate + - webpack-cli + + '@docusaurus/plugin-google-analytics@3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.27)(react@19.2.3))(bufferutil@4.0.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.6.3)(utf-8-validate@5.0.10)': + dependencies: + '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.27)(react@19.2.3))(bufferutil@4.0.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.6.3)(utf-8-validate@5.0.10) + '@docusaurus/types': 3.9.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@docusaurus/utils-validation': 3.9.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + tslib: 2.8.1 + transitivePeerDependencies: + - '@docusaurus/faster' + - '@mdx-js/react' + - '@parcel/css' + - '@rspack/core' + - '@swc/core' + - '@swc/css' + - bufferutil + - csso + - debug + - esbuild + - lightningcss + - supports-color + - typescript + - uglify-js + - utf-8-validate + - webpack-cli + + '@docusaurus/plugin-google-gtag@3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.27)(react@19.2.3))(bufferutil@4.0.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.6.3)(utf-8-validate@5.0.10)': + dependencies: + '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.27)(react@19.2.3))(bufferutil@4.0.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.6.3)(utf-8-validate@5.0.10) + '@docusaurus/types': 3.9.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@docusaurus/utils-validation': 3.9.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@types/gtag.js': 0.0.12 + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + tslib: 2.8.1 + transitivePeerDependencies: + - '@docusaurus/faster' + - '@mdx-js/react' + - '@parcel/css' + - '@rspack/core' + - '@swc/core' + - '@swc/css' + - bufferutil + - csso + - debug + - esbuild + - lightningcss + - supports-color + - typescript + - uglify-js + - utf-8-validate + - webpack-cli + + '@docusaurus/plugin-google-tag-manager@3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.27)(react@19.2.3))(bufferutil@4.0.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.6.3)(utf-8-validate@5.0.10)': + dependencies: + '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.27)(react@19.2.3))(bufferutil@4.0.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.6.3)(utf-8-validate@5.0.10) + '@docusaurus/types': 3.9.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@docusaurus/utils-validation': 3.9.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + tslib: 2.8.1 + transitivePeerDependencies: + - '@docusaurus/faster' + - '@mdx-js/react' + - '@parcel/css' + - '@rspack/core' + - '@swc/core' + - '@swc/css' + - bufferutil + - csso + - debug + - esbuild + - lightningcss + - supports-color + - typescript + - uglify-js + - utf-8-validate + - webpack-cli + + '@docusaurus/plugin-sitemap@3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.27)(react@19.2.3))(bufferutil@4.0.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.6.3)(utf-8-validate@5.0.10)': + dependencies: + '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.27)(react@19.2.3))(bufferutil@4.0.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.6.3)(utf-8-validate@5.0.10) + '@docusaurus/logger': 3.9.2 + '@docusaurus/types': 3.9.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@docusaurus/utils': 3.9.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@docusaurus/utils-common': 3.9.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@docusaurus/utils-validation': 3.9.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + fs-extra: 11.3.3 + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + sitemap: 7.1.2 + tslib: 2.8.1 + transitivePeerDependencies: + - '@docusaurus/faster' + - '@mdx-js/react' + - '@parcel/css' + - '@rspack/core' + - '@swc/core' + - '@swc/css' + - bufferutil + - csso + - debug + - esbuild + - lightningcss + - supports-color + - typescript + - uglify-js + - utf-8-validate + - webpack-cli + + '@docusaurus/plugin-svgr@3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.27)(react@19.2.3))(bufferutil@4.0.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.6.3)(utf-8-validate@5.0.10)': + dependencies: + '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.27)(react@19.2.3))(bufferutil@4.0.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.6.3)(utf-8-validate@5.0.10) + '@docusaurus/types': 3.9.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@docusaurus/utils': 3.9.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@docusaurus/utils-validation': 3.9.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@svgr/core': 8.1.0(typescript@5.6.3) + '@svgr/webpack': 8.1.0(typescript@5.6.3) + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + tslib: 2.8.1 + webpack: 5.104.1 + transitivePeerDependencies: + - '@docusaurus/faster' + - '@mdx-js/react' + - '@parcel/css' + - '@rspack/core' + - '@swc/core' + - '@swc/css' + - bufferutil + - csso + - debug + - esbuild + - lightningcss + - supports-color + - typescript + - uglify-js + - utf-8-validate + - webpack-cli + + '@docusaurus/preset-classic@3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.27)(react@19.2.3))(@types/react@18.3.27)(bufferutil@4.0.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.6.3)(utf-8-validate@5.0.10)': + dependencies: + '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.27)(react@19.2.3))(bufferutil@4.0.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.6.3)(utf-8-validate@5.0.10) + '@docusaurus/plugin-content-blog': 3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.27)(react@19.2.3))(bufferutil@4.0.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.6.3)(utf-8-validate@5.0.10))(@mdx-js/react@3.1.1(@types/react@18.3.27)(react@19.2.3))(bufferutil@4.0.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.6.3)(utf-8-validate@5.0.10) + '@docusaurus/plugin-content-docs': 3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.27)(react@19.2.3))(bufferutil@4.0.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.6.3)(utf-8-validate@5.0.10) + '@docusaurus/plugin-content-pages': 3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.27)(react@19.2.3))(bufferutil@4.0.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.6.3)(utf-8-validate@5.0.10) + '@docusaurus/plugin-css-cascade-layers': 3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.27)(react@19.2.3))(bufferutil@4.0.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.6.3)(utf-8-validate@5.0.10) + '@docusaurus/plugin-debug': 3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.27)(react@19.2.3))(bufferutil@4.0.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.6.3)(utf-8-validate@5.0.10) + '@docusaurus/plugin-google-analytics': 3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.27)(react@19.2.3))(bufferutil@4.0.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.6.3)(utf-8-validate@5.0.10) + '@docusaurus/plugin-google-gtag': 3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.27)(react@19.2.3))(bufferutil@4.0.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.6.3)(utf-8-validate@5.0.10) + '@docusaurus/plugin-google-tag-manager': 3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.27)(react@19.2.3))(bufferutil@4.0.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.6.3)(utf-8-validate@5.0.10) + '@docusaurus/plugin-sitemap': 3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.27)(react@19.2.3))(bufferutil@4.0.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.6.3)(utf-8-validate@5.0.10) + '@docusaurus/plugin-svgr': 3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.27)(react@19.2.3))(bufferutil@4.0.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.6.3)(utf-8-validate@5.0.10) + '@docusaurus/theme-classic': 3.9.2(@types/react@18.3.27)(bufferutil@4.0.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.6.3)(utf-8-validate@5.0.10) + '@docusaurus/theme-common': 3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.27)(react@19.2.3))(bufferutil@4.0.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.6.3)(utf-8-validate@5.0.10))(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@docusaurus/theme-search-algolia': 3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.27)(react@19.2.3))(@types/react@18.3.27)(bufferutil@4.0.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.6.3)(utf-8-validate@5.0.10) + '@docusaurus/types': 3.9.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + transitivePeerDependencies: + - '@docusaurus/faster' + - '@mdx-js/react' + - '@parcel/css' + - '@rspack/core' + - '@swc/core' + - '@swc/css' + - '@types/react' + - bufferutil + - csso + - debug + - esbuild + - lightningcss + - search-insights + - supports-color + - typescript + - uglify-js + - utf-8-validate + - webpack-cli + + '@docusaurus/react-loadable@6.0.0(react@19.2.3)': + dependencies: + '@types/react': 18.3.27 + react: 19.2.3 + + '@docusaurus/theme-classic@3.9.2(@types/react@18.3.27)(bufferutil@4.0.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.6.3)(utf-8-validate@5.0.10)': + dependencies: + '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.27)(react@19.2.3))(bufferutil@4.0.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.6.3)(utf-8-validate@5.0.10) + '@docusaurus/logger': 3.9.2 + '@docusaurus/mdx-loader': 3.9.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@docusaurus/module-type-aliases': 3.9.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@docusaurus/plugin-content-blog': 3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.27)(react@19.2.3))(bufferutil@4.0.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.6.3)(utf-8-validate@5.0.10))(@mdx-js/react@3.1.1(@types/react@18.3.27)(react@19.2.3))(bufferutil@4.0.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.6.3)(utf-8-validate@5.0.10) + '@docusaurus/plugin-content-docs': 3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.27)(react@19.2.3))(bufferutil@4.0.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.6.3)(utf-8-validate@5.0.10) + '@docusaurus/plugin-content-pages': 3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.27)(react@19.2.3))(bufferutil@4.0.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.6.3)(utf-8-validate@5.0.10) + '@docusaurus/theme-common': 3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.27)(react@19.2.3))(bufferutil@4.0.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.6.3)(utf-8-validate@5.0.10))(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@docusaurus/theme-translations': 3.9.2 + '@docusaurus/types': 3.9.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@docusaurus/utils': 3.9.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@docusaurus/utils-common': 3.9.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@docusaurus/utils-validation': 3.9.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@mdx-js/react': 3.1.1(@types/react@18.3.27)(react@19.2.3) + clsx: 2.1.1 + infima: 0.2.0-alpha.45 + lodash: 4.17.21 + nprogress: 0.2.0 + postcss: 8.5.6 + prism-react-renderer: 2.4.1(react@19.2.3) + prismjs: 1.30.0 + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + react-router-dom: 5.3.4(react@19.2.3) + rtlcss: 4.3.0 + tslib: 2.8.1 + utility-types: 3.11.0 + transitivePeerDependencies: + - '@docusaurus/faster' + - '@parcel/css' + - '@rspack/core' + - '@swc/core' + - '@swc/css' + - '@types/react' + - bufferutil + - csso + - debug + - esbuild + - lightningcss + - supports-color + - typescript + - uglify-js + - utf-8-validate + - webpack-cli + + '@docusaurus/theme-common@3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.27)(react@19.2.3))(bufferutil@4.0.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.6.3)(utf-8-validate@5.0.10))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + dependencies: + '@docusaurus/mdx-loader': 3.9.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@docusaurus/module-type-aliases': 3.9.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@docusaurus/plugin-content-docs': 3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.27)(react@19.2.3))(bufferutil@4.0.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.6.3)(utf-8-validate@5.0.10) + '@docusaurus/utils': 3.9.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@docusaurus/utils-common': 3.9.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@types/history': 4.7.11 + '@types/react': 18.3.27 + '@types/react-router-config': 5.0.11 + clsx: 2.1.1 + parse-numeric-range: 1.3.0 + prism-react-renderer: 2.4.1(react@19.2.3) + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + tslib: 2.8.1 + utility-types: 3.11.0 + transitivePeerDependencies: + - '@swc/core' + - esbuild + - supports-color + - uglify-js + - webpack-cli + + '@docusaurus/theme-search-algolia@3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.27)(react@19.2.3))(@types/react@18.3.27)(bufferutil@4.0.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.6.3)(utf-8-validate@5.0.10)': + dependencies: + '@docsearch/react': 4.5.2(@types/react@18.3.27)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.27)(react@19.2.3))(bufferutil@4.0.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.6.3)(utf-8-validate@5.0.10) + '@docusaurus/logger': 3.9.2 + '@docusaurus/plugin-content-docs': 3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.27)(react@19.2.3))(bufferutil@4.0.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.6.3)(utf-8-validate@5.0.10) + '@docusaurus/theme-common': 3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.27)(react@19.2.3))(bufferutil@4.0.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.6.3)(utf-8-validate@5.0.10))(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@docusaurus/theme-translations': 3.9.2 + '@docusaurus/utils': 3.9.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@docusaurus/utils-validation': 3.9.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + algoliasearch: 5.47.0 + algoliasearch-helper: 3.27.0(algoliasearch@5.47.0) + clsx: 2.1.1 + eta: 2.2.0 + fs-extra: 11.3.3 + lodash: 4.17.21 + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + tslib: 2.8.1 + utility-types: 3.11.0 + transitivePeerDependencies: + - '@docusaurus/faster' + - '@mdx-js/react' + - '@parcel/css' + - '@rspack/core' + - '@swc/core' + - '@swc/css' + - '@types/react' + - bufferutil + - csso + - debug + - esbuild + - lightningcss + - search-insights + - supports-color + - typescript + - uglify-js + - utf-8-validate + - webpack-cli + + '@docusaurus/theme-translations@3.9.2': + dependencies: + fs-extra: 11.3.3 + tslib: 2.8.1 + + '@docusaurus/tsconfig@3.9.2': {} + + '@docusaurus/types@3.9.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + dependencies: + '@mdx-js/mdx': 3.1.1 + '@types/history': 4.7.11 + '@types/mdast': 4.0.4 + '@types/react': 18.3.27 + commander: 5.1.0 + joi: 17.13.3 + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + react-helmet-async: '@slorber/react-helmet-async@1.3.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3)' + utility-types: 3.11.0 + webpack: 5.104.1 + webpack-merge: 5.10.0 + transitivePeerDependencies: + - '@swc/core' + - esbuild + - supports-color + - uglify-js + - webpack-cli + + '@docusaurus/utils-common@3.9.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + dependencies: + '@docusaurus/types': 3.9.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + tslib: 2.8.1 + transitivePeerDependencies: + - '@swc/core' + - esbuild + - react + - react-dom + - supports-color + - uglify-js + - webpack-cli + + '@docusaurus/utils-validation@3.9.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + dependencies: + '@docusaurus/logger': 3.9.2 + '@docusaurus/utils': 3.9.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@docusaurus/utils-common': 3.9.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + fs-extra: 11.3.3 + joi: 17.13.3 + js-yaml: 4.1.1 + lodash: 4.17.21 + tslib: 2.8.1 + transitivePeerDependencies: + - '@swc/core' + - esbuild + - react + - react-dom + - supports-color + - uglify-js + - webpack-cli + + '@docusaurus/utils@3.9.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + dependencies: + '@docusaurus/logger': 3.9.2 + '@docusaurus/types': 3.9.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@docusaurus/utils-common': 3.9.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + escape-string-regexp: 4.0.0 + execa: 5.1.1 + file-loader: 6.2.0(webpack@5.104.1) + fs-extra: 11.3.3 + github-slugger: 1.5.0 + globby: 11.1.0 + gray-matter: 4.0.3 + jiti: 1.21.7 + js-yaml: 4.1.1 + lodash: 4.17.21 + micromatch: 4.0.8 + p-queue: 6.6.2 + prompts: 2.4.2 + resolve-pathname: 3.0.0 + tslib: 2.8.1 + url-loader: 4.1.1(file-loader@6.2.0(webpack@5.104.1))(webpack@5.104.1) + utility-types: 3.11.0 + webpack: 5.104.1 + transitivePeerDependencies: + - '@swc/core' + - esbuild + - react + - react-dom + - supports-color + - uglify-js + - webpack-cli + + '@ecies/ciphers@0.2.5(@noble/ciphers@1.3.0)': + dependencies: + '@noble/ciphers': 1.3.0 + + '@emotion/hash@0.9.2': {} + + '@esbuild/aix-ppc64@0.21.5': + optional: true + + '@esbuild/android-arm64@0.21.5': + optional: true + + '@esbuild/android-arm@0.21.5': + optional: true + + '@esbuild/android-x64@0.21.5': + optional: true + + '@esbuild/darwin-arm64@0.21.5': + optional: true + + '@esbuild/darwin-x64@0.21.5': + optional: true + + '@esbuild/freebsd-arm64@0.21.5': + optional: true + + '@esbuild/freebsd-x64@0.21.5': + optional: true + + '@esbuild/linux-arm64@0.21.5': + optional: true + + '@esbuild/linux-arm@0.21.5': + optional: true + + '@esbuild/linux-ia32@0.21.5': + optional: true + + '@esbuild/linux-loong64@0.21.5': + optional: true + + '@esbuild/linux-mips64el@0.21.5': + optional: true + + '@esbuild/linux-ppc64@0.21.5': + optional: true + + '@esbuild/linux-riscv64@0.21.5': + optional: true + + '@esbuild/linux-s390x@0.21.5': + optional: true + + '@esbuild/linux-x64@0.21.5': + optional: true + + '@esbuild/netbsd-x64@0.21.5': + optional: true + + '@esbuild/openbsd-x64@0.21.5': + optional: true + + '@esbuild/sunos-x64@0.21.5': + optional: true + + '@esbuild/win32-arm64@0.21.5': + optional: true + + '@esbuild/win32-ia32@0.21.5': + optional: true + + '@esbuild/win32-x64@0.21.5': + optional: true + + '@ethereumjs/common@3.2.0': + dependencies: + '@ethereumjs/util': 8.1.0 + crc-32: 1.2.2 + + '@ethereumjs/rlp@4.0.1': {} + + '@ethereumjs/rlp@5.0.2': {} + + '@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 + + '@ethereumjs/util@9.1.0': + dependencies: + '@ethereumjs/rlp': 5.0.2 + ethereum-cryptography: 2.2.1 + + '@ethersproject/abi@5.8.0': + dependencies: + '@ethersproject/address': 5.8.0 + '@ethersproject/bignumber': 5.8.0 + '@ethersproject/bytes': 5.8.0 + '@ethersproject/constants': 5.8.0 + '@ethersproject/hash': 5.8.0 + '@ethersproject/keccak256': 5.8.0 + '@ethersproject/logger': 5.8.0 + '@ethersproject/properties': 5.8.0 + '@ethersproject/strings': 5.8.0 + + '@ethersproject/abstract-provider@5.8.0': + dependencies: + '@ethersproject/bignumber': 5.8.0 + '@ethersproject/bytes': 5.8.0 + '@ethersproject/logger': 5.8.0 + '@ethersproject/networks': 5.8.0 + '@ethersproject/properties': 5.8.0 + '@ethersproject/transactions': 5.8.0 + '@ethersproject/web': 5.8.0 + + '@ethersproject/abstract-signer@5.8.0': + dependencies: + '@ethersproject/abstract-provider': 5.8.0 + '@ethersproject/bignumber': 5.8.0 + '@ethersproject/bytes': 5.8.0 + '@ethersproject/logger': 5.8.0 + '@ethersproject/properties': 5.8.0 + + '@ethersproject/address@5.6.1': + dependencies: + '@ethersproject/bignumber': 5.8.0 + '@ethersproject/bytes': 5.8.0 + '@ethersproject/keccak256': 5.8.0 + '@ethersproject/logger': 5.8.0 + '@ethersproject/rlp': 5.8.0 + + '@ethersproject/address@5.8.0': + dependencies: + '@ethersproject/bignumber': 5.8.0 + '@ethersproject/bytes': 5.8.0 + '@ethersproject/keccak256': 5.8.0 + '@ethersproject/logger': 5.8.0 + '@ethersproject/rlp': 5.8.0 + + '@ethersproject/base64@5.8.0': + dependencies: + '@ethersproject/bytes': 5.8.0 + + '@ethersproject/basex@5.8.0': + dependencies: + '@ethersproject/bytes': 5.8.0 + '@ethersproject/properties': 5.8.0 + + '@ethersproject/bignumber@5.8.0': + dependencies: + '@ethersproject/bytes': 5.8.0 + '@ethersproject/logger': 5.8.0 + bn.js: 5.2.2 + + '@ethersproject/bytes@5.8.0': + dependencies: + '@ethersproject/logger': 5.8.0 + + '@ethersproject/constants@5.8.0': + dependencies: + '@ethersproject/bignumber': 5.8.0 + + '@ethersproject/contracts@5.8.0': + dependencies: + '@ethersproject/abi': 5.8.0 + '@ethersproject/abstract-provider': 5.8.0 + '@ethersproject/abstract-signer': 5.8.0 + '@ethersproject/address': 5.8.0 + '@ethersproject/bignumber': 5.8.0 + '@ethersproject/bytes': 5.8.0 + '@ethersproject/constants': 5.8.0 + '@ethersproject/logger': 5.8.0 + '@ethersproject/properties': 5.8.0 + '@ethersproject/transactions': 5.8.0 + + '@ethersproject/hash@5.8.0': + dependencies: + '@ethersproject/abstract-signer': 5.8.0 + '@ethersproject/address': 5.8.0 + '@ethersproject/base64': 5.8.0 + '@ethersproject/bignumber': 5.8.0 + '@ethersproject/bytes': 5.8.0 + '@ethersproject/keccak256': 5.8.0 + '@ethersproject/logger': 5.8.0 + '@ethersproject/properties': 5.8.0 + '@ethersproject/strings': 5.8.0 + + '@ethersproject/hdnode@5.8.0': + dependencies: + '@ethersproject/abstract-signer': 5.8.0 + '@ethersproject/basex': 5.8.0 + '@ethersproject/bignumber': 5.8.0 + '@ethersproject/bytes': 5.8.0 + '@ethersproject/logger': 5.8.0 + '@ethersproject/pbkdf2': 5.8.0 + '@ethersproject/properties': 5.8.0 + '@ethersproject/sha2': 5.8.0 + '@ethersproject/signing-key': 5.8.0 + '@ethersproject/strings': 5.8.0 + '@ethersproject/transactions': 5.8.0 + '@ethersproject/wordlists': 5.8.0 + + '@ethersproject/json-wallets@5.8.0': + dependencies: + '@ethersproject/abstract-signer': 5.8.0 + '@ethersproject/address': 5.8.0 + '@ethersproject/bytes': 5.8.0 + '@ethersproject/hdnode': 5.8.0 + '@ethersproject/keccak256': 5.8.0 + '@ethersproject/logger': 5.8.0 + '@ethersproject/pbkdf2': 5.8.0 + '@ethersproject/properties': 5.8.0 + '@ethersproject/random': 5.8.0 + '@ethersproject/strings': 5.8.0 + '@ethersproject/transactions': 5.8.0 + aes-js: 3.0.0 + scrypt-js: 3.0.1 + + '@ethersproject/keccak256@5.8.0': + dependencies: + '@ethersproject/bytes': 5.8.0 + js-sha3: 0.8.0 + + '@ethersproject/logger@5.8.0': {} + + '@ethersproject/networks@5.8.0': + dependencies: + '@ethersproject/logger': 5.8.0 + + '@ethersproject/pbkdf2@5.8.0': + dependencies: + '@ethersproject/bytes': 5.8.0 + '@ethersproject/sha2': 5.8.0 + + '@ethersproject/properties@5.8.0': + dependencies: + '@ethersproject/logger': 5.8.0 + + '@ethersproject/providers@5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)': + dependencies: + '@ethersproject/abstract-provider': 5.8.0 + '@ethersproject/abstract-signer': 5.8.0 + '@ethersproject/address': 5.8.0 + '@ethersproject/base64': 5.8.0 + '@ethersproject/basex': 5.8.0 + '@ethersproject/bignumber': 5.8.0 + '@ethersproject/bytes': 5.8.0 + '@ethersproject/constants': 5.8.0 + '@ethersproject/hash': 5.8.0 + '@ethersproject/logger': 5.8.0 + '@ethersproject/networks': 5.8.0 + '@ethersproject/properties': 5.8.0 + '@ethersproject/random': 5.8.0 + '@ethersproject/rlp': 5.8.0 + '@ethersproject/sha2': 5.8.0 + '@ethersproject/strings': 5.8.0 + '@ethersproject/transactions': 5.8.0 + '@ethersproject/web': 5.8.0 + bech32: 1.1.4 + ws: 8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + '@ethersproject/random@5.8.0': + dependencies: + '@ethersproject/bytes': 5.8.0 + '@ethersproject/logger': 5.8.0 + + '@ethersproject/rlp@5.8.0': + dependencies: + '@ethersproject/bytes': 5.8.0 + '@ethersproject/logger': 5.8.0 + + '@ethersproject/sha2@5.8.0': + dependencies: + '@ethersproject/bytes': 5.8.0 + '@ethersproject/logger': 5.8.0 + hash.js: 1.1.7 + + '@ethersproject/signing-key@5.8.0': + dependencies: + '@ethersproject/bytes': 5.8.0 + '@ethersproject/logger': 5.8.0 + '@ethersproject/properties': 5.8.0 + bn.js: 5.2.2 + elliptic: 6.6.1 + hash.js: 1.1.7 + + '@ethersproject/solidity@5.8.0': + dependencies: + '@ethersproject/bignumber': 5.8.0 + '@ethersproject/bytes': 5.8.0 + '@ethersproject/keccak256': 5.8.0 + '@ethersproject/logger': 5.8.0 + '@ethersproject/sha2': 5.8.0 + '@ethersproject/strings': 5.8.0 + + '@ethersproject/strings@5.8.0': + dependencies: + '@ethersproject/bytes': 5.8.0 + '@ethersproject/constants': 5.8.0 + '@ethersproject/logger': 5.8.0 + + '@ethersproject/transactions@5.8.0': + dependencies: + '@ethersproject/address': 5.8.0 + '@ethersproject/bignumber': 5.8.0 + '@ethersproject/bytes': 5.8.0 + '@ethersproject/constants': 5.8.0 + '@ethersproject/keccak256': 5.8.0 + '@ethersproject/logger': 5.8.0 + '@ethersproject/properties': 5.8.0 + '@ethersproject/rlp': 5.8.0 + '@ethersproject/signing-key': 5.8.0 + + '@ethersproject/units@5.8.0': + dependencies: + '@ethersproject/bignumber': 5.8.0 + '@ethersproject/constants': 5.8.0 + '@ethersproject/logger': 5.8.0 + + '@ethersproject/wallet@5.8.0': + dependencies: + '@ethersproject/abstract-provider': 5.8.0 + '@ethersproject/abstract-signer': 5.8.0 + '@ethersproject/address': 5.8.0 + '@ethersproject/bignumber': 5.8.0 + '@ethersproject/bytes': 5.8.0 + '@ethersproject/hash': 5.8.0 + '@ethersproject/hdnode': 5.8.0 + '@ethersproject/json-wallets': 5.8.0 + '@ethersproject/keccak256': 5.8.0 + '@ethersproject/logger': 5.8.0 + '@ethersproject/properties': 5.8.0 + '@ethersproject/random': 5.8.0 + '@ethersproject/signing-key': 5.8.0 + '@ethersproject/transactions': 5.8.0 + '@ethersproject/wordlists': 5.8.0 + + '@ethersproject/web@5.8.0': + dependencies: + '@ethersproject/base64': 5.8.0 + '@ethersproject/bytes': 5.8.0 + '@ethersproject/logger': 5.8.0 + '@ethersproject/properties': 5.8.0 + '@ethersproject/strings': 5.8.0 + + '@ethersproject/wordlists@5.8.0': + dependencies: + '@ethersproject/bytes': 5.8.0 + '@ethersproject/hash': 5.8.0 + '@ethersproject/logger': 5.8.0 + '@ethersproject/properties': 5.8.0 + '@ethersproject/strings': 5.8.0 + + '@fastify/busboy@2.1.1': {} + + '@gemini-wallet/core@0.3.2(viem@2.43.1(bufferutil@4.0.9)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.25.76))': + dependencies: + '@metamask/rpc-errors': 7.0.2 + eventemitter3: 5.0.1 + viem: 2.43.1(bufferutil@4.0.9)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.25.76) + transitivePeerDependencies: + - supports-color + + '@hapi/hoek@9.3.0': {} + + '@hapi/topo@5.1.0': + dependencies: + '@hapi/hoek': 9.3.0 + + '@isaacs/balanced-match@4.0.1': {} + + '@isaacs/brace-expansion@5.0.0': + dependencies: + '@isaacs/balanced-match': 4.0.1 + + '@jest/schemas@29.6.3': + dependencies: + '@sinclair/typebox': 0.27.8 + + '@jest/types@29.6.3': + dependencies: + '@jest/schemas': 29.6.3 + '@types/istanbul-lib-coverage': 2.0.6 + '@types/istanbul-reports': 3.0.4 + '@types/node': 20.19.27 + '@types/yargs': 17.0.35 + chalk: 4.1.2 + + '@jridgewell/gen-mapping@0.3.13': + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/remapping@2.3.5': + dependencies: + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/source-map@0.3.11': + dependencies: + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/sourcemap-codec@1.5.5': {} + + '@jridgewell/trace-mapping@0.3.31': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.5 + + '@jridgewell/trace-mapping@0.3.9': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.5 + + '@jsonjoy.com/base64@1.1.2(tslib@2.8.1)': + dependencies: + tslib: 2.8.1 + + '@jsonjoy.com/base64@17.65.0(tslib@2.8.1)': + dependencies: + tslib: 2.8.1 + + '@jsonjoy.com/buffers@1.2.1(tslib@2.8.1)': + dependencies: + tslib: 2.8.1 + + '@jsonjoy.com/buffers@17.65.0(tslib@2.8.1)': + dependencies: + tslib: 2.8.1 + + '@jsonjoy.com/codegen@1.0.0(tslib@2.8.1)': + dependencies: + tslib: 2.8.1 + + '@jsonjoy.com/codegen@17.65.0(tslib@2.8.1)': + dependencies: + tslib: 2.8.1 + + '@jsonjoy.com/fs-core@4.56.4(tslib@2.8.1)': + dependencies: + '@jsonjoy.com/fs-node-builtins': 4.56.4(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.56.4(tslib@2.8.1) + thingies: 2.5.0(tslib@2.8.1) + tslib: 2.8.1 + + '@jsonjoy.com/fs-fsa@4.56.4(tslib@2.8.1)': + dependencies: + '@jsonjoy.com/fs-core': 4.56.4(tslib@2.8.1) + '@jsonjoy.com/fs-node-builtins': 4.56.4(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.56.4(tslib@2.8.1) + thingies: 2.5.0(tslib@2.8.1) + tslib: 2.8.1 + + '@jsonjoy.com/fs-node-builtins@4.56.4(tslib@2.8.1)': + dependencies: + tslib: 2.8.1 + + '@jsonjoy.com/fs-node-to-fsa@4.56.4(tslib@2.8.1)': + dependencies: + '@jsonjoy.com/fs-fsa': 4.56.4(tslib@2.8.1) + '@jsonjoy.com/fs-node-builtins': 4.56.4(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.56.4(tslib@2.8.1) + tslib: 2.8.1 + + '@jsonjoy.com/fs-node-utils@4.56.4(tslib@2.8.1)': + dependencies: + '@jsonjoy.com/fs-node-builtins': 4.56.4(tslib@2.8.1) + tslib: 2.8.1 + + '@jsonjoy.com/fs-node@4.56.4(tslib@2.8.1)': + dependencies: + '@jsonjoy.com/fs-core': 4.56.4(tslib@2.8.1) + '@jsonjoy.com/fs-node-builtins': 4.56.4(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.56.4(tslib@2.8.1) + '@jsonjoy.com/fs-print': 4.56.4(tslib@2.8.1) + glob-to-regex.js: 1.2.0(tslib@2.8.1) + thingies: 2.5.0(tslib@2.8.1) + tslib: 2.8.1 + + '@jsonjoy.com/fs-print@4.56.4(tslib@2.8.1)': + dependencies: + '@jsonjoy.com/fs-node-utils': 4.56.4(tslib@2.8.1) + tree-dump: 1.1.0(tslib@2.8.1) + tslib: 2.8.1 + + '@jsonjoy.com/fs-snapshot@4.56.4(tslib@2.8.1)': + dependencies: + '@jsonjoy.com/buffers': 17.65.0(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.56.4(tslib@2.8.1) + '@jsonjoy.com/json-pack': 17.65.0(tslib@2.8.1) + '@jsonjoy.com/util': 17.65.0(tslib@2.8.1) + tslib: 2.8.1 + + '@jsonjoy.com/json-pack@1.21.0(tslib@2.8.1)': + dependencies: + '@jsonjoy.com/base64': 1.1.2(tslib@2.8.1) + '@jsonjoy.com/buffers': 1.2.1(tslib@2.8.1) + '@jsonjoy.com/codegen': 1.0.0(tslib@2.8.1) + '@jsonjoy.com/json-pointer': 1.0.2(tslib@2.8.1) + '@jsonjoy.com/util': 1.9.0(tslib@2.8.1) + hyperdyperid: 1.2.0 + thingies: 2.5.0(tslib@2.8.1) + tree-dump: 1.1.0(tslib@2.8.1) + tslib: 2.8.1 + + '@jsonjoy.com/json-pack@17.65.0(tslib@2.8.1)': + dependencies: + '@jsonjoy.com/base64': 17.65.0(tslib@2.8.1) + '@jsonjoy.com/buffers': 17.65.0(tslib@2.8.1) + '@jsonjoy.com/codegen': 17.65.0(tslib@2.8.1) + '@jsonjoy.com/json-pointer': 17.65.0(tslib@2.8.1) + '@jsonjoy.com/util': 17.65.0(tslib@2.8.1) + hyperdyperid: 1.2.0 + thingies: 2.5.0(tslib@2.8.1) + tree-dump: 1.1.0(tslib@2.8.1) + tslib: 2.8.1 + + '@jsonjoy.com/json-pointer@1.0.2(tslib@2.8.1)': + dependencies: + '@jsonjoy.com/codegen': 1.0.0(tslib@2.8.1) + '@jsonjoy.com/util': 1.9.0(tslib@2.8.1) + tslib: 2.8.1 + + '@jsonjoy.com/json-pointer@17.65.0(tslib@2.8.1)': + dependencies: + '@jsonjoy.com/util': 17.65.0(tslib@2.8.1) + tslib: 2.8.1 + + '@jsonjoy.com/util@1.9.0(tslib@2.8.1)': + dependencies: + '@jsonjoy.com/buffers': 1.2.1(tslib@2.8.1) + '@jsonjoy.com/codegen': 1.0.0(tslib@2.8.1) + tslib: 2.8.1 + + '@jsonjoy.com/util@17.65.0(tslib@2.8.1)': + dependencies: + '@jsonjoy.com/buffers': 17.65.0(tslib@2.8.1) + '@jsonjoy.com/codegen': 17.65.0(tslib@2.8.1) + tslib: 2.8.1 + + '@leichtgewicht/ip-codec@2.0.5': {} + + '@lit-labs/ssr-dom-shim@1.4.0': {} + + '@lit/reactive-element@2.1.1': + dependencies: + '@lit-labs/ssr-dom-shim': 1.4.0 + + '@mdx-js/mdx@3.1.1': + dependencies: + '@types/estree': 1.0.8 + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + '@types/mdx': 2.0.13 + acorn: 8.15.0 + collapse-white-space: 2.1.0 + devlop: 1.1.0 + estree-util-is-identifier-name: 3.0.0 + estree-util-scope: 1.0.0 + estree-walker: 3.0.3 + hast-util-to-jsx-runtime: 2.3.6 + markdown-extensions: 2.0.0 + recma-build-jsx: 1.0.0 + recma-jsx: 1.0.1(acorn@8.15.0) + recma-stringify: 1.0.0 + rehype-recma: 1.0.0 + remark-mdx: 3.1.1 + remark-parse: 11.0.0 + remark-rehype: 11.1.2 + source-map: 0.7.6 + unified: 11.0.5 + unist-util-position-from-estree: 2.0.0 + unist-util-stringify-position: 4.0.0 + unist-util-visit: 5.0.0 + vfile: 6.0.3 + transitivePeerDependencies: + - supports-color + + '@mdx-js/react@3.1.1(@types/react@18.3.27)(react@19.2.3)': + dependencies: + '@types/mdx': 2.0.13 + '@types/react': 18.3.27 + react: 19.2.3 + + '@metamask/eth-json-rpc-provider@1.0.1': + dependencies: + '@metamask/json-rpc-engine': 7.3.3 + '@metamask/safe-event-emitter': 3.1.2 + '@metamask/utils': 5.0.2 + transitivePeerDependencies: + - supports-color + + '@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 + + '@metamask/json-rpc-engine@8.0.2': + dependencies: + '@metamask/rpc-errors': 6.4.0 + '@metamask/safe-event-emitter': 3.1.2 + '@metamask/utils': 8.5.0 + transitivePeerDependencies: + - supports-color + + '@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 + + '@metamask/object-multiplex@2.1.0': + dependencies: + once: 1.4.0 + readable-stream: 3.6.2 + + '@metamask/onboarding@1.0.1': + dependencies: + bowser: 2.13.1 + + '@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 + + '@metamask/rpc-errors@6.4.0': + dependencies: + '@metamask/utils': 9.3.0 + fast-safe-stringify: 2.1.1 + transitivePeerDependencies: + - supports-color + + '@metamask/rpc-errors@7.0.2': + dependencies: + '@metamask/utils': 11.9.0 + fast-safe-stringify: 2.1.1 + transitivePeerDependencies: + - supports-color + + '@metamask/safe-event-emitter@2.0.0': {} + + '@metamask/safe-event-emitter@3.1.2': {} + + '@metamask/sdk-analytics@0.0.5': + dependencies: + openapi-fetch: 0.13.8 + + '@metamask/sdk-communication-layer@0.33.1(cross-fetch@4.1.0)(eciesjs@0.4.16)(eventemitter2@6.4.9)(readable-stream@3.6.2)(socket.io-client@4.8.1(bufferutil@4.0.9)(utf-8-validate@5.0.10))': + dependencies: + '@metamask/sdk-analytics': 0.0.5 + bufferutil: 4.0.9 + cross-fetch: 4.1.0 + date-fns: 2.30.0 + debug: 4.3.4 + eciesjs: 0.4.16 + eventemitter2: 6.4.9 + readable-stream: 3.6.2 + socket.io-client: 4.8.1(bufferutil@4.0.9)(utf-8-validate@5.0.10) + 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.0.9)(utf-8-validate@5.0.10)': + dependencies: + '@babel/runtime': 7.28.4 + '@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.16)(eventemitter2@6.4.9)(readable-stream@3.6.2)(socket.io-client@4.8.1(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@metamask/sdk-install-modal-web': 0.32.1 + '@paulmillr/qr': 0.2.1 + bowser: 2.13.1 + cross-fetch: 4.1.0 + debug: 4.3.4 + eciesjs: 0.4.16 + 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.1(bufferutil@4.0.9)(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.9.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.21 + debug: 4.4.3(supports-color@8.1.1) + lodash: 4.17.21 + pony-cause: 2.1.11 + semver: 7.7.3 + uuid: 9.0.1 + transitivePeerDependencies: + - supports-color + + '@metamask/utils@5.0.2': + dependencies: + '@ethereumjs/tx': 4.2.0 + '@types/debug': 4.1.12 + debug: 4.4.3(supports-color@8.1.1) + semver: 7.7.3 + 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.3.4 + pony-cause: 2.1.11 + semver: 7.7.3 + 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.3.4 + pony-cause: 2.1.11 + semver: 7.7.3 + uuid: 9.0.1 + transitivePeerDependencies: + - supports-color + + '@noble/ciphers@1.2.1': {} + + '@noble/ciphers@1.3.0': {} + + '@noble/curves@1.2.0': + dependencies: + '@noble/hashes': 1.3.2 + + '@noble/curves@1.4.2': + dependencies: + '@noble/hashes': 1.4.0 + + '@noble/curves@1.8.0': + dependencies: + '@noble/hashes': 1.7.0 + + '@noble/curves@1.8.1': + dependencies: + '@noble/hashes': 1.7.1 + + '@noble/curves@1.8.2': + dependencies: + '@noble/hashes': 1.7.2 + + '@noble/curves@1.9.1': + dependencies: + '@noble/hashes': 1.8.0 + + '@noble/curves@1.9.7': + dependencies: + '@noble/hashes': 1.8.0 + + '@noble/curves@2.0.1': + dependencies: + '@noble/hashes': 2.0.1 + + '@noble/hashes@1.2.0': {} + + '@noble/hashes@1.3.2': {} + + '@noble/hashes@1.4.0': {} + + '@noble/hashes@1.7.0': {} + + '@noble/hashes@1.7.1': {} + + '@noble/hashes@1.7.2': {} + + '@noble/hashes@1.8.0': {} + + '@noble/hashes@2.0.1': {} + + '@noble/post-quantum@0.5.4': + dependencies: + '@noble/curves': 2.0.1 + '@noble/hashes': 2.0.1 + + '@noble/secp256k1@1.7.1': {} + + '@noble/secp256k1@2.3.0': {} + + '@nodelib/fs.scandir@2.1.5': + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + + '@nodelib/fs.stat@2.0.5': {} + + '@nodelib/fs.walk@1.2.8': + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.19.1 + + '@nomicfoundation/edr-darwin-arm64@0.12.0-next.17': {} + + '@nomicfoundation/edr-darwin-x64@0.12.0-next.17': {} + + '@nomicfoundation/edr-linux-arm64-gnu@0.12.0-next.17': {} + + '@nomicfoundation/edr-linux-arm64-musl@0.12.0-next.17': {} + + '@nomicfoundation/edr-linux-x64-gnu@0.12.0-next.17': {} + + '@nomicfoundation/edr-linux-x64-musl@0.12.0-next.17': {} + + '@nomicfoundation/edr-win32-x64-msvc@0.12.0-next.17': {} + + '@nomicfoundation/edr@0.12.0-next.17': + dependencies: + '@nomicfoundation/edr-darwin-arm64': 0.12.0-next.17 + '@nomicfoundation/edr-darwin-x64': 0.12.0-next.17 + '@nomicfoundation/edr-linux-arm64-gnu': 0.12.0-next.17 + '@nomicfoundation/edr-linux-arm64-musl': 0.12.0-next.17 + '@nomicfoundation/edr-linux-x64-gnu': 0.12.0-next.17 + '@nomicfoundation/edr-linux-x64-musl': 0.12.0-next.17 + '@nomicfoundation/edr-win32-x64-msvc': 0.12.0-next.17 + + '@nomicfoundation/hardhat-chai-matchers@2.1.0(@nomicfoundation/hardhat-ethers@3.1.3(ethers@6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.6.3))(typescript@5.6.3)(utf-8-validate@5.0.10)))(chai@4.5.0)(ethers@6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.6.3))(typescript@5.6.3)(utf-8-validate@5.0.10))': + dependencies: + '@nomicfoundation/hardhat-ethers': 3.1.3(ethers@6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.6.3))(typescript@5.6.3)(utf-8-validate@5.0.10)) + '@types/chai-as-promised': 7.1.8 + chai: 4.5.0 + chai-as-promised: 7.1.2(chai@4.5.0) + deep-eql: 4.1.4 + ethers: 6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + hardhat: 2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.6.3))(typescript@5.6.3)(utf-8-validate@5.0.10) + ordinal: 1.0.3 + + '@nomicfoundation/hardhat-ethers@3.1.3(ethers@6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.6.3))(typescript@5.6.3)(utf-8-validate@5.0.10))': + dependencies: + debug: 4.4.3(supports-color@8.1.1) + ethers: 6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + hardhat: 2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.6.3))(typescript@5.6.3)(utf-8-validate@5.0.10) + lodash.isequal: 4.5.0 + transitivePeerDependencies: + - supports-color + + '@nomicfoundation/hardhat-ignition-ethers@0.15.17(@nomicfoundation/hardhat-ethers@3.1.3(ethers@6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.6.3))(typescript@5.6.3)(utf-8-validate@5.0.10)))(@nomicfoundation/hardhat-ignition@0.15.16(@nomicfoundation/hardhat-verify@2.1.3(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.6.3))(typescript@5.6.3)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.6.3))(typescript@5.6.3)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10))(@nomicfoundation/ignition-core@0.15.15(bufferutil@4.0.9)(utf-8-validate@5.0.10))(ethers@6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.6.3))(typescript@5.6.3)(utf-8-validate@5.0.10))': + dependencies: + '@nomicfoundation/hardhat-ethers': 3.1.3(ethers@6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.6.3))(typescript@5.6.3)(utf-8-validate@5.0.10)) + '@nomicfoundation/hardhat-ignition': 0.15.16(@nomicfoundation/hardhat-verify@2.1.3(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.6.3))(typescript@5.6.3)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.6.3))(typescript@5.6.3)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) + '@nomicfoundation/ignition-core': 0.15.15(bufferutil@4.0.9)(utf-8-validate@5.0.10) + ethers: 6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + hardhat: 2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.6.3))(typescript@5.6.3)(utf-8-validate@5.0.10) + + '@nomicfoundation/hardhat-ignition@0.15.16(@nomicfoundation/hardhat-verify@2.1.3(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.6.3))(typescript@5.6.3)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.6.3))(typescript@5.6.3)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10)': + dependencies: + '@nomicfoundation/hardhat-verify': 2.1.3(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.6.3))(typescript@5.6.3)(utf-8-validate@5.0.10)) + '@nomicfoundation/ignition-core': 0.15.15(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@nomicfoundation/ignition-ui': 0.15.13 + chalk: 4.1.2 + debug: 4.4.3(supports-color@8.1.1) + fs-extra: 10.1.0 + hardhat: 2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.6.3))(typescript@5.6.3)(utf-8-validate@5.0.10) + json5: 2.2.3 + prompts: 2.4.2 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + + '@nomicfoundation/hardhat-network-helpers@1.1.2(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.6.3))(typescript@5.6.3)(utf-8-validate@5.0.10))': + dependencies: + ethereumjs-util: 7.1.5 + hardhat: 2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.6.3))(typescript@5.6.3)(utf-8-validate@5.0.10) + + '@nomicfoundation/hardhat-toolbox@5.0.0(1c68260e3d5fd3faa23987294e569bd7)': + dependencies: + '@nomicfoundation/hardhat-chai-matchers': 2.1.0(@nomicfoundation/hardhat-ethers@3.1.3(ethers@6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.6.3))(typescript@5.6.3)(utf-8-validate@5.0.10)))(chai@4.5.0)(ethers@6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.6.3))(typescript@5.6.3)(utf-8-validate@5.0.10)) + '@nomicfoundation/hardhat-ethers': 3.1.3(ethers@6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.6.3))(typescript@5.6.3)(utf-8-validate@5.0.10)) + '@nomicfoundation/hardhat-ignition-ethers': 0.15.17(@nomicfoundation/hardhat-ethers@3.1.3(ethers@6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.6.3))(typescript@5.6.3)(utf-8-validate@5.0.10)))(@nomicfoundation/hardhat-ignition@0.15.16(@nomicfoundation/hardhat-verify@2.1.3(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.6.3))(typescript@5.6.3)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.6.3))(typescript@5.6.3)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10))(@nomicfoundation/ignition-core@0.15.15(bufferutil@4.0.9)(utf-8-validate@5.0.10))(ethers@6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.6.3))(typescript@5.6.3)(utf-8-validate@5.0.10)) + '@nomicfoundation/hardhat-network-helpers': 1.1.2(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.6.3))(typescript@5.6.3)(utf-8-validate@5.0.10)) + '@nomicfoundation/hardhat-verify': 2.1.3(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.6.3))(typescript@5.6.3)(utf-8-validate@5.0.10)) + '@typechain/ethers-v6': 0.5.1(ethers@6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(typechain@8.3.2(typescript@5.6.3))(typescript@5.6.3) + '@typechain/hardhat': 9.1.0(@typechain/ethers-v6@0.5.1(ethers@6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(typechain@8.3.2(typescript@5.6.3))(typescript@5.6.3))(ethers@6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.6.3))(typescript@5.6.3)(utf-8-validate@5.0.10))(typechain@8.3.2(typescript@5.6.3)) + '@types/chai': 4.3.20 + '@types/mocha': 10.0.10 + '@types/node': 22.7.5 + chai: 4.5.0 + ethers: 6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + hardhat: 2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.6.3))(typescript@5.6.3)(utf-8-validate@5.0.10) + hardhat-gas-reporter: 1.0.10(bufferutil@4.0.9)(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.6.3))(typescript@5.6.3)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) + solidity-coverage: 0.8.17(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.6.3))(typescript@5.6.3)(utf-8-validate@5.0.10)) + ts-node: 10.9.2(@types/node@22.7.5)(typescript@5.6.3) + typechain: 8.3.2(typescript@5.6.3) + typescript: 5.6.3 + + '@nomicfoundation/hardhat-verify@2.1.3(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.6.3))(typescript@5.6.3)(utf-8-validate@5.0.10))': + dependencies: + '@ethersproject/abi': 5.8.0 + '@ethersproject/address': 5.8.0 + cbor: 8.1.0 + debug: 4.4.3(supports-color@8.1.1) + hardhat: 2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.6.3))(typescript@5.6.3)(utf-8-validate@5.0.10) + lodash.clonedeep: 4.5.0 + picocolors: 1.1.1 + semver: 6.3.1 + table: 6.9.0 + undici: 5.29.0 + transitivePeerDependencies: + - supports-color + + '@nomicfoundation/ignition-core@0.15.15(bufferutil@4.0.9)(utf-8-validate@5.0.10)': + dependencies: + '@ethersproject/address': 5.6.1 + '@nomicfoundation/solidity-analyzer': 0.1.2 + cbor: 9.0.2 + debug: 4.4.3(supports-color@8.1.1) + ethers: 6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + fs-extra: 10.1.0 + immer: 10.0.2 + lodash: 4.17.21 + ndjson: 2.0.0 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + + '@nomicfoundation/ignition-ui@0.15.13': {} + + '@nomicfoundation/slang@0.18.3': + dependencies: + '@bytecodealliance/preview2-shim': 0.17.0 + + '@nomicfoundation/solidity-analyzer-darwin-arm64@0.1.2': + optional: true + + '@nomicfoundation/solidity-analyzer-darwin-x64@0.1.2': + optional: true + + '@nomicfoundation/solidity-analyzer-linux-arm64-gnu@0.1.2': + optional: true + + '@nomicfoundation/solidity-analyzer-linux-arm64-musl@0.1.2': + optional: true + + '@nomicfoundation/solidity-analyzer-linux-x64-gnu@0.1.2': + optional: true + + '@nomicfoundation/solidity-analyzer-linux-x64-musl@0.1.2': + optional: true + + '@nomicfoundation/solidity-analyzer-win32-x64-msvc@0.1.2': + optional: true + + '@nomicfoundation/solidity-analyzer@0.1.2': + optionalDependencies: + '@nomicfoundation/solidity-analyzer-darwin-arm64': 0.1.2 + '@nomicfoundation/solidity-analyzer-darwin-x64': 0.1.2 + '@nomicfoundation/solidity-analyzer-linux-arm64-gnu': 0.1.2 + '@nomicfoundation/solidity-analyzer-linux-arm64-musl': 0.1.2 + '@nomicfoundation/solidity-analyzer-linux-x64-gnu': 0.1.2 + '@nomicfoundation/solidity-analyzer-linux-x64-musl': 0.1.2 + '@nomicfoundation/solidity-analyzer-win32-x64-msvc': 0.1.2 + + '@openzeppelin/community-contracts@https://codeload.github.com/OpenZeppelin/openzeppelin-community-contracts/tar.gz/a12b30ca7affe3320777378eddf2d0cebae8c5b2': {} + + '@openzeppelin/contracts-upgradeable@5.4.0(@openzeppelin/contracts@5.4.0)': + dependencies: + '@openzeppelin/contracts': 5.4.0 + + '@openzeppelin/contracts@3.4.2-solc-0.7': {} + + '@openzeppelin/contracts@5.4.0': {} + + '@openzeppelin/defender-sdk-base-client@2.7.0': + dependencies: + '@aws-sdk/client-lambda': 3.954.0 + amazon-cognito-identity-js: 6.3.16 + async-retry: 1.3.3 + transitivePeerDependencies: + - aws-crt + - encoding + + '@openzeppelin/defender-sdk-deploy-client@2.7.0(debug@4.4.3)': + dependencies: + '@openzeppelin/defender-sdk-base-client': 2.7.0 + axios: 1.13.2(debug@4.4.3) + lodash: 4.17.21 + transitivePeerDependencies: + - aws-crt + - debug + - encoding + + '@openzeppelin/defender-sdk-network-client@2.7.0(debug@4.4.3)': + dependencies: + '@openzeppelin/defender-sdk-base-client': 2.7.0 + axios: 1.13.2(debug@4.4.3) + lodash: 4.17.21 + transitivePeerDependencies: + - aws-crt + - debug + - encoding + + '@openzeppelin/hardhat-upgrades@3.9.1(@nomicfoundation/hardhat-ethers@3.1.3(ethers@6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.6.3))(typescript@5.6.3)(utf-8-validate@5.0.10)))(@nomicfoundation/hardhat-verify@2.1.3(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.6.3))(typescript@5.6.3)(utf-8-validate@5.0.10)))(ethers@6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.6.3))(typescript@5.6.3)(utf-8-validate@5.0.10))': + dependencies: + '@nomicfoundation/hardhat-ethers': 3.1.3(ethers@6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.6.3))(typescript@5.6.3)(utf-8-validate@5.0.10)) + '@openzeppelin/defender-sdk-base-client': 2.7.0 + '@openzeppelin/defender-sdk-deploy-client': 2.7.0(debug@4.4.3) + '@openzeppelin/defender-sdk-network-client': 2.7.0(debug@4.4.3) + '@openzeppelin/upgrades-core': 1.44.2 + chalk: 4.1.2 + debug: 4.4.3(supports-color@8.1.1) + ethereumjs-util: 7.1.5 + ethers: 6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + hardhat: 2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.6.3))(typescript@5.6.3)(utf-8-validate@5.0.10) + proper-lockfile: 4.1.2 + undici: 6.22.0 + optionalDependencies: + '@nomicfoundation/hardhat-verify': 2.1.3(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.6.3))(typescript@5.6.3)(utf-8-validate@5.0.10)) + transitivePeerDependencies: + - aws-crt + - encoding + - supports-color + + '@openzeppelin/upgrades-core@1.44.2': + dependencies: + '@nomicfoundation/slang': 0.18.3 + bignumber.js: 9.3.1 + cbor: 10.0.11 + chalk: 4.1.2 + compare-versions: 6.1.1 + debug: 4.4.3(supports-color@8.1.1) + ethereumjs-util: 7.1.5 + minimatch: 9.0.5 + minimist: 1.2.8 + proper-lockfile: 4.1.2 + solidity-ast: 0.4.61 + transitivePeerDependencies: + - supports-color + + '@paulmillr/qr@0.2.1': {} + + '@peculiar/asn1-cms@2.6.0': + dependencies: + '@peculiar/asn1-schema': 2.6.0 + '@peculiar/asn1-x509': 2.6.0 + '@peculiar/asn1-x509-attr': 2.6.0 + asn1js: 3.0.7 + tslib: 2.8.1 + + '@peculiar/asn1-csr@2.6.0': + dependencies: + '@peculiar/asn1-schema': 2.6.0 + '@peculiar/asn1-x509': 2.6.0 + asn1js: 3.0.7 + tslib: 2.8.1 + + '@peculiar/asn1-ecc@2.6.0': + dependencies: + '@peculiar/asn1-schema': 2.6.0 + '@peculiar/asn1-x509': 2.6.0 + asn1js: 3.0.7 + tslib: 2.8.1 + + '@peculiar/asn1-pfx@2.6.0': + dependencies: + '@peculiar/asn1-cms': 2.6.0 + '@peculiar/asn1-pkcs8': 2.6.0 + '@peculiar/asn1-rsa': 2.6.0 + '@peculiar/asn1-schema': 2.6.0 + asn1js: 3.0.7 + tslib: 2.8.1 + + '@peculiar/asn1-pkcs8@2.6.0': + dependencies: + '@peculiar/asn1-schema': 2.6.0 + '@peculiar/asn1-x509': 2.6.0 + asn1js: 3.0.7 + tslib: 2.8.1 + + '@peculiar/asn1-pkcs9@2.6.0': + dependencies: + '@peculiar/asn1-cms': 2.6.0 + '@peculiar/asn1-pfx': 2.6.0 + '@peculiar/asn1-pkcs8': 2.6.0 + '@peculiar/asn1-schema': 2.6.0 + '@peculiar/asn1-x509': 2.6.0 + '@peculiar/asn1-x509-attr': 2.6.0 + asn1js: 3.0.7 + tslib: 2.8.1 + + '@peculiar/asn1-rsa@2.6.0': + dependencies: + '@peculiar/asn1-schema': 2.6.0 + '@peculiar/asn1-x509': 2.6.0 + asn1js: 3.0.7 + tslib: 2.8.1 + + '@peculiar/asn1-schema@2.6.0': + dependencies: + asn1js: 3.0.7 + pvtsutils: 1.3.6 + tslib: 2.8.1 + + '@peculiar/asn1-x509-attr@2.6.0': + dependencies: + '@peculiar/asn1-schema': 2.6.0 + '@peculiar/asn1-x509': 2.6.0 + asn1js: 3.0.7 + tslib: 2.8.1 + + '@peculiar/asn1-x509@2.6.0': + dependencies: + '@peculiar/asn1-schema': 2.6.0 + asn1js: 3.0.7 + pvtsutils: 1.3.6 + tslib: 2.8.1 + + '@peculiar/x509@1.14.3': + dependencies: + '@peculiar/asn1-cms': 2.6.0 + '@peculiar/asn1-csr': 2.6.0 + '@peculiar/asn1-ecc': 2.6.0 + '@peculiar/asn1-pkcs9': 2.6.0 + '@peculiar/asn1-rsa': 2.6.0 + '@peculiar/asn1-schema': 2.6.0 + '@peculiar/asn1-x509': 2.6.0 + pvtsutils: 1.3.6 + reflect-metadata: 0.2.2 + tslib: 2.8.1 + tsyringe: 4.10.0 + + '@pnpm/config.env-replace@1.1.0': {} + + '@pnpm/network.ca-file@1.0.2': + dependencies: + graceful-fs: 4.2.10 + + '@pnpm/npm-conf@3.0.2': + dependencies: + '@pnpm/config.env-replace': 1.1.0 + '@pnpm/network.ca-file': 1.0.2 + config-chain: 1.1.13 + + '@polka/url@1.0.0-next.29': {} + + '@rainbow-me/rainbowkit@2.2.10(@tanstack/react-query@5.90.12(react@18.3.1))(@types/react@18.3.27)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3)(viem@2.43.1(bufferutil@4.0.9)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.25.76))(wagmi@2.19.5(@tanstack/query-core@5.90.12)(@tanstack/react-query@5.90.12(react@18.3.1))(@types/react@18.3.27)(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(immer@10.0.2)(react@18.3.1)(typescript@5.6.3)(utf-8-validate@5.0.10)(viem@2.43.1(bufferutil@4.0.9)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.25.76))(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76))': + dependencies: + '@tanstack/react-query': 5.90.12(react@18.3.1) + '@vanilla-extract/css': 1.17.3 + '@vanilla-extract/dynamic': 2.1.4 + '@vanilla-extract/sprinkles': 1.6.4(@vanilla-extract/css@1.17.3) + clsx: 2.1.1 + cuer: 0.0.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + react-remove-scroll: 2.6.2(@types/react@18.3.27)(react@18.3.1) + ua-parser-js: 1.0.41 + viem: 2.43.1(bufferutil@4.0.9)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.25.76) + wagmi: 2.19.5(@tanstack/query-core@5.90.12)(@tanstack/react-query@5.90.12(react@18.3.1))(@types/react@18.3.27)(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(immer@10.0.2)(react@18.3.1)(typescript@5.6.3)(utf-8-validate@5.0.10)(viem@2.43.1(bufferutil@4.0.9)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.25.76))(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76) + transitivePeerDependencies: + - '@types/react' + - babel-plugin-macros + - typescript + + '@reown/appkit-common@1.7.8(bufferutil@4.0.9)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.22.4)': + dependencies: + big.js: 6.2.2 + dayjs: 1.11.13 + viem: 2.43.1(bufferutil@4.0.9)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.22.4) + transitivePeerDependencies: + - bufferutil + - typescript + - utf-8-validate + - zod + + '@reown/appkit-common@1.7.8(bufferutil@4.0.9)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.25.76)': + dependencies: + big.js: 6.2.2 + dayjs: 1.11.13 + viem: 2.43.1(bufferutil@4.0.9)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.25.76) + transitivePeerDependencies: + - bufferutil + - typescript + - utf-8-validate + - zod + + '@reown/appkit-controllers@1.7.8(@types/react@18.3.27)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.25.76)': + dependencies: + '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.9)(typescript@5.6.3)(utf-8-validate@5.0.10) + '@walletconnect/universal-provider': 2.21.0(bufferutil@4.0.9)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.25.76) + valtio: 1.13.2(@types/react@18.3.27)(react@18.3.1) + viem: 2.43.1(bufferutil@4.0.9)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.25.76) + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@types/react' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - encoding + - ioredis + - react + - typescript + - uploadthing + - utf-8-validate + - zod + + '@reown/appkit-pay@1.7.8(@types/react@18.3.27)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.25.76)': + dependencies: + '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-controllers': 1.7.8(@types/react@18.3.27)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-ui': 1.7.8(@types/react@18.3.27)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-utils': 1.7.8(@types/react@18.3.27)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.6.3)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@18.3.27)(react@18.3.1))(zod@3.25.76) + lit: 3.3.0 + valtio: 1.13.2(@types/react@18.3.27)(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.27)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.6.3)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@18.3.27)(react@18.3.1))(zod@3.25.76)': + dependencies: + '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-controllers': 1.7.8(@types/react@18.3.27)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-ui': 1.7.8(@types/react@18.3.27)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-utils': 1.7.8(@types/react@18.3.27)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.6.3)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@18.3.27)(react@18.3.1))(zod@3.25.76) + '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.9)(typescript@5.6.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.27)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.25.76)': + dependencies: + '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-controllers': 1.7.8(@types/react@18.3.27)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.9)(typescript@5.6.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.27)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.6.3)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@18.3.27)(react@18.3.1))(zod@3.25.76)': + dependencies: + '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-controllers': 1.7.8(@types/react@18.3.27)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-polyfills': 1.7.8 + '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.9)(typescript@5.6.3)(utf-8-validate@5.0.10) + '@walletconnect/logger': 2.1.2 + '@walletconnect/universal-provider': 2.21.0(bufferutil@4.0.9)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.25.76) + valtio: 1.13.2(@types/react@18.3.27)(react@18.3.1) + viem: 2.43.1(bufferutil@4.0.9)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.25.76) + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@types/react' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - encoding + - ioredis + - react + - typescript + - uploadthing + - utf-8-validate + - zod + + '@reown/appkit-wallet@1.7.8(bufferutil@4.0.9)(typescript@5.6.3)(utf-8-validate@5.0.10)': + dependencies: + '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.6.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.27)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.25.76)': + dependencies: + '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-controllers': 1.7.8(@types/react@18.3.27)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-pay': 1.7.8(@types/react@18.3.27)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-polyfills': 1.7.8 + '@reown/appkit-scaffold-ui': 1.7.8(@types/react@18.3.27)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.6.3)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@18.3.27)(react@18.3.1))(zod@3.25.76) + '@reown/appkit-ui': 1.7.8(@types/react@18.3.27)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-utils': 1.7.8(@types/react@18.3.27)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.6.3)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@18.3.27)(react@18.3.1))(zod@3.25.76) + '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.9)(typescript@5.6.3)(utf-8-validate@5.0.10) + '@walletconnect/types': 2.21.0 + '@walletconnect/universal-provider': 2.21.0(bufferutil@4.0.9)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.25.76) + bs58: 6.0.0 + valtio: 1.13.2(@types/react@18.3.27)(react@18.3.1) + viem: 2.43.1(bufferutil@4.0.9)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.25.76) + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@types/react' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - encoding + - ioredis + - react + - typescript + - uploadthing + - utf-8-validate + - zod + + '@rolldown/pluginutils@1.0.0-beta.27': {} + + '@rollup/rollup-android-arm-eabi@4.53.5': + optional: true + + '@rollup/rollup-android-arm64@4.53.5': + optional: true + + '@rollup/rollup-darwin-arm64@4.53.5': + optional: true + + '@rollup/rollup-darwin-x64@4.53.5': + optional: true + + '@rollup/rollup-freebsd-arm64@4.53.5': + optional: true + + '@rollup/rollup-freebsd-x64@4.53.5': + optional: true + + '@rollup/rollup-linux-arm-gnueabihf@4.53.5': + optional: true + + '@rollup/rollup-linux-arm-musleabihf@4.53.5': + optional: true + + '@rollup/rollup-linux-arm64-gnu@4.53.5': + optional: true + + '@rollup/rollup-linux-arm64-musl@4.53.5': + optional: true + + '@rollup/rollup-linux-loong64-gnu@4.53.5': + optional: true + + '@rollup/rollup-linux-ppc64-gnu@4.53.5': + optional: true + + '@rollup/rollup-linux-riscv64-gnu@4.53.5': + optional: true + + '@rollup/rollup-linux-riscv64-musl@4.53.5': + optional: true + + '@rollup/rollup-linux-s390x-gnu@4.53.5': + optional: true + + '@rollup/rollup-linux-x64-gnu@4.53.5': + optional: true + + '@rollup/rollup-linux-x64-musl@4.53.5': + optional: true + + '@rollup/rollup-openharmony-arm64@4.53.5': + optional: true + + '@rollup/rollup-win32-arm64-msvc@4.53.5': + optional: true + + '@rollup/rollup-win32-ia32-msvc@4.53.5': + optional: true + + '@rollup/rollup-win32-x64-gnu@4.53.5': + optional: true + + '@rollup/rollup-win32-x64-msvc@4.53.5': + optional: true + + '@safe-global/api-kit@4.0.1(bufferutil@4.0.9)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.25.76)': + dependencies: + '@safe-global/protocol-kit': 6.1.2(bufferutil@4.0.9)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@safe-global/types-kit': 3.0.0(typescript@5.6.3)(zod@3.25.76) + node-fetch: 2.7.0 + viem: 2.43.1(bufferutil@4.0.9)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.25.76) + transitivePeerDependencies: + - bufferutil + - encoding + - typescript + - utf-8-validate + - zod + + '@safe-global/protocol-kit@6.1.2(bufferutil@4.0.9)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.25.76)': + dependencies: + '@safe-global/safe-deployments': 1.37.49 + '@safe-global/safe-modules-deployments': 2.2.21 + '@safe-global/types-kit': 3.0.0(typescript@5.6.3)(zod@3.25.76) + abitype: 1.2.3(typescript@5.6.3)(zod@3.25.76) + semver: 7.7.3 + viem: 2.43.1(bufferutil@4.0.9)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.25.76) + optionalDependencies: + '@noble/curves': 1.9.7 + '@peculiar/asn1-schema': 2.6.0 + transitivePeerDependencies: + - bufferutil + - typescript + - utf-8-validate + - zod + + '@safe-global/safe-apps-provider@0.18.6(bufferutil@4.0.9)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.25.76)': + dependencies: + '@safe-global/safe-apps-sdk': 9.1.0(bufferutil@4.0.9)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.25.76) + events: 3.3.0 + transitivePeerDependencies: + - bufferutil + - typescript + - utf-8-validate + - zod + + '@safe-global/safe-apps-sdk@9.1.0(bufferutil@4.0.9)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.25.76)': + dependencies: + '@safe-global/safe-gateway-typescript-sdk': 3.23.1 + viem: 2.43.1(bufferutil@4.0.9)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.25.76) + transitivePeerDependencies: + - bufferutil + - typescript + - utf-8-validate + - zod + + '@safe-global/safe-deployments@1.37.49': + dependencies: + semver: 7.7.3 + + '@safe-global/safe-gateway-typescript-sdk@3.23.1': {} + + '@safe-global/safe-modules-deployments@2.2.21': {} + + '@safe-global/types-kit@3.0.0(typescript@5.6.3)(zod@3.25.76)': + dependencies: + abitype: 1.2.3(typescript@5.6.3)(zod@3.25.76) + transitivePeerDependencies: + - typescript + - zod + + '@scure/base@1.1.9': {} + + '@scure/base@1.2.6': {} + + '@scure/bip32@1.1.5': + dependencies: + '@noble/hashes': 1.2.0 + '@noble/secp256k1': 1.7.1 + '@scure/base': 1.1.9 + + '@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.2 + '@noble/hashes': 1.7.2 + '@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.1.1': + dependencies: + '@noble/hashes': 1.2.0 + '@scure/base': 1.1.9 + + '@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.2 + '@scure/base': 1.2.6 + + '@scure/bip39@1.6.0': + dependencies: + '@noble/hashes': 1.8.0 + '@scure/base': 1.2.6 + + '@sentry/core@5.30.0': + dependencies: + '@sentry/hub': 5.30.0 + '@sentry/minimal': 5.30.0 + '@sentry/types': 5.30.0 + '@sentry/utils': 5.30.0 + tslib: 1.14.1 + + '@sentry/hub@5.30.0': + dependencies: + '@sentry/types': 5.30.0 + '@sentry/utils': 5.30.0 + tslib: 1.14.1 + + '@sentry/minimal@5.30.0': + dependencies: + '@sentry/hub': 5.30.0 + '@sentry/types': 5.30.0 + tslib: 1.14.1 + + '@sentry/node@5.30.0': + dependencies: + '@sentry/core': 5.30.0 + '@sentry/hub': 5.30.0 + '@sentry/tracing': 5.30.0 + '@sentry/types': 5.30.0 + '@sentry/utils': 5.30.0 + cookie: 0.4.2 + https-proxy-agent: 5.0.1 + lru_map: 0.3.3 + tslib: 1.14.1 + transitivePeerDependencies: + - supports-color + + '@sentry/tracing@5.30.0': + dependencies: + '@sentry/hub': 5.30.0 + '@sentry/minimal': 5.30.0 + '@sentry/types': 5.30.0 + '@sentry/utils': 5.30.0 + tslib: 1.14.1 + + '@sentry/types@5.30.0': {} + + '@sentry/utils@5.30.0': + dependencies: + '@sentry/types': 5.30.0 + tslib: 1.14.1 + + '@sideway/address@4.1.5': + dependencies: + '@hapi/hoek': 9.3.0 + + '@sideway/formula@3.0.1': {} + + '@sideway/pinpoint@2.0.0': {} + + '@sinclair/typebox@0.27.8': {} + + '@sindresorhus/is@4.6.0': {} + + '@sindresorhus/is@5.6.0': {} + + '@slorber/react-helmet-async@1.3.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + dependencies: + '@babel/runtime': 7.28.4 + invariant: 2.2.4 + prop-types: 15.8.1 + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + react-fast-compare: 3.2.2 + shallowequal: 1.1.0 + + '@slorber/remark-comment@1.0.0': + dependencies: + micromark-factory-space: 1.1.0 + micromark-util-character: 1.2.0 + micromark-util-symbol: 1.1.0 + + '@smithy/abort-controller@4.2.6': + dependencies: + '@smithy/types': 4.10.0 + tslib: 2.8.1 + + '@smithy/config-resolver@4.4.4': + dependencies: + '@smithy/node-config-provider': 4.3.6 + '@smithy/types': 4.10.0 + '@smithy/util-config-provider': 4.2.0 + '@smithy/util-endpoints': 3.2.6 + '@smithy/util-middleware': 4.2.6 + tslib: 2.8.1 + + '@smithy/core@3.19.0': + dependencies: + '@smithy/middleware-serde': 4.2.7 + '@smithy/protocol-http': 5.3.6 + '@smithy/types': 4.10.0 + '@smithy/util-base64': 4.3.0 + '@smithy/util-body-length-browser': 4.2.0 + '@smithy/util-middleware': 4.2.6 + '@smithy/util-stream': 4.5.7 + '@smithy/util-utf8': 4.2.0 + '@smithy/uuid': 1.1.0 + tslib: 2.8.1 + + '@smithy/credential-provider-imds@4.2.6': + dependencies: + '@smithy/node-config-provider': 4.3.6 + '@smithy/property-provider': 4.2.6 + '@smithy/types': 4.10.0 + '@smithy/url-parser': 4.2.6 + tslib: 2.8.1 + + '@smithy/eventstream-codec@4.2.6': + dependencies: + '@aws-crypto/crc32': 5.2.0 + '@smithy/types': 4.10.0 + '@smithy/util-hex-encoding': 4.2.0 + tslib: 2.8.1 + + '@smithy/eventstream-serde-browser@4.2.6': + dependencies: + '@smithy/eventstream-serde-universal': 4.2.6 + '@smithy/types': 4.10.0 + tslib: 2.8.1 + + '@smithy/eventstream-serde-config-resolver@4.3.6': + dependencies: + '@smithy/types': 4.10.0 + tslib: 2.8.1 + + '@smithy/eventstream-serde-node@4.2.6': + dependencies: + '@smithy/eventstream-serde-universal': 4.2.6 + '@smithy/types': 4.10.0 + tslib: 2.8.1 + + '@smithy/eventstream-serde-universal@4.2.6': + dependencies: + '@smithy/eventstream-codec': 4.2.6 + '@smithy/types': 4.10.0 + tslib: 2.8.1 + + '@smithy/fetch-http-handler@5.3.7': + dependencies: + '@smithy/protocol-http': 5.3.6 + '@smithy/querystring-builder': 4.2.6 + '@smithy/types': 4.10.0 + '@smithy/util-base64': 4.3.0 + tslib: 2.8.1 + + '@smithy/hash-node@4.2.6': + dependencies: + '@smithy/types': 4.10.0 + '@smithy/util-buffer-from': 4.2.0 + '@smithy/util-utf8': 4.2.0 + tslib: 2.8.1 + + '@smithy/invalid-dependency@4.2.6': + dependencies: + '@smithy/types': 4.10.0 + tslib: 2.8.1 + + '@smithy/is-array-buffer@2.2.0': + dependencies: + tslib: 2.8.1 + + '@smithy/is-array-buffer@4.2.0': + dependencies: + tslib: 2.8.1 + + '@smithy/middleware-content-length@4.2.6': + dependencies: + '@smithy/protocol-http': 5.3.6 + '@smithy/types': 4.10.0 + tslib: 2.8.1 + + '@smithy/middleware-endpoint@4.4.0': + dependencies: + '@smithy/core': 3.19.0 + '@smithy/middleware-serde': 4.2.7 + '@smithy/node-config-provider': 4.3.6 + '@smithy/shared-ini-file-loader': 4.4.1 + '@smithy/types': 4.10.0 + '@smithy/url-parser': 4.2.6 + '@smithy/util-middleware': 4.2.6 + tslib: 2.8.1 + + '@smithy/middleware-retry@4.4.16': + dependencies: + '@smithy/node-config-provider': 4.3.6 + '@smithy/protocol-http': 5.3.6 + '@smithy/service-error-classification': 4.2.6 + '@smithy/smithy-client': 4.10.1 + '@smithy/types': 4.10.0 + '@smithy/util-middleware': 4.2.6 + '@smithy/util-retry': 4.2.6 + '@smithy/uuid': 1.1.0 + tslib: 2.8.1 + + '@smithy/middleware-serde@4.2.7': + dependencies: + '@smithy/protocol-http': 5.3.6 + '@smithy/types': 4.10.0 + tslib: 2.8.1 + + '@smithy/middleware-stack@4.2.6': + dependencies: + '@smithy/types': 4.10.0 + tslib: 2.8.1 + + '@smithy/node-config-provider@4.3.6': + dependencies: + '@smithy/property-provider': 4.2.6 + '@smithy/shared-ini-file-loader': 4.4.1 + '@smithy/types': 4.10.0 + tslib: 2.8.1 + + '@smithy/node-http-handler@4.4.6': + dependencies: + '@smithy/abort-controller': 4.2.6 + '@smithy/protocol-http': 5.3.6 + '@smithy/querystring-builder': 4.2.6 + '@smithy/types': 4.10.0 + tslib: 2.8.1 + + '@smithy/property-provider@4.2.6': + dependencies: + '@smithy/types': 4.10.0 + tslib: 2.8.1 + + '@smithy/protocol-http@5.3.6': + dependencies: + '@smithy/types': 4.10.0 + tslib: 2.8.1 + + '@smithy/querystring-builder@4.2.6': + dependencies: + '@smithy/types': 4.10.0 + '@smithy/util-uri-escape': 4.2.0 + tslib: 2.8.1 + + '@smithy/querystring-parser@4.2.6': + dependencies: + '@smithy/types': 4.10.0 + tslib: 2.8.1 + + '@smithy/service-error-classification@4.2.6': + dependencies: + '@smithy/types': 4.10.0 + + '@smithy/shared-ini-file-loader@4.4.1': + dependencies: + '@smithy/types': 4.10.0 + tslib: 2.8.1 + + '@smithy/signature-v4@5.3.6': + dependencies: + '@smithy/is-array-buffer': 4.2.0 + '@smithy/protocol-http': 5.3.6 + '@smithy/types': 4.10.0 + '@smithy/util-hex-encoding': 4.2.0 + '@smithy/util-middleware': 4.2.6 + '@smithy/util-uri-escape': 4.2.0 + '@smithy/util-utf8': 4.2.0 + tslib: 2.8.1 + + '@smithy/smithy-client@4.10.1': + dependencies: + '@smithy/core': 3.19.0 '@smithy/middleware-endpoint': 4.4.0 - '@smithy/middleware-retry': 4.4.16 - '@smithy/middleware-serde': 4.2.7 '@smithy/middleware-stack': 4.2.6 - '@smithy/node-config-provider': 4.3.6 - '@smithy/node-http-handler': 4.4.6 '@smithy/protocol-http': 5.3.6 + '@smithy/types': 4.10.0 + '@smithy/util-stream': 4.5.7 + tslib: 2.8.1 + + '@smithy/types@4.10.0': + dependencies: + tslib: 2.8.1 + + '@smithy/url-parser@4.2.6': + dependencies: + '@smithy/querystring-parser': 4.2.6 + '@smithy/types': 4.10.0 + tslib: 2.8.1 + + '@smithy/util-base64@4.3.0': + dependencies: + '@smithy/util-buffer-from': 4.2.0 + '@smithy/util-utf8': 4.2.0 + tslib: 2.8.1 + + '@smithy/util-body-length-browser@4.2.0': + dependencies: + tslib: 2.8.1 + + '@smithy/util-body-length-node@4.2.1': + dependencies: + tslib: 2.8.1 + + '@smithy/util-buffer-from@2.2.0': + dependencies: + '@smithy/is-array-buffer': 2.2.0 + tslib: 2.8.1 + + '@smithy/util-buffer-from@4.2.0': + dependencies: + '@smithy/is-array-buffer': 4.2.0 + tslib: 2.8.1 + + '@smithy/util-config-provider@4.2.0': + dependencies: + tslib: 2.8.1 + + '@smithy/util-defaults-mode-browser@4.3.15': + dependencies: + '@smithy/property-provider': 4.2.6 '@smithy/smithy-client': 4.10.1 '@smithy/types': 4.10.0 - '@smithy/url-parser': 4.2.6 + tslib: 2.8.1 + + '@smithy/util-defaults-mode-node@4.2.18': + dependencies: + '@smithy/config-resolver': 4.4.4 + '@smithy/credential-provider-imds': 4.2.6 + '@smithy/node-config-provider': 4.3.6 + '@smithy/property-provider': 4.2.6 + '@smithy/smithy-client': 4.10.1 + '@smithy/types': 4.10.0 + tslib: 2.8.1 + + '@smithy/util-endpoints@3.2.6': + dependencies: + '@smithy/node-config-provider': 4.3.6 + '@smithy/types': 4.10.0 + tslib: 2.8.1 + + '@smithy/util-hex-encoding@4.2.0': + dependencies: + tslib: 2.8.1 + + '@smithy/util-middleware@4.2.6': + dependencies: + '@smithy/types': 4.10.0 + tslib: 2.8.1 + + '@smithy/util-retry@4.2.6': + dependencies: + '@smithy/service-error-classification': 4.2.6 + '@smithy/types': 4.10.0 + tslib: 2.8.1 + + '@smithy/util-stream@4.5.7': + dependencies: + '@smithy/fetch-http-handler': 5.3.7 + '@smithy/node-http-handler': 4.4.6 + '@smithy/types': 4.10.0 '@smithy/util-base64': 4.3.0 - '@smithy/util-body-length-browser': 4.2.0 - '@smithy/util-body-length-node': 4.2.1 - '@smithy/util-defaults-mode-browser': 4.3.15 - '@smithy/util-defaults-mode-node': 4.2.18 - '@smithy/util-endpoints': 3.2.6 - '@smithy/util-middleware': 4.2.6 - '@smithy/util-retry': 4.2.6 - '@smithy/util-stream': 4.5.7 + '@smithy/util-buffer-from': 4.2.0 + '@smithy/util-hex-encoding': 4.2.0 '@smithy/util-utf8': 4.2.0 - '@smithy/util-waiter': 4.2.6 tslib: 2.8.1 + + '@smithy/util-uri-escape@4.2.0': + dependencies: + tslib: 2.8.1 + + '@smithy/util-utf8@2.3.0': + dependencies: + '@smithy/util-buffer-from': 2.2.0 + tslib: 2.8.1 + + '@smithy/util-utf8@4.2.0': + dependencies: + '@smithy/util-buffer-from': 4.2.0 + tslib: 2.8.1 + + '@smithy/util-waiter@4.2.6': + dependencies: + '@smithy/abort-controller': 4.2.6 + '@smithy/types': 4.10.0 + tslib: 2.8.1 + + '@smithy/uuid@1.1.0': + dependencies: + tslib: 2.8.1 + + '@socket.io/component-emitter@3.1.2': {} + + '@solana-program/system@0.8.1(@solana/kit@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)))': + dependencies: + '@solana/kit': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + + '@solana-program/token@0.6.0(@solana/kit@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)))': + dependencies: + '@solana/kit': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + + '@solana/accounts@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3)': + dependencies: + '@solana/addresses': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) + '@solana/codecs-core': 3.0.3(typescript@5.6.3) + '@solana/codecs-strings': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) + '@solana/errors': 3.0.3(typescript@5.6.3) + '@solana/rpc-spec': 3.0.3(typescript@5.6.3) + '@solana/rpc-types': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) + typescript: 5.6.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/addresses@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3)': + dependencies: + '@solana/assertions': 3.0.3(typescript@5.6.3) + '@solana/codecs-core': 3.0.3(typescript@5.6.3) + '@solana/codecs-strings': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) + '@solana/errors': 3.0.3(typescript@5.6.3) + '@solana/nominal-types': 3.0.3(typescript@5.6.3) + typescript: 5.6.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/assertions@3.0.3(typescript@5.6.3)': + dependencies: + '@solana/errors': 3.0.3(typescript@5.6.3) + typescript: 5.6.3 + + '@solana/buffer-layout@4.0.1': + dependencies: + buffer: 6.0.3 + + '@solana/codecs-core@2.3.0(typescript@5.6.3)': + dependencies: + '@solana/errors': 2.3.0(typescript@5.6.3) + typescript: 5.6.3 + + '@solana/codecs-core@3.0.3(typescript@5.6.3)': + dependencies: + '@solana/errors': 3.0.3(typescript@5.6.3) + typescript: 5.6.3 + + '@solana/codecs-data-structures@3.0.3(typescript@5.6.3)': + dependencies: + '@solana/codecs-core': 3.0.3(typescript@5.6.3) + '@solana/codecs-numbers': 3.0.3(typescript@5.6.3) + '@solana/errors': 3.0.3(typescript@5.6.3) + typescript: 5.6.3 + + '@solana/codecs-numbers@2.3.0(typescript@5.6.3)': + dependencies: + '@solana/codecs-core': 2.3.0(typescript@5.6.3) + '@solana/errors': 2.3.0(typescript@5.6.3) + typescript: 5.6.3 + + '@solana/codecs-numbers@3.0.3(typescript@5.6.3)': + dependencies: + '@solana/codecs-core': 3.0.3(typescript@5.6.3) + '@solana/errors': 3.0.3(typescript@5.6.3) + typescript: 5.6.3 + + '@solana/codecs-strings@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3)': + dependencies: + '@solana/codecs-core': 3.0.3(typescript@5.6.3) + '@solana/codecs-numbers': 3.0.3(typescript@5.6.3) + '@solana/errors': 3.0.3(typescript@5.6.3) + fastestsmallesttextencoderdecoder: 1.0.22 + typescript: 5.6.3 + + '@solana/codecs@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3)': + dependencies: + '@solana/codecs-core': 3.0.3(typescript@5.6.3) + '@solana/codecs-data-structures': 3.0.3(typescript@5.6.3) + '@solana/codecs-numbers': 3.0.3(typescript@5.6.3) + '@solana/codecs-strings': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) + '@solana/options': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) + typescript: 5.6.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/errors@2.3.0(typescript@5.6.3)': + dependencies: + chalk: 5.6.2 + commander: 14.0.2 + typescript: 5.6.3 + + '@solana/errors@3.0.3(typescript@5.6.3)': + dependencies: + chalk: 5.6.2 + commander: 14.0.0 + typescript: 5.6.3 + + '@solana/fast-stable-stringify@3.0.3(typescript@5.6.3)': + dependencies: + typescript: 5.6.3 + + '@solana/functional@3.0.3(typescript@5.6.3)': + dependencies: + typescript: 5.6.3 + + '@solana/instruction-plans@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3)': + dependencies: + '@solana/errors': 3.0.3(typescript@5.6.3) + '@solana/instructions': 3.0.3(typescript@5.6.3) + '@solana/promises': 3.0.3(typescript@5.6.3) + '@solana/transaction-messages': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) + '@solana/transactions': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) + typescript: 5.6.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/instructions@3.0.3(typescript@5.6.3)': + dependencies: + '@solana/codecs-core': 3.0.3(typescript@5.6.3) + '@solana/errors': 3.0.3(typescript@5.6.3) + typescript: 5.6.3 + + '@solana/keys@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3)': + dependencies: + '@solana/assertions': 3.0.3(typescript@5.6.3) + '@solana/codecs-core': 3.0.3(typescript@5.6.3) + '@solana/codecs-strings': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) + '@solana/errors': 3.0.3(typescript@5.6.3) + '@solana/nominal-types': 3.0.3(typescript@5.6.3) + typescript: 5.6.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/kit@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))': + dependencies: + '@solana/accounts': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) + '@solana/addresses': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) + '@solana/codecs': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) + '@solana/errors': 3.0.3(typescript@5.6.3) + '@solana/functional': 3.0.3(typescript@5.6.3) + '@solana/instruction-plans': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) + '@solana/instructions': 3.0.3(typescript@5.6.3) + '@solana/keys': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) + '@solana/programs': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) + '@solana/rpc': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) + '@solana/rpc-parsed-types': 3.0.3(typescript@5.6.3) + '@solana/rpc-spec-types': 3.0.3(typescript@5.6.3) + '@solana/rpc-subscriptions': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@solana/rpc-types': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) + '@solana/signers': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) + '@solana/sysvars': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) + '@solana/transaction-confirmation': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@solana/transaction-messages': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) + '@solana/transactions': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) + typescript: 5.6.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + - ws + + '@solana/nominal-types@3.0.3(typescript@5.6.3)': + dependencies: + typescript: 5.6.3 + + '@solana/options@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3)': + dependencies: + '@solana/codecs-core': 3.0.3(typescript@5.6.3) + '@solana/codecs-data-structures': 3.0.3(typescript@5.6.3) + '@solana/codecs-numbers': 3.0.3(typescript@5.6.3) + '@solana/codecs-strings': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) + '@solana/errors': 3.0.3(typescript@5.6.3) + typescript: 5.6.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/programs@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3)': + dependencies: + '@solana/addresses': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) + '@solana/errors': 3.0.3(typescript@5.6.3) + typescript: 5.6.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/promises@3.0.3(typescript@5.6.3)': + dependencies: + typescript: 5.6.3 + + '@solana/rpc-api@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3)': + dependencies: + '@solana/addresses': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) + '@solana/codecs-core': 3.0.3(typescript@5.6.3) + '@solana/codecs-strings': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) + '@solana/errors': 3.0.3(typescript@5.6.3) + '@solana/keys': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) + '@solana/rpc-parsed-types': 3.0.3(typescript@5.6.3) + '@solana/rpc-spec': 3.0.3(typescript@5.6.3) + '@solana/rpc-transformers': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) + '@solana/rpc-types': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) + '@solana/transaction-messages': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) + '@solana/transactions': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) + typescript: 5.6.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/rpc-parsed-types@3.0.3(typescript@5.6.3)': + dependencies: + typescript: 5.6.3 + + '@solana/rpc-spec-types@3.0.3(typescript@5.6.3)': + dependencies: + typescript: 5.6.3 + + '@solana/rpc-spec@3.0.3(typescript@5.6.3)': + dependencies: + '@solana/errors': 3.0.3(typescript@5.6.3) + '@solana/rpc-spec-types': 3.0.3(typescript@5.6.3) + typescript: 5.6.3 + + '@solana/rpc-subscriptions-api@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3)': + dependencies: + '@solana/addresses': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) + '@solana/keys': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) + '@solana/rpc-subscriptions-spec': 3.0.3(typescript@5.6.3) + '@solana/rpc-transformers': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) + '@solana/rpc-types': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) + '@solana/transaction-messages': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) + '@solana/transactions': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) + typescript: 5.6.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/rpc-subscriptions-channel-websocket@3.0.3(typescript@5.6.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))': + dependencies: + '@solana/errors': 3.0.3(typescript@5.6.3) + '@solana/functional': 3.0.3(typescript@5.6.3) + '@solana/rpc-subscriptions-spec': 3.0.3(typescript@5.6.3) + '@solana/subscribable': 3.0.3(typescript@5.6.3) + typescript: 5.6.3 + ws: 8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + + '@solana/rpc-subscriptions-spec@3.0.3(typescript@5.6.3)': + dependencies: + '@solana/errors': 3.0.3(typescript@5.6.3) + '@solana/promises': 3.0.3(typescript@5.6.3) + '@solana/rpc-spec-types': 3.0.3(typescript@5.6.3) + '@solana/subscribable': 3.0.3(typescript@5.6.3) + typescript: 5.6.3 + + '@solana/rpc-subscriptions@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))': + dependencies: + '@solana/errors': 3.0.3(typescript@5.6.3) + '@solana/fast-stable-stringify': 3.0.3(typescript@5.6.3) + '@solana/functional': 3.0.3(typescript@5.6.3) + '@solana/promises': 3.0.3(typescript@5.6.3) + '@solana/rpc-spec-types': 3.0.3(typescript@5.6.3) + '@solana/rpc-subscriptions-api': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) + '@solana/rpc-subscriptions-channel-websocket': 3.0.3(typescript@5.6.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@solana/rpc-subscriptions-spec': 3.0.3(typescript@5.6.3) + '@solana/rpc-transformers': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) + '@solana/rpc-types': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) + '@solana/subscribable': 3.0.3(typescript@5.6.3) + typescript: 5.6.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + - ws + + '@solana/rpc-transformers@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3)': + dependencies: + '@solana/errors': 3.0.3(typescript@5.6.3) + '@solana/functional': 3.0.3(typescript@5.6.3) + '@solana/nominal-types': 3.0.3(typescript@5.6.3) + '@solana/rpc-spec-types': 3.0.3(typescript@5.6.3) + '@solana/rpc-types': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) + typescript: 5.6.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/rpc-transport-http@3.0.3(typescript@5.6.3)': + dependencies: + '@solana/errors': 3.0.3(typescript@5.6.3) + '@solana/rpc-spec': 3.0.3(typescript@5.6.3) + '@solana/rpc-spec-types': 3.0.3(typescript@5.6.3) + typescript: 5.6.3 + undici-types: 7.16.0 + + '@solana/rpc-types@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3)': + dependencies: + '@solana/addresses': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) + '@solana/codecs-core': 3.0.3(typescript@5.6.3) + '@solana/codecs-numbers': 3.0.3(typescript@5.6.3) + '@solana/codecs-strings': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) + '@solana/errors': 3.0.3(typescript@5.6.3) + '@solana/nominal-types': 3.0.3(typescript@5.6.3) + typescript: 5.6.3 transitivePeerDependencies: - - aws-crt + - fastestsmallesttextencoderdecoder + + '@solana/rpc@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3)': + dependencies: + '@solana/errors': 3.0.3(typescript@5.6.3) + '@solana/fast-stable-stringify': 3.0.3(typescript@5.6.3) + '@solana/functional': 3.0.3(typescript@5.6.3) + '@solana/rpc-api': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) + '@solana/rpc-spec': 3.0.3(typescript@5.6.3) + '@solana/rpc-spec-types': 3.0.3(typescript@5.6.3) + '@solana/rpc-transformers': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) + '@solana/rpc-transport-http': 3.0.3(typescript@5.6.3) + '@solana/rpc-types': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) + typescript: 5.6.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/signers@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3)': + dependencies: + '@solana/addresses': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) + '@solana/codecs-core': 3.0.3(typescript@5.6.3) + '@solana/errors': 3.0.3(typescript@5.6.3) + '@solana/instructions': 3.0.3(typescript@5.6.3) + '@solana/keys': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) + '@solana/nominal-types': 3.0.3(typescript@5.6.3) + '@solana/transaction-messages': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) + '@solana/transactions': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) + typescript: 5.6.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/subscribable@3.0.3(typescript@5.6.3)': + dependencies: + '@solana/errors': 3.0.3(typescript@5.6.3) + typescript: 5.6.3 + + '@solana/sysvars@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3)': + dependencies: + '@solana/accounts': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) + '@solana/codecs': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) + '@solana/errors': 3.0.3(typescript@5.6.3) + '@solana/rpc-types': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) + typescript: 5.6.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/transaction-confirmation@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))': + dependencies: + '@solana/addresses': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) + '@solana/codecs-strings': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) + '@solana/errors': 3.0.3(typescript@5.6.3) + '@solana/keys': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) + '@solana/promises': 3.0.3(typescript@5.6.3) + '@solana/rpc': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) + '@solana/rpc-subscriptions': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@solana/rpc-types': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) + '@solana/transaction-messages': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) + '@solana/transactions': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) + typescript: 5.6.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + - ws + + '@solana/transaction-messages@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3)': + dependencies: + '@solana/addresses': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) + '@solana/codecs-core': 3.0.3(typescript@5.6.3) + '@solana/codecs-data-structures': 3.0.3(typescript@5.6.3) + '@solana/codecs-numbers': 3.0.3(typescript@5.6.3) + '@solana/errors': 3.0.3(typescript@5.6.3) + '@solana/functional': 3.0.3(typescript@5.6.3) + '@solana/instructions': 3.0.3(typescript@5.6.3) + '@solana/nominal-types': 3.0.3(typescript@5.6.3) + '@solana/rpc-types': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) + typescript: 5.6.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/transactions@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3)': + dependencies: + '@solana/addresses': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) + '@solana/codecs-core': 3.0.3(typescript@5.6.3) + '@solana/codecs-data-structures': 3.0.3(typescript@5.6.3) + '@solana/codecs-numbers': 3.0.3(typescript@5.6.3) + '@solana/codecs-strings': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) + '@solana/errors': 3.0.3(typescript@5.6.3) + '@solana/functional': 3.0.3(typescript@5.6.3) + '@solana/instructions': 3.0.3(typescript@5.6.3) + '@solana/keys': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) + '@solana/nominal-types': 3.0.3(typescript@5.6.3) + '@solana/rpc-types': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) + '@solana/transaction-messages': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) + typescript: 5.6.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/web3.js@1.98.4(bufferutil@4.0.9)(typescript@5.6.3)(utf-8-validate@5.0.10)': + dependencies: + '@babel/runtime': 7.28.4 + '@noble/curves': 1.9.7 + '@noble/hashes': 1.8.0 + '@solana/buffer-layout': 4.0.1 + '@solana/codecs-numbers': 2.3.0(typescript@5.6.3) + agentkeepalive: 4.6.0 + bn.js: 5.2.2 + borsh: 0.7.0 + bs58: 4.0.1 + buffer: 6.0.3 + fast-stable-stringify: 1.0.0 + jayson: 4.2.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + node-fetch: 2.7.0 + rpc-websockets: 9.3.2 + superstruct: 2.0.2 + transitivePeerDependencies: + - bufferutil + - encoding + - typescript + - utf-8-validate + + '@solidity-parser/parser@0.14.5': + dependencies: + antlr4ts: 0.5.0-alpha.4 + + '@solidity-parser/parser@0.20.2': {} + + '@svgr/babel-plugin-add-jsx-attribute@8.0.0(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + + '@svgr/babel-plugin-remove-jsx-attribute@8.0.0(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + + '@svgr/babel-plugin-remove-jsx-empty-expression@8.0.0(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + + '@svgr/babel-plugin-replace-jsx-attribute-value@8.0.0(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + + '@svgr/babel-plugin-svg-dynamic-title@8.0.0(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + + '@svgr/babel-plugin-svg-em-dimensions@8.0.0(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + + '@svgr/babel-plugin-transform-react-native-svg@8.1.0(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + + '@svgr/babel-plugin-transform-svg-component@8.0.0(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + + '@svgr/babel-preset@8.1.0(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@svgr/babel-plugin-add-jsx-attribute': 8.0.0(@babel/core@7.28.5) + '@svgr/babel-plugin-remove-jsx-attribute': 8.0.0(@babel/core@7.28.5) + '@svgr/babel-plugin-remove-jsx-empty-expression': 8.0.0(@babel/core@7.28.5) + '@svgr/babel-plugin-replace-jsx-attribute-value': 8.0.0(@babel/core@7.28.5) + '@svgr/babel-plugin-svg-dynamic-title': 8.0.0(@babel/core@7.28.5) + '@svgr/babel-plugin-svg-em-dimensions': 8.0.0(@babel/core@7.28.5) + '@svgr/babel-plugin-transform-react-native-svg': 8.1.0(@babel/core@7.28.5) + '@svgr/babel-plugin-transform-svg-component': 8.0.0(@babel/core@7.28.5) + + '@svgr/core@8.1.0(typescript@5.6.3)': + dependencies: + '@babel/core': 7.28.5 + '@svgr/babel-preset': 8.1.0(@babel/core@7.28.5) + camelcase: 6.3.0 + cosmiconfig: 8.3.6(typescript@5.6.3) + snake-case: 3.0.4 + transitivePeerDependencies: + - supports-color + - typescript + + '@svgr/hast-util-to-babel-ast@8.0.0': + dependencies: + '@babel/types': 7.28.5 + entities: 4.5.0 + + '@svgr/plugin-jsx@8.1.0(@svgr/core@8.1.0(typescript@5.6.3))': + dependencies: + '@babel/core': 7.28.5 + '@svgr/babel-preset': 8.1.0(@babel/core@7.28.5) + '@svgr/core': 8.1.0(typescript@5.6.3) + '@svgr/hast-util-to-babel-ast': 8.0.0 + svg-parser: 2.0.4 + transitivePeerDependencies: + - supports-color + + '@svgr/plugin-svgo@8.1.0(@svgr/core@8.1.0(typescript@5.6.3))(typescript@5.6.3)': + dependencies: + '@svgr/core': 8.1.0(typescript@5.6.3) + cosmiconfig: 8.3.6(typescript@5.6.3) + deepmerge: 4.3.1 + svgo: 3.3.2 + transitivePeerDependencies: + - typescript + + '@svgr/webpack@8.1.0(typescript@5.6.3)': + dependencies: + '@babel/core': 7.28.5 + '@babel/plugin-transform-react-constant-elements': 7.27.1(@babel/core@7.28.5) + '@babel/preset-env': 7.28.6(@babel/core@7.28.5) + '@babel/preset-react': 7.28.5(@babel/core@7.28.5) + '@babel/preset-typescript': 7.28.5(@babel/core@7.28.5) + '@svgr/core': 8.1.0(typescript@5.6.3) + '@svgr/plugin-jsx': 8.1.0(@svgr/core@8.1.0(typescript@5.6.3)) + '@svgr/plugin-svgo': 8.1.0(@svgr/core@8.1.0(typescript@5.6.3))(typescript@5.6.3) + transitivePeerDependencies: + - supports-color + - typescript + + '@swc/helpers@0.5.17': + dependencies: + tslib: 2.8.1 + + '@szmarczak/http-timer@5.0.1': + dependencies: + defer-to-connect: 2.0.1 + + '@tanstack/query-core@5.90.12': {} + + '@tanstack/react-query@5.90.12(react@18.3.1)': + dependencies: + '@tanstack/query-core': 5.90.12 + react: 18.3.1 + + '@trysound/sax@0.2.0': {} + + '@tsconfig/node10@1.0.12': {} + + '@tsconfig/node12@1.0.11': {} + + '@tsconfig/node14@1.0.3': {} + + '@tsconfig/node16@1.0.4': {} + + '@typechain/ethers-v6@0.5.1(ethers@6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(typechain@8.3.2(typescript@5.6.3))(typescript@5.6.3)': + dependencies: + ethers: 6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + lodash: 4.17.21 + ts-essentials: 7.0.3(typescript@5.6.3) + typechain: 8.3.2(typescript@5.6.3) + typescript: 5.6.3 + + '@typechain/hardhat@9.1.0(@typechain/ethers-v6@0.5.1(ethers@6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(typechain@8.3.2(typescript@5.6.3))(typescript@5.6.3))(ethers@6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.6.3))(typescript@5.6.3)(utf-8-validate@5.0.10))(typechain@8.3.2(typescript@5.6.3))': + dependencies: + '@typechain/ethers-v6': 0.5.1(ethers@6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(typechain@8.3.2(typescript@5.6.3))(typescript@5.6.3) + ethers: 6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + fs-extra: 9.1.0 + hardhat: 2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.6.3))(typescript@5.6.3)(utf-8-validate@5.0.10) + typechain: 8.3.2(typescript@5.6.3) + + '@types/babel__core@7.20.5': + dependencies: + '@babel/parser': 7.28.5 + '@babel/types': 7.28.5 + '@types/babel__generator': 7.27.0 + '@types/babel__template': 7.4.4 + '@types/babel__traverse': 7.28.0 + + '@types/babel__generator@7.27.0': + dependencies: + '@babel/types': 7.28.5 + + '@types/babel__template@7.4.4': + dependencies: + '@babel/parser': 7.28.5 + '@babel/types': 7.28.5 + + '@types/babel__traverse@7.28.0': + dependencies: + '@babel/types': 7.28.5 + + '@types/bn.js@5.2.0': + dependencies: + '@types/node': 20.19.27 + + '@types/body-parser@1.19.6': + dependencies: + '@types/connect': 3.4.38 + '@types/node': 20.19.27 + + '@types/bonjour@3.5.13': + dependencies: + '@types/node': 20.19.27 + + '@types/chai-as-promised@7.1.8': + dependencies: + '@types/chai': 4.3.20 + + '@types/chai@4.3.20': {} + + '@types/chai@5.2.3': + dependencies: + '@types/deep-eql': 4.0.2 + assertion-error: 2.0.1 + + '@types/concat-stream@1.6.1': + dependencies: + '@types/node': 20.19.27 + + '@types/connect-history-api-fallback@1.5.4': + dependencies: + '@types/express-serve-static-core': 4.19.8 + '@types/node': 20.19.27 + + '@types/connect@3.4.38': + dependencies: + '@types/node': 20.19.27 + + '@types/debug@4.1.12': + dependencies: + '@types/ms': 2.1.0 + + '@types/deep-eql@4.0.2': {} + + '@types/eslint-scope@3.7.7': + dependencies: + '@types/eslint': 9.6.1 + '@types/estree': 1.0.8 + + '@types/eslint@9.6.1': + dependencies: + '@types/estree': 1.0.8 + '@types/json-schema': 7.0.15 + + '@types/estree-jsx@1.0.5': + dependencies: + '@types/estree': 1.0.8 + + '@types/estree@1.0.8': {} + + '@types/express-serve-static-core@4.19.8': + dependencies: + '@types/node': 20.19.27 + '@types/qs': 6.14.0 + '@types/range-parser': 1.2.7 + '@types/send': 1.2.1 + + '@types/express@4.17.25': + dependencies: + '@types/body-parser': 1.19.6 + '@types/express-serve-static-core': 4.19.8 + '@types/qs': 6.14.0 + '@types/serve-static': 1.15.10 + + '@types/form-data@0.0.33': + dependencies: + '@types/node': 20.19.27 + + '@types/glob@7.2.0': + dependencies: + '@types/minimatch': 6.0.0 + '@types/node': 20.19.27 + + '@types/gtag.js@0.0.12': {} + + '@types/hast@3.0.4': + dependencies: + '@types/unist': 3.0.3 + + '@types/history@4.7.11': {} + + '@types/html-minifier-terser@6.1.0': {} + + '@types/http-cache-semantics@4.0.4': {} + + '@types/http-errors@2.0.5': {} + + '@types/http-proxy@1.17.17': + dependencies: + '@types/node': 20.19.27 + + '@types/istanbul-lib-coverage@2.0.6': {} + + '@types/istanbul-lib-report@3.0.3': + dependencies: + '@types/istanbul-lib-coverage': 2.0.6 + + '@types/istanbul-reports@3.0.4': + dependencies: + '@types/istanbul-lib-report': 3.0.3 + + '@types/json-schema@7.0.15': {} + + '@types/lodash@4.17.21': {} + + '@types/mdast@4.0.4': + dependencies: + '@types/unist': 3.0.3 + + '@types/mdx@2.0.13': {} + + '@types/mime@1.3.5': {} + + '@types/minimatch@6.0.0': + dependencies: + minimatch: 10.1.1 + + '@types/mocha@10.0.10': {} + + '@types/ms@2.1.0': {} + + '@types/node@10.17.60': {} + + '@types/node@12.20.55': {} - '@aws-sdk/client-sso@3.954.0': + '@types/node@17.0.45': {} + + '@types/node@20.19.27': dependencies: - '@aws-crypto/sha256-browser': 5.2.0 - '@aws-crypto/sha256-js': 5.2.0 - '@aws-sdk/core': 3.954.0 - '@aws-sdk/middleware-host-header': 3.953.0 - '@aws-sdk/middleware-logger': 3.953.0 - '@aws-sdk/middleware-recursion-detection': 3.953.0 - '@aws-sdk/middleware-user-agent': 3.954.0 - '@aws-sdk/region-config-resolver': 3.953.0 - '@aws-sdk/types': 3.953.0 - '@aws-sdk/util-endpoints': 3.953.0 - '@aws-sdk/util-user-agent-browser': 3.953.0 - '@aws-sdk/util-user-agent-node': 3.954.0 - '@smithy/config-resolver': 4.4.4 - '@smithy/core': 3.19.0 - '@smithy/fetch-http-handler': 5.3.7 - '@smithy/hash-node': 4.2.6 - '@smithy/invalid-dependency': 4.2.6 - '@smithy/middleware-content-length': 4.2.6 - '@smithy/middleware-endpoint': 4.4.0 - '@smithy/middleware-retry': 4.4.16 - '@smithy/middleware-serde': 4.2.7 - '@smithy/middleware-stack': 4.2.6 - '@smithy/node-config-provider': 4.3.6 - '@smithy/node-http-handler': 4.4.6 - '@smithy/protocol-http': 5.3.6 - '@smithy/smithy-client': 4.10.1 - '@smithy/types': 4.10.0 - '@smithy/url-parser': 4.2.6 - '@smithy/util-base64': 4.3.0 - '@smithy/util-body-length-browser': 4.2.0 - '@smithy/util-body-length-node': 4.2.1 - '@smithy/util-defaults-mode-browser': 4.3.15 - '@smithy/util-defaults-mode-node': 4.2.18 - '@smithy/util-endpoints': 3.2.6 - '@smithy/util-middleware': 4.2.6 - '@smithy/util-retry': 4.2.6 - '@smithy/util-utf8': 4.2.0 - tslib: 2.8.1 - transitivePeerDependencies: - - aws-crt + undici-types: 6.21.0 - '@aws-sdk/core@3.954.0': + '@types/node@22.7.5': dependencies: - '@aws-sdk/types': 3.953.0 - '@aws-sdk/xml-builder': 3.953.0 - '@smithy/core': 3.19.0 - '@smithy/node-config-provider': 4.3.6 - '@smithy/property-provider': 4.2.6 - '@smithy/protocol-http': 5.3.6 - '@smithy/signature-v4': 5.3.6 - '@smithy/smithy-client': 4.10.1 - '@smithy/types': 4.10.0 - '@smithy/util-base64': 4.3.0 - '@smithy/util-middleware': 4.2.6 - '@smithy/util-utf8': 4.2.0 - tslib: 2.8.1 + undici-types: 6.19.8 - '@aws-sdk/credential-provider-env@3.954.0': + '@types/node@8.10.66': {} + + '@types/pbkdf2@3.1.2': dependencies: - '@aws-sdk/core': 3.954.0 - '@aws-sdk/types': 3.953.0 - '@smithy/property-provider': 4.2.6 - '@smithy/types': 4.10.0 - tslib: 2.8.1 + '@types/node': 20.19.27 - '@aws-sdk/credential-provider-http@3.954.0': + '@types/prettier@2.7.3': {} + + '@types/prismjs@1.26.5': {} + + '@types/prop-types@15.7.15': {} + + '@types/qs@6.14.0': {} + + '@types/range-parser@1.2.7': {} + + '@types/react-dom@18.3.7(@types/react@18.3.27)': dependencies: - '@aws-sdk/core': 3.954.0 - '@aws-sdk/types': 3.953.0 - '@smithy/fetch-http-handler': 5.3.7 - '@smithy/node-http-handler': 4.4.6 - '@smithy/property-provider': 4.2.6 - '@smithy/protocol-http': 5.3.6 - '@smithy/smithy-client': 4.10.1 - '@smithy/types': 4.10.0 - '@smithy/util-stream': 4.5.7 - tslib: 2.8.1 + '@types/react': 18.3.27 - '@aws-sdk/credential-provider-ini@3.954.0': + '@types/react-router-config@5.0.11': dependencies: - '@aws-sdk/core': 3.954.0 - '@aws-sdk/credential-provider-env': 3.954.0 - '@aws-sdk/credential-provider-http': 3.954.0 - '@aws-sdk/credential-provider-login': 3.954.0 - '@aws-sdk/credential-provider-process': 3.954.0 - '@aws-sdk/credential-provider-sso': 3.954.0 - '@aws-sdk/credential-provider-web-identity': 3.954.0 - '@aws-sdk/nested-clients': 3.954.0 - '@aws-sdk/types': 3.953.0 - '@smithy/credential-provider-imds': 4.2.6 - '@smithy/property-provider': 4.2.6 - '@smithy/shared-ini-file-loader': 4.4.1 - '@smithy/types': 4.10.0 - tslib: 2.8.1 - transitivePeerDependencies: - - aws-crt + '@types/history': 4.7.11 + '@types/react': 18.3.27 + '@types/react-router': 5.1.20 - '@aws-sdk/credential-provider-login@3.954.0': + '@types/react-router-dom@5.3.3': dependencies: - '@aws-sdk/core': 3.954.0 - '@aws-sdk/nested-clients': 3.954.0 - '@aws-sdk/types': 3.953.0 - '@smithy/property-provider': 4.2.6 - '@smithy/protocol-http': 5.3.6 - '@smithy/shared-ini-file-loader': 4.4.1 - '@smithy/types': 4.10.0 - tslib: 2.8.1 - transitivePeerDependencies: - - aws-crt + '@types/history': 4.7.11 + '@types/react': 18.3.27 + '@types/react-router': 5.1.20 - '@aws-sdk/credential-provider-node@3.954.0': + '@types/react-router@5.1.20': dependencies: - '@aws-sdk/credential-provider-env': 3.954.0 - '@aws-sdk/credential-provider-http': 3.954.0 - '@aws-sdk/credential-provider-ini': 3.954.0 - '@aws-sdk/credential-provider-process': 3.954.0 - '@aws-sdk/credential-provider-sso': 3.954.0 - '@aws-sdk/credential-provider-web-identity': 3.954.0 - '@aws-sdk/types': 3.953.0 - '@smithy/credential-provider-imds': 4.2.6 - '@smithy/property-provider': 4.2.6 - '@smithy/shared-ini-file-loader': 4.4.1 - '@smithy/types': 4.10.0 - tslib: 2.8.1 - transitivePeerDependencies: - - aws-crt + '@types/history': 4.7.11 + '@types/react': 18.3.27 - '@aws-sdk/credential-provider-process@3.954.0': + '@types/react@18.3.27': dependencies: - '@aws-sdk/core': 3.954.0 - '@aws-sdk/types': 3.953.0 - '@smithy/property-provider': 4.2.6 - '@smithy/shared-ini-file-loader': 4.4.1 - '@smithy/types': 4.10.0 - tslib: 2.8.1 + '@types/prop-types': 15.7.15 + csstype: 3.2.3 - '@aws-sdk/credential-provider-sso@3.954.0': + '@types/retry@0.12.2': {} + + '@types/sax@1.2.7': dependencies: - '@aws-sdk/client-sso': 3.954.0 - '@aws-sdk/core': 3.954.0 - '@aws-sdk/token-providers': 3.954.0 - '@aws-sdk/types': 3.953.0 - '@smithy/property-provider': 4.2.6 - '@smithy/shared-ini-file-loader': 4.4.1 - '@smithy/types': 4.10.0 - tslib: 2.8.1 - transitivePeerDependencies: - - aws-crt + '@types/node': 20.19.27 - '@aws-sdk/credential-provider-web-identity@3.954.0': + '@types/secp256k1@4.0.7': dependencies: - '@aws-sdk/core': 3.954.0 - '@aws-sdk/nested-clients': 3.954.0 - '@aws-sdk/types': 3.953.0 - '@smithy/property-provider': 4.2.6 - '@smithy/shared-ini-file-loader': 4.4.1 - '@smithy/types': 4.10.0 - tslib: 2.8.1 + '@types/node': 20.19.27 + + '@types/send@0.17.6': + dependencies: + '@types/mime': 1.3.5 + '@types/node': 20.19.27 + + '@types/send@1.2.1': + dependencies: + '@types/node': 20.19.27 + + '@types/serve-index@1.9.4': + dependencies: + '@types/express': 4.17.25 + + '@types/serve-static@1.15.10': + dependencies: + '@types/http-errors': 2.0.5 + '@types/node': 20.19.27 + '@types/send': 0.17.6 + + '@types/sockjs@0.3.36': + dependencies: + '@types/node': 20.19.27 + + '@types/trusted-types@2.0.7': {} + + '@types/unist@2.0.11': {} + + '@types/unist@3.0.3': {} + + '@types/uuid@8.3.4': {} + + '@types/ws@7.4.7': + dependencies: + '@types/node': 20.19.27 + + '@types/ws@8.18.1': + dependencies: + '@types/node': 20.19.27 + + '@types/yargs-parser@21.0.3': {} + + '@types/yargs@17.0.35': + dependencies: + '@types/yargs-parser': 21.0.3 + + '@ungap/structured-clone@1.3.0': {} + + '@uniswap/lib@4.0.1-alpha': {} + + '@uniswap/v2-core@1.0.1': {} + + '@uniswap/v3-core@1.0.1': {} + + '@uniswap/v3-periphery@1.4.4': + dependencies: + '@openzeppelin/contracts': 3.4.2-solc-0.7 + '@uniswap/lib': 4.0.1-alpha + '@uniswap/v2-core': 1.0.1 + '@uniswap/v3-core': 1.0.1 + base64-sol: 1.0.1 + + '@vanilla-extract/css@1.17.3': + dependencies: + '@emotion/hash': 0.9.2 + '@vanilla-extract/private': 1.0.9 + css-what: 6.2.2 + cssesc: 3.0.0 + csstype: 3.2.3 + dedent: 1.7.1 + deep-object-diff: 1.1.9 + deepmerge: 4.3.1 + lru-cache: 10.4.3 + media-query-parser: 2.0.2 + modern-ahocorasick: 1.1.0 + picocolors: 1.1.1 transitivePeerDependencies: - - aws-crt + - babel-plugin-macros - '@aws-sdk/middleware-host-header@3.953.0': + '@vanilla-extract/dynamic@2.1.4': dependencies: - '@aws-sdk/types': 3.953.0 - '@smithy/protocol-http': 5.3.6 - '@smithy/types': 4.10.0 - tslib: 2.8.1 + '@vanilla-extract/private': 1.0.9 + + '@vanilla-extract/private@1.0.9': {} + + '@vanilla-extract/sprinkles@1.6.4(@vanilla-extract/css@1.17.3)': + dependencies: + '@vanilla-extract/css': 1.17.3 + + '@vitejs/plugin-react@4.7.0(vite@5.4.21(@types/node@22.7.5)(terser@5.46.0))': + dependencies: + '@babel/core': 7.28.5 + '@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-react-jsx-source': 7.27.1(@babel/core@7.28.5) + '@rolldown/pluginutils': 1.0.0-beta.27 + '@types/babel__core': 7.20.5 + react-refresh: 0.17.0 + vite: 5.4.21(@types/node@22.7.5)(terser@5.46.0) + transitivePeerDependencies: + - supports-color - '@aws-sdk/middleware-logger@3.953.0': + '@vitest/expect@3.2.4': dependencies: - '@aws-sdk/types': 3.953.0 - '@smithy/types': 4.10.0 - tslib: 2.8.1 + '@types/chai': 5.2.3 + '@vitest/spy': 3.2.4 + '@vitest/utils': 3.2.4 + chai: 5.3.3 + tinyrainbow: 2.0.0 - '@aws-sdk/middleware-recursion-detection@3.953.0': + '@vitest/mocker@3.2.4(vite@5.4.21(@types/node@20.19.27)(terser@5.46.0))': dependencies: - '@aws-sdk/types': 3.953.0 - '@aws/lambda-invoke-store': 0.2.2 - '@smithy/protocol-http': 5.3.6 - '@smithy/types': 4.10.0 - tslib: 2.8.1 + '@vitest/spy': 3.2.4 + estree-walker: 3.0.3 + magic-string: 0.30.21 + optionalDependencies: + vite: 5.4.21(@types/node@20.19.27)(terser@5.46.0) - '@aws-sdk/middleware-user-agent@3.954.0': + '@vitest/mocker@3.2.4(vite@5.4.21(@types/node@22.7.5)(terser@5.46.0))': dependencies: - '@aws-sdk/core': 3.954.0 - '@aws-sdk/types': 3.953.0 - '@aws-sdk/util-endpoints': 3.953.0 - '@smithy/core': 3.19.0 - '@smithy/protocol-http': 5.3.6 - '@smithy/types': 4.10.0 - tslib: 2.8.1 + '@vitest/spy': 3.2.4 + estree-walker: 3.0.3 + magic-string: 0.30.21 + optionalDependencies: + vite: 5.4.21(@types/node@22.7.5)(terser@5.46.0) - '@aws-sdk/nested-clients@3.954.0': + '@vitest/pretty-format@3.2.4': dependencies: - '@aws-crypto/sha256-browser': 5.2.0 - '@aws-crypto/sha256-js': 5.2.0 - '@aws-sdk/core': 3.954.0 - '@aws-sdk/middleware-host-header': 3.953.0 - '@aws-sdk/middleware-logger': 3.953.0 - '@aws-sdk/middleware-recursion-detection': 3.953.0 - '@aws-sdk/middleware-user-agent': 3.954.0 - '@aws-sdk/region-config-resolver': 3.953.0 - '@aws-sdk/types': 3.953.0 - '@aws-sdk/util-endpoints': 3.953.0 - '@aws-sdk/util-user-agent-browser': 3.953.0 - '@aws-sdk/util-user-agent-node': 3.954.0 - '@smithy/config-resolver': 4.4.4 - '@smithy/core': 3.19.0 - '@smithy/fetch-http-handler': 5.3.7 - '@smithy/hash-node': 4.2.6 - '@smithy/invalid-dependency': 4.2.6 - '@smithy/middleware-content-length': 4.2.6 - '@smithy/middleware-endpoint': 4.4.0 - '@smithy/middleware-retry': 4.4.16 - '@smithy/middleware-serde': 4.2.7 - '@smithy/middleware-stack': 4.2.6 - '@smithy/node-config-provider': 4.3.6 - '@smithy/node-http-handler': 4.4.6 - '@smithy/protocol-http': 5.3.6 - '@smithy/smithy-client': 4.10.1 - '@smithy/types': 4.10.0 - '@smithy/url-parser': 4.2.6 - '@smithy/util-base64': 4.3.0 - '@smithy/util-body-length-browser': 4.2.0 - '@smithy/util-body-length-node': 4.2.1 - '@smithy/util-defaults-mode-browser': 4.3.15 - '@smithy/util-defaults-mode-node': 4.2.18 - '@smithy/util-endpoints': 3.2.6 - '@smithy/util-middleware': 4.2.6 - '@smithy/util-retry': 4.2.6 - '@smithy/util-utf8': 4.2.0 - tslib: 2.8.1 - transitivePeerDependencies: - - aws-crt + tinyrainbow: 2.0.0 - '@aws-sdk/region-config-resolver@3.953.0': + '@vitest/runner@3.2.4': dependencies: - '@aws-sdk/types': 3.953.0 - '@smithy/config-resolver': 4.4.4 - '@smithy/node-config-provider': 4.3.6 - '@smithy/types': 4.10.0 - tslib: 2.8.1 + '@vitest/utils': 3.2.4 + pathe: 2.0.3 + strip-literal: 3.1.0 - '@aws-sdk/token-providers@3.954.0': + '@vitest/snapshot@3.2.4': dependencies: - '@aws-sdk/core': 3.954.0 - '@aws-sdk/nested-clients': 3.954.0 - '@aws-sdk/types': 3.953.0 - '@smithy/property-provider': 4.2.6 - '@smithy/shared-ini-file-loader': 4.4.1 - '@smithy/types': 4.10.0 - tslib: 2.8.1 - transitivePeerDependencies: - - aws-crt + '@vitest/pretty-format': 3.2.4 + magic-string: 0.30.21 + pathe: 2.0.3 - '@aws-sdk/types@3.953.0': + '@vitest/spy@3.2.4': dependencies: - '@smithy/types': 4.10.0 - tslib: 2.8.1 + tinyspy: 4.0.4 - '@aws-sdk/util-endpoints@3.953.0': + '@vitest/utils@3.2.4': dependencies: - '@aws-sdk/types': 3.953.0 - '@smithy/types': 4.10.0 - '@smithy/url-parser': 4.2.6 - '@smithy/util-endpoints': 3.2.6 - tslib: 2.8.1 + '@vitest/pretty-format': 3.2.4 + loupe: 3.2.1 + tinyrainbow: 2.0.0 - '@aws-sdk/util-locate-window@3.953.0': + '@wagmi/connectors@6.2.0(d21a8c3adbd777f8e242ee40accde91d)': dependencies: - tslib: 2.8.1 + '@base-org/account': 2.4.0(@types/react@18.3.27)(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(immer@10.0.2)(react@18.3.1)(typescript@5.6.3)(use-sync-external-store@1.4.0(react@18.3.1))(utf-8-validate@5.0.10)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76) + '@coinbase/wallet-sdk': 4.3.6(@types/react@18.3.27)(bufferutil@4.0.9)(immer@10.0.2)(react@18.3.1)(typescript@5.6.3)(use-sync-external-store@1.4.0(react@18.3.1))(utf-8-validate@5.0.10)(zod@3.25.76) + '@gemini-wallet/core': 0.3.2(viem@2.43.1(bufferutil@4.0.9)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.25.76)) + '@metamask/sdk': 0.33.1(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@safe-global/safe-apps-provider': 0.18.6(bufferutil@4.0.9)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@safe-global/safe-apps-sdk': 9.1.0(bufferutil@4.0.9)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@wagmi/core': 2.22.1(@tanstack/query-core@5.90.12)(@types/react@18.3.27)(immer@10.0.2)(react@18.3.1)(typescript@5.6.3)(use-sync-external-store@1.4.0(react@18.3.1))(viem@2.43.1(bufferutil@4.0.9)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.25.76)) + '@walletconnect/ethereum-provider': 2.21.1(@types/react@18.3.27)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.25.76) + cbw-sdk: '@coinbase/wallet-sdk@3.9.3' + porto: 0.2.35(@tanstack/react-query@5.90.12(react@18.3.1))(@types/react@18.3.27)(@wagmi/core@2.22.1(@tanstack/query-core@5.90.12)(@types/react@18.3.27)(immer@10.0.2)(react@18.3.1)(typescript@5.6.3)(use-sync-external-store@1.4.0(react@18.3.1))(viem@2.43.1(bufferutil@4.0.9)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.25.76)))(immer@10.0.2)(react@18.3.1)(typescript@5.6.3)(use-sync-external-store@1.4.0(react@18.3.1))(viem@2.43.1(bufferutil@4.0.9)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.25.76))(wagmi@2.19.5(@tanstack/query-core@5.90.12)(@tanstack/react-query@5.90.12(react@18.3.1))(@types/react@18.3.27)(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(immer@10.0.2)(react@18.3.1)(typescript@5.6.3)(utf-8-validate@5.0.10)(viem@2.43.1(bufferutil@4.0.9)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.25.76))(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)) + viem: 2.43.1(bufferutil@4.0.9)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.25.76) + optionalDependencies: + typescript: 5.6.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 + - ws + - zod - '@aws-sdk/util-user-agent-browser@3.953.0': + '@wagmi/core@2.22.1(@tanstack/query-core@5.90.12)(@types/react@18.3.27)(immer@10.0.2)(react@18.3.1)(typescript@5.6.3)(use-sync-external-store@1.4.0(react@18.3.1))(viem@2.43.1(bufferutil@4.0.9)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.25.76))': dependencies: - '@aws-sdk/types': 3.953.0 - '@smithy/types': 4.10.0 - bowser: 2.13.1 - tslib: 2.8.1 + eventemitter3: 5.0.1 + mipd: 0.0.7(typescript@5.6.3) + viem: 2.43.1(bufferutil@4.0.9)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.25.76) + zustand: 5.0.0(@types/react@18.3.27)(immer@10.0.2)(react@18.3.1)(use-sync-external-store@1.4.0(react@18.3.1)) + optionalDependencies: + '@tanstack/query-core': 5.90.12 + typescript: 5.6.3 + transitivePeerDependencies: + - '@types/react' + - immer + - react + - use-sync-external-store - '@aws-sdk/util-user-agent-node@3.954.0': + '@walletconnect/core@2.21.0(bufferutil@4.0.9)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.25.76)': dependencies: - '@aws-sdk/middleware-user-agent': 3.954.0 - '@aws-sdk/types': 3.953.0 - '@smithy/node-config-provider': 4.3.6 - '@smithy/types': 4.10.0 - tslib: 2.8.1 + '@walletconnect/heartbeat': 1.2.2 + '@walletconnect/jsonrpc-provider': 1.0.14 + '@walletconnect/jsonrpc-types': 1.0.4 + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/jsonrpc-ws-connection': 1.0.16(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@walletconnect/keyvaluestorage': 1.1.1 + '@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.0.9)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@walletconnect/window-getters': 1.0.1 + es-toolkit: 1.33.0 + events: 3.3.0 + uint8arrays: 3.1.0 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - ioredis + - typescript + - uploadthing + - utf-8-validate + - zod + + '@walletconnect/core@2.21.1(bufferutil@4.0.9)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.25.76)': + dependencies: + '@walletconnect/heartbeat': 1.2.2 + '@walletconnect/jsonrpc-provider': 1.0.14 + '@walletconnect/jsonrpc-types': 1.0.4 + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/jsonrpc-ws-connection': 1.0.16(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@walletconnect/keyvaluestorage': 1.1.1 + '@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.0.9)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@walletconnect/window-getters': 1.0.1 + es-toolkit: 1.33.0 + events: 3.3.0 + uint8arrays: 3.1.0 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - ioredis + - typescript + - uploadthing + - utf-8-validate + - zod - '@aws-sdk/util-utf8-browser@3.259.0': + '@walletconnect/environment@1.0.1': dependencies: - tslib: 2.8.1 + tslib: 1.14.1 - '@aws-sdk/xml-builder@3.953.0': + '@walletconnect/ethereum-provider@2.21.1(@types/react@18.3.27)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.25.76)': dependencies: - '@smithy/types': 4.10.0 - fast-xml-parser: 5.2.5 - tslib: 2.8.1 - - '@aws/lambda-invoke-store@0.2.2': {} + '@reown/appkit': 1.7.8(@types/react@18.3.27)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@walletconnect/jsonrpc-http-connection': 1.0.8 + '@walletconnect/jsonrpc-provider': 1.0.14 + '@walletconnect/jsonrpc-types': 1.0.4 + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/keyvaluestorage': 1.1.1 + '@walletconnect/sign-client': 2.21.1(bufferutil@4.0.9)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@walletconnect/types': 2.21.1 + '@walletconnect/universal-provider': 2.21.1(bufferutil@4.0.9)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@walletconnect/utils': 2.21.1(bufferutil@4.0.9)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.25.76) + events: 3.3.0 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@types/react' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - encoding + - ioredis + - react + - typescript + - uploadthing + - utf-8-validate + - zod - '@babel/code-frame@7.27.1': + '@walletconnect/events@1.0.1': dependencies: - '@babel/helper-validator-identifier': 7.28.5 - js-tokens: 4.0.0 - picocolors: 1.1.1 + keyvaluestorage-interface: 1.0.0 + tslib: 1.14.1 - '@babel/compat-data@7.28.5': {} + '@walletconnect/heartbeat@1.2.2': + dependencies: + '@walletconnect/events': 1.0.1 + '@walletconnect/time': 1.0.2 + events: 3.3.0 - '@babel/core@7.28.5': + '@walletconnect/jsonrpc-http-connection@1.0.8': dependencies: - '@babel/code-frame': 7.27.1 - '@babel/generator': 7.28.5 - '@babel/helper-compilation-targets': 7.27.2 - '@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.5) - '@babel/helpers': 7.28.4 - '@babel/parser': 7.28.5 - '@babel/template': 7.27.2 - '@babel/traverse': 7.28.5 - '@babel/types': 7.28.5 - '@jridgewell/remapping': 2.3.5 - convert-source-map: 2.0.0 - debug: 4.4.3(supports-color@8.1.1) - gensync: 1.0.0-beta.2 - json5: 2.2.3 - semver: 6.3.1 + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/safe-json': 1.0.2 + cross-fetch: 3.2.0 + events: 3.3.0 transitivePeerDependencies: - - supports-color + - encoding - '@babel/generator@7.28.5': + '@walletconnect/jsonrpc-provider@1.0.14': dependencies: - '@babel/parser': 7.28.5 - '@babel/types': 7.28.5 - '@jridgewell/gen-mapping': 0.3.13 - '@jridgewell/trace-mapping': 0.3.31 - jsesc: 3.1.0 + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/safe-json': 1.0.2 + events: 3.3.0 - '@babel/helper-compilation-targets@7.27.2': + '@walletconnect/jsonrpc-types@1.0.4': dependencies: - '@babel/compat-data': 7.28.5 - '@babel/helper-validator-option': 7.27.1 - browserslist: 4.28.1 - lru-cache: 5.1.1 - semver: 6.3.1 - - '@babel/helper-globals@7.28.0': {} + events: 3.3.0 + keyvaluestorage-interface: 1.0.0 - '@babel/helper-module-imports@7.27.1': + '@walletconnect/jsonrpc-utils@1.0.8': dependencies: - '@babel/traverse': 7.28.5 - '@babel/types': 7.28.5 - transitivePeerDependencies: - - supports-color + '@walletconnect/environment': 1.0.1 + '@walletconnect/jsonrpc-types': 1.0.4 + tslib: 1.14.1 - '@babel/helper-module-transforms@7.28.3(@babel/core@7.28.5)': + '@walletconnect/jsonrpc-ws-connection@1.0.16(bufferutil@4.0.9)(utf-8-validate@5.0.10)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-module-imports': 7.27.1 - '@babel/helper-validator-identifier': 7.28.5 - '@babel/traverse': 7.28.5 + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/safe-json': 1.0.2 + events: 3.3.0 + ws: 7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10) transitivePeerDependencies: - - supports-color - - '@babel/helper-plugin-utils@7.27.1': {} - - '@babel/helper-string-parser@7.27.1': {} - - '@babel/helper-validator-identifier@7.28.5': {} - - '@babel/helper-validator-option@7.27.1': {} + - bufferutil + - utf-8-validate - '@babel/helpers@7.28.4': + '@walletconnect/keyvaluestorage@1.1.1': dependencies: - '@babel/template': 7.27.2 - '@babel/types': 7.28.5 + '@walletconnect/safe-json': 1.0.2 + idb-keyval: 6.2.2 + unstorage: 1.17.3(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 - '@babel/parser@7.28.5': + '@walletconnect/logger@2.1.2': dependencies: - '@babel/types': 7.28.5 + '@walletconnect/safe-json': 1.0.2 + pino: 7.11.0 - '@babel/plugin-transform-react-jsx-self@7.27.1(@babel/core@7.28.5)': + '@walletconnect/relay-api@1.0.11': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-plugin-utils': 7.27.1 + '@walletconnect/jsonrpc-types': 1.0.4 - '@babel/plugin-transform-react-jsx-source@7.27.1(@babel/core@7.28.5)': + '@walletconnect/relay-auth@1.1.0': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-plugin-utils': 7.27.1 - - '@babel/runtime@7.28.4': {} + '@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 - '@babel/template@7.27.2': + '@walletconnect/safe-json@1.0.2': dependencies: - '@babel/code-frame': 7.27.1 - '@babel/parser': 7.28.5 - '@babel/types': 7.28.5 + tslib: 1.14.1 - '@babel/traverse@7.28.5': + '@walletconnect/sign-client@2.21.0(bufferutil@4.0.9)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.25.76)': dependencies: - '@babel/code-frame': 7.27.1 - '@babel/generator': 7.28.5 - '@babel/helper-globals': 7.28.0 - '@babel/parser': 7.28.5 - '@babel/template': 7.27.2 - '@babel/types': 7.28.5 - debug: 4.4.3(supports-color@8.1.1) + '@walletconnect/core': 2.21.0(bufferutil@4.0.9)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@walletconnect/events': 1.0.1 + '@walletconnect/heartbeat': 1.2.2 + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/logger': 2.1.2 + '@walletconnect/time': 1.0.2 + '@walletconnect/types': 2.21.0 + '@walletconnect/utils': 2.21.0(bufferutil@4.0.9)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.25.76) + events: 3.3.0 transitivePeerDependencies: - - supports-color - - '@babel/types@7.28.5': - dependencies: - '@babel/helper-string-parser': 7.27.1 - '@babel/helper-validator-identifier': 7.28.5 + - '@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 - '@base-org/account@2.4.0(@types/react@18.3.27)(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(immer@10.0.2)(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)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@4.2.1)': + '@walletconnect/sign-client@2.21.1(bufferutil@4.0.9)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.25.76)': dependencies: - '@coinbase/cdp-sdk': 1.40.1(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.18.0(bufferutil@4.0.9)(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.2.1) - preact: 10.24.2 - viem: 2.43.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) - zustand: 5.0.3(@types/react@18.3.27)(immer@10.0.2)(react@18.3.1)(use-sync-external-store@1.4.0(react@18.3.1)) + '@walletconnect/core': 2.21.1(bufferutil@4.0.9)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@walletconnect/events': 1.0.1 + '@walletconnect/heartbeat': 1.2.2 + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/logger': 2.1.2 + '@walletconnect/time': 1.0.2 + '@walletconnect/types': 2.21.1 + '@walletconnect/utils': 2.21.1(bufferutil@4.0.9)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.25.76) + events: 3.3.0 transitivePeerDependencies: - - '@types/react' + - '@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 - - debug - - encoding - - fastestsmallesttextencoderdecoder - - immer - - react + - db0 + - ioredis - typescript - - use-sync-external-store + - uploadthing - utf-8-validate - - ws - zod - '@bytecodealliance/preview2-shim@0.17.0': {} + '@walletconnect/time@1.0.2': + dependencies: + tslib: 1.14.1 - '@coinbase/cdp-sdk@1.40.1(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))': + '@walletconnect/types@2.21.0': dependencies: - '@solana-program/system': 0.8.1(@solana/kit@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))) - '@solana-program/token': 0.6.0(@solana/kit@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))) - '@solana/kit': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) - '@solana/web3.js': 1.98.4(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10) - abitype: 1.0.6(typescript@5.9.3)(zod@3.25.76) - axios: 1.13.2(debug@4.4.3) - axios-retry: 4.5.0(axios@1.13.2) - jose: 6.1.3 - md5: 2.3.0 - uncrypto: 0.1.3 - viem: 2.43.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) - zod: 3.25.76 + '@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: - - bufferutil - - debug - - encoding - - fastestsmallesttextencoderdecoder - - typescript - - utf-8-validate - - ws + - '@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 - '@coinbase/wallet-sdk@3.9.3': + '@walletconnect/types@2.21.1': 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.1 - keccak: 3.0.4 - preact: 10.28.0 - sha.js: 2.4.12 + '@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: - - supports-color + - '@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 - '@coinbase/wallet-sdk@4.3.6(@types/react@18.3.27)(bufferutil@4.0.9)(immer@10.0.2)(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.2.1)': + '@walletconnect/universal-provider@2.21.0(bufferutil@4.0.9)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.25.76)': dependencies: - '@noble/hashes': 1.4.0 - clsx: 1.2.1 - eventemitter3: 5.0.1 - idb-keyval: 6.2.1 - ox: 0.6.9(typescript@5.9.3)(zod@4.2.1) - preact: 10.24.2 - viem: 2.43.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) - zustand: 5.0.3(@types/react@18.3.27)(immer@10.0.2)(react@18.3.1)(use-sync-external-store@1.4.0(react@18.3.1)) + '@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.0.9)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@walletconnect/types': 2.21.0 + '@walletconnect/utils': 2.21.0(bufferutil@4.0.9)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.25.76) + es-toolkit: 1.33.0 + events: 3.3.0 transitivePeerDependencies: - - '@types/react' + - '@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 - - immer - - react + - db0 + - encoding + - ioredis - typescript - - use-sync-external-store + - uploadthing - utf-8-validate - zod - '@cspotcode/source-map-support@0.8.1': - dependencies: - '@jridgewell/trace-mapping': 0.3.9 - - '@ecies/ciphers@0.2.5(@noble/ciphers@1.3.0)': - dependencies: - '@noble/ciphers': 1.3.0 - - '@emotion/hash@0.9.2': {} - - '@esbuild/aix-ppc64@0.21.5': - optional: true - - '@esbuild/android-arm64@0.21.5': - optional: true - - '@esbuild/android-arm@0.21.5': - optional: true - - '@esbuild/android-x64@0.21.5': - optional: true - - '@esbuild/darwin-arm64@0.21.5': - optional: true - - '@esbuild/darwin-x64@0.21.5': - optional: true - - '@esbuild/freebsd-arm64@0.21.5': - optional: true - - '@esbuild/freebsd-x64@0.21.5': - optional: true - - '@esbuild/linux-arm64@0.21.5': - optional: true - - '@esbuild/linux-arm@0.21.5': - optional: true - - '@esbuild/linux-ia32@0.21.5': - optional: true - - '@esbuild/linux-loong64@0.21.5': - optional: true - - '@esbuild/linux-mips64el@0.21.5': - optional: true - - '@esbuild/linux-ppc64@0.21.5': - optional: true - - '@esbuild/linux-riscv64@0.21.5': - optional: true - - '@esbuild/linux-s390x@0.21.5': - optional: true - - '@esbuild/linux-x64@0.21.5': - optional: true - - '@esbuild/netbsd-x64@0.21.5': - optional: true - - '@esbuild/openbsd-x64@0.21.5': - optional: true - - '@esbuild/sunos-x64@0.21.5': - optional: true - - '@esbuild/win32-arm64@0.21.5': - optional: true - - '@esbuild/win32-ia32@0.21.5': - optional: true - - '@esbuild/win32-x64@0.21.5': - optional: true - - '@ethereumjs/common@3.2.0': + '@walletconnect/universal-provider@2.21.1(bufferutil@4.0.9)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.25.76)': dependencies: - '@ethereumjs/util': 8.1.0 - crc-32: 1.2.2 - - '@ethereumjs/rlp@4.0.1': {} - - '@ethereumjs/rlp@5.0.2': {} + '@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.0.9)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@walletconnect/types': 2.21.1 + '@walletconnect/utils': 2.21.1(bufferutil@4.0.9)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.25.76) + es-toolkit: 1.33.0 + events: 3.3.0 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - encoding + - ioredis + - typescript + - uploadthing + - utf-8-validate + - zod - '@ethereumjs/tx@4.2.0': + '@walletconnect/utils@2.21.0(bufferutil@4.0.9)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.25.76)': dependencies: - '@ethereumjs/common': 3.2.0 - '@ethereumjs/rlp': 4.0.1 - '@ethereumjs/util': 8.1.0 - ethereum-cryptography: 2.2.1 + '@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.0.9)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.25.76) + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - ioredis + - typescript + - uploadthing + - utf-8-validate + - zod - '@ethereumjs/util@8.1.0': + '@walletconnect/utils@2.21.1(bufferutil@4.0.9)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.25.76)': dependencies: - '@ethereumjs/rlp': 4.0.1 - ethereum-cryptography: 2.2.1 - micro-ftch: 0.3.1 + '@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.0.9)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.25.76) + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - ioredis + - typescript + - uploadthing + - utf-8-validate + - zod - '@ethereumjs/util@9.1.0': + '@walletconnect/window-getters@1.0.1': dependencies: - '@ethereumjs/rlp': 5.0.2 - ethereum-cryptography: 2.2.1 + tslib: 1.14.1 - '@ethersproject/abi@5.8.0': + '@walletconnect/window-metadata@1.0.1': dependencies: - '@ethersproject/address': 5.8.0 - '@ethersproject/bignumber': 5.8.0 - '@ethersproject/bytes': 5.8.0 - '@ethersproject/constants': 5.8.0 - '@ethersproject/hash': 5.8.0 - '@ethersproject/keccak256': 5.8.0 - '@ethersproject/logger': 5.8.0 - '@ethersproject/properties': 5.8.0 - '@ethersproject/strings': 5.8.0 + '@walletconnect/window-getters': 1.0.1 + tslib: 1.14.1 - '@ethersproject/abstract-provider@5.8.0': + '@webassemblyjs/ast@1.14.1': dependencies: - '@ethersproject/bignumber': 5.8.0 - '@ethersproject/bytes': 5.8.0 - '@ethersproject/logger': 5.8.0 - '@ethersproject/networks': 5.8.0 - '@ethersproject/properties': 5.8.0 - '@ethersproject/transactions': 5.8.0 - '@ethersproject/web': 5.8.0 + '@webassemblyjs/helper-numbers': 1.13.2 + '@webassemblyjs/helper-wasm-bytecode': 1.13.2 - '@ethersproject/abstract-signer@5.8.0': - dependencies: - '@ethersproject/abstract-provider': 5.8.0 - '@ethersproject/bignumber': 5.8.0 - '@ethersproject/bytes': 5.8.0 - '@ethersproject/logger': 5.8.0 - '@ethersproject/properties': 5.8.0 + '@webassemblyjs/floating-point-hex-parser@1.13.2': {} - '@ethersproject/address@5.6.1': - dependencies: - '@ethersproject/bignumber': 5.8.0 - '@ethersproject/bytes': 5.8.0 - '@ethersproject/keccak256': 5.8.0 - '@ethersproject/logger': 5.8.0 - '@ethersproject/rlp': 5.8.0 + '@webassemblyjs/helper-api-error@1.13.2': {} - '@ethersproject/address@5.8.0': - dependencies: - '@ethersproject/bignumber': 5.8.0 - '@ethersproject/bytes': 5.8.0 - '@ethersproject/keccak256': 5.8.0 - '@ethersproject/logger': 5.8.0 - '@ethersproject/rlp': 5.8.0 + '@webassemblyjs/helper-buffer@1.14.1': {} - '@ethersproject/base64@5.8.0': + '@webassemblyjs/helper-numbers@1.13.2': dependencies: - '@ethersproject/bytes': 5.8.0 + '@webassemblyjs/floating-point-hex-parser': 1.13.2 + '@webassemblyjs/helper-api-error': 1.13.2 + '@xtuc/long': 4.2.2 - '@ethersproject/basex@5.8.0': - dependencies: - '@ethersproject/bytes': 5.8.0 - '@ethersproject/properties': 5.8.0 + '@webassemblyjs/helper-wasm-bytecode@1.13.2': {} - '@ethersproject/bignumber@5.8.0': + '@webassemblyjs/helper-wasm-section@1.14.1': dependencies: - '@ethersproject/bytes': 5.8.0 - '@ethersproject/logger': 5.8.0 - bn.js: 5.2.2 + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/helper-buffer': 1.14.1 + '@webassemblyjs/helper-wasm-bytecode': 1.13.2 + '@webassemblyjs/wasm-gen': 1.14.1 - '@ethersproject/bytes@5.8.0': + '@webassemblyjs/ieee754@1.13.2': dependencies: - '@ethersproject/logger': 5.8.0 + '@xtuc/ieee754': 1.2.0 - '@ethersproject/constants@5.8.0': + '@webassemblyjs/leb128@1.13.2': dependencies: - '@ethersproject/bignumber': 5.8.0 + '@xtuc/long': 4.2.2 - '@ethersproject/contracts@5.8.0': + '@webassemblyjs/utf8@1.13.2': {} + + '@webassemblyjs/wasm-edit@1.14.1': dependencies: - '@ethersproject/abi': 5.8.0 - '@ethersproject/abstract-provider': 5.8.0 - '@ethersproject/abstract-signer': 5.8.0 - '@ethersproject/address': 5.8.0 - '@ethersproject/bignumber': 5.8.0 - '@ethersproject/bytes': 5.8.0 - '@ethersproject/constants': 5.8.0 - '@ethersproject/logger': 5.8.0 - '@ethersproject/properties': 5.8.0 - '@ethersproject/transactions': 5.8.0 + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/helper-buffer': 1.14.1 + '@webassemblyjs/helper-wasm-bytecode': 1.13.2 + '@webassemblyjs/helper-wasm-section': 1.14.1 + '@webassemblyjs/wasm-gen': 1.14.1 + '@webassemblyjs/wasm-opt': 1.14.1 + '@webassemblyjs/wasm-parser': 1.14.1 + '@webassemblyjs/wast-printer': 1.14.1 - '@ethersproject/hash@5.8.0': + '@webassemblyjs/wasm-gen@1.14.1': dependencies: - '@ethersproject/abstract-signer': 5.8.0 - '@ethersproject/address': 5.8.0 - '@ethersproject/base64': 5.8.0 - '@ethersproject/bignumber': 5.8.0 - '@ethersproject/bytes': 5.8.0 - '@ethersproject/keccak256': 5.8.0 - '@ethersproject/logger': 5.8.0 - '@ethersproject/properties': 5.8.0 - '@ethersproject/strings': 5.8.0 + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/helper-wasm-bytecode': 1.13.2 + '@webassemblyjs/ieee754': 1.13.2 + '@webassemblyjs/leb128': 1.13.2 + '@webassemblyjs/utf8': 1.13.2 - '@ethersproject/hdnode@5.8.0': + '@webassemblyjs/wasm-opt@1.14.1': dependencies: - '@ethersproject/abstract-signer': 5.8.0 - '@ethersproject/basex': 5.8.0 - '@ethersproject/bignumber': 5.8.0 - '@ethersproject/bytes': 5.8.0 - '@ethersproject/logger': 5.8.0 - '@ethersproject/pbkdf2': 5.8.0 - '@ethersproject/properties': 5.8.0 - '@ethersproject/sha2': 5.8.0 - '@ethersproject/signing-key': 5.8.0 - '@ethersproject/strings': 5.8.0 - '@ethersproject/transactions': 5.8.0 - '@ethersproject/wordlists': 5.8.0 + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/helper-buffer': 1.14.1 + '@webassemblyjs/wasm-gen': 1.14.1 + '@webassemblyjs/wasm-parser': 1.14.1 - '@ethersproject/json-wallets@5.8.0': + '@webassemblyjs/wasm-parser@1.14.1': dependencies: - '@ethersproject/abstract-signer': 5.8.0 - '@ethersproject/address': 5.8.0 - '@ethersproject/bytes': 5.8.0 - '@ethersproject/hdnode': 5.8.0 - '@ethersproject/keccak256': 5.8.0 - '@ethersproject/logger': 5.8.0 - '@ethersproject/pbkdf2': 5.8.0 - '@ethersproject/properties': 5.8.0 - '@ethersproject/random': 5.8.0 - '@ethersproject/strings': 5.8.0 - '@ethersproject/transactions': 5.8.0 - aes-js: 3.0.0 - scrypt-js: 3.0.1 + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/helper-api-error': 1.13.2 + '@webassemblyjs/helper-wasm-bytecode': 1.13.2 + '@webassemblyjs/ieee754': 1.13.2 + '@webassemblyjs/leb128': 1.13.2 + '@webassemblyjs/utf8': 1.13.2 - '@ethersproject/keccak256@5.8.0': + '@webassemblyjs/wast-printer@1.14.1': dependencies: - '@ethersproject/bytes': 5.8.0 - js-sha3: 0.8.0 + '@webassemblyjs/ast': 1.14.1 + '@xtuc/long': 4.2.2 - '@ethersproject/logger@5.8.0': {} + '@xtuc/ieee754@1.2.0': {} - '@ethersproject/networks@5.8.0': - dependencies: - '@ethersproject/logger': 5.8.0 + '@xtuc/long@4.2.2': {} - '@ethersproject/pbkdf2@5.8.0': - dependencies: - '@ethersproject/bytes': 5.8.0 - '@ethersproject/sha2': 5.8.0 + abbrev@1.0.9: {} - '@ethersproject/properties@5.8.0': - dependencies: - '@ethersproject/logger': 5.8.0 + abitype@1.0.6(typescript@5.6.3)(zod@3.25.76): + optionalDependencies: + typescript: 5.6.3 + zod: 3.25.76 - '@ethersproject/providers@5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)': + abitype@1.0.8(typescript@5.6.3)(zod@3.25.76): + optionalDependencies: + typescript: 5.6.3 + zod: 3.25.76 + + abitype@1.2.3(typescript@5.6.3)(zod@3.22.4): + optionalDependencies: + typescript: 5.6.3 + zod: 3.22.4 + + abitype@1.2.3(typescript@5.6.3)(zod@3.25.76): + optionalDependencies: + typescript: 5.6.3 + zod: 3.25.76 + + abitype@1.2.3(typescript@5.6.3)(zod@4.2.1): + optionalDependencies: + typescript: 5.6.3 + zod: 4.2.1 + + accepts@1.3.8: dependencies: - '@ethersproject/abstract-provider': 5.8.0 - '@ethersproject/abstract-signer': 5.8.0 - '@ethersproject/address': 5.8.0 - '@ethersproject/base64': 5.8.0 - '@ethersproject/basex': 5.8.0 - '@ethersproject/bignumber': 5.8.0 - '@ethersproject/bytes': 5.8.0 - '@ethersproject/constants': 5.8.0 - '@ethersproject/hash': 5.8.0 - '@ethersproject/logger': 5.8.0 - '@ethersproject/networks': 5.8.0 - '@ethersproject/properties': 5.8.0 - '@ethersproject/random': 5.8.0 - '@ethersproject/rlp': 5.8.0 - '@ethersproject/sha2': 5.8.0 - '@ethersproject/strings': 5.8.0 - '@ethersproject/transactions': 5.8.0 - '@ethersproject/web': 5.8.0 - bech32: 1.1.4 - ws: 8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) - transitivePeerDependencies: - - bufferutil - - utf-8-validate + mime-types: 2.1.35 + negotiator: 0.6.3 - '@ethersproject/random@5.8.0': + acorn-import-phases@1.0.4(acorn@8.15.0): dependencies: - '@ethersproject/bytes': 5.8.0 - '@ethersproject/logger': 5.8.0 + acorn: 8.15.0 - '@ethersproject/rlp@5.8.0': + acorn-jsx@5.3.2(acorn@8.15.0): dependencies: - '@ethersproject/bytes': 5.8.0 - '@ethersproject/logger': 5.8.0 + acorn: 8.15.0 - '@ethersproject/sha2@5.8.0': + acorn-walk@8.3.4: dependencies: - '@ethersproject/bytes': 5.8.0 - '@ethersproject/logger': 5.8.0 - hash.js: 1.1.7 + acorn: 8.15.0 - '@ethersproject/signing-key@5.8.0': + acorn@8.15.0: {} + + address@1.2.2: {} + + adm-zip@0.4.16: {} + + aes-js@3.0.0: {} + + aes-js@4.0.0-beta.5: {} + + agent-base@6.0.2: dependencies: - '@ethersproject/bytes': 5.8.0 - '@ethersproject/logger': 5.8.0 - '@ethersproject/properties': 5.8.0 - bn.js: 5.2.2 - elliptic: 6.6.1 - hash.js: 1.1.7 + debug: 4.4.3(supports-color@8.1.1) + transitivePeerDependencies: + - supports-color - '@ethersproject/solidity@5.8.0': + agentkeepalive@4.6.0: dependencies: - '@ethersproject/bignumber': 5.8.0 - '@ethersproject/bytes': 5.8.0 - '@ethersproject/keccak256': 5.8.0 - '@ethersproject/logger': 5.8.0 - '@ethersproject/sha2': 5.8.0 - '@ethersproject/strings': 5.8.0 + humanize-ms: 1.2.1 - '@ethersproject/strings@5.8.0': + aggregate-error@3.1.0: dependencies: - '@ethersproject/bytes': 5.8.0 - '@ethersproject/constants': 5.8.0 - '@ethersproject/logger': 5.8.0 + clean-stack: 2.2.0 + indent-string: 4.0.0 - '@ethersproject/transactions@5.8.0': + ajv-formats@2.1.1(ajv@8.17.1): + optionalDependencies: + ajv: 8.17.1 + + ajv-keywords@3.5.2(ajv@6.12.6): dependencies: - '@ethersproject/address': 5.8.0 - '@ethersproject/bignumber': 5.8.0 - '@ethersproject/bytes': 5.8.0 - '@ethersproject/constants': 5.8.0 - '@ethersproject/keccak256': 5.8.0 - '@ethersproject/logger': 5.8.0 - '@ethersproject/properties': 5.8.0 - '@ethersproject/rlp': 5.8.0 - '@ethersproject/signing-key': 5.8.0 + ajv: 6.12.6 - '@ethersproject/units@5.8.0': + ajv-keywords@5.1.0(ajv@8.17.1): dependencies: - '@ethersproject/bignumber': 5.8.0 - '@ethersproject/constants': 5.8.0 - '@ethersproject/logger': 5.8.0 + ajv: 8.17.1 + fast-deep-equal: 3.1.3 - '@ethersproject/wallet@5.8.0': + ajv@6.12.6: dependencies: - '@ethersproject/abstract-provider': 5.8.0 - '@ethersproject/abstract-signer': 5.8.0 - '@ethersproject/address': 5.8.0 - '@ethersproject/bignumber': 5.8.0 - '@ethersproject/bytes': 5.8.0 - '@ethersproject/hash': 5.8.0 - '@ethersproject/hdnode': 5.8.0 - '@ethersproject/json-wallets': 5.8.0 - '@ethersproject/keccak256': 5.8.0 - '@ethersproject/logger': 5.8.0 - '@ethersproject/properties': 5.8.0 - '@ethersproject/random': 5.8.0 - '@ethersproject/signing-key': 5.8.0 - '@ethersproject/transactions': 5.8.0 - '@ethersproject/wordlists': 5.8.0 + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 - '@ethersproject/web@5.8.0': + ajv@8.17.1: dependencies: - '@ethersproject/base64': 5.8.0 - '@ethersproject/bytes': 5.8.0 - '@ethersproject/logger': 5.8.0 - '@ethersproject/properties': 5.8.0 - '@ethersproject/strings': 5.8.0 + fast-deep-equal: 3.1.3 + fast-uri: 3.1.0 + json-schema-traverse: 1.0.0 + require-from-string: 2.0.2 - '@ethersproject/wordlists@5.8.0': + algoliasearch-helper@3.27.0(algoliasearch@5.47.0): dependencies: - '@ethersproject/bytes': 5.8.0 - '@ethersproject/hash': 5.8.0 - '@ethersproject/logger': 5.8.0 - '@ethersproject/properties': 5.8.0 - '@ethersproject/strings': 5.8.0 + '@algolia/events': 4.0.1 + algoliasearch: 5.47.0 - '@fastify/busboy@2.1.1': {} + algoliasearch@5.47.0: + dependencies: + '@algolia/abtesting': 1.13.0 + '@algolia/client-abtesting': 5.47.0 + '@algolia/client-analytics': 5.47.0 + '@algolia/client-common': 5.47.0 + '@algolia/client-insights': 5.47.0 + '@algolia/client-personalization': 5.47.0 + '@algolia/client-query-suggestions': 5.47.0 + '@algolia/client-search': 5.47.0 + '@algolia/ingestion': 1.47.0 + '@algolia/monitoring': 1.47.0 + '@algolia/recommend': 5.47.0 + '@algolia/requester-browser-xhr': 5.47.0 + '@algolia/requester-fetch': 5.47.0 + '@algolia/requester-node-http': 5.47.0 - '@gemini-wallet/core@0.3.2(viem@2.43.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1))': + amazon-cognito-identity-js@6.3.16: dependencies: - '@metamask/rpc-errors': 7.0.2 - eventemitter3: 5.0.1 - viem: 2.43.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) + '@aws-crypto/sha256-js': 1.2.2 + buffer: 4.9.2 + fast-base64-decode: 1.0.0 + isomorphic-unfetch: 3.1.0 + js-cookie: 2.2.1 transitivePeerDependencies: - - supports-color + - encoding - '@isaacs/balanced-match@4.0.1': {} + amdefine@1.0.1: + optional: true - '@isaacs/brace-expansion@5.0.0': + ansi-align@3.0.1: dependencies: - '@isaacs/balanced-match': 4.0.1 + string-width: 4.2.3 - '@jridgewell/gen-mapping@0.3.13': - dependencies: - '@jridgewell/sourcemap-codec': 1.5.5 - '@jridgewell/trace-mapping': 0.3.31 + ansi-colors@4.1.3: {} - '@jridgewell/remapping@2.3.5': + ansi-escapes@4.3.2: dependencies: - '@jridgewell/gen-mapping': 0.3.13 - '@jridgewell/trace-mapping': 0.3.31 + type-fest: 0.21.3 - '@jridgewell/resolve-uri@3.1.2': {} + ansi-html-community@0.0.8: {} - '@jridgewell/sourcemap-codec@1.5.5': {} + ansi-regex@3.0.1: {} - '@jridgewell/trace-mapping@0.3.31': + ansi-regex@5.0.1: {} + + ansi-regex@6.2.2: {} + + ansi-styles@3.2.1: dependencies: - '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.5.5 + color-convert: 1.9.3 - '@jridgewell/trace-mapping@0.3.9': + ansi-styles@4.3.0: dependencies: - '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.5.5 + color-convert: 2.0.1 - '@lit-labs/ssr-dom-shim@1.4.0': {} + ansi-styles@6.2.3: {} - '@lit/reactive-element@2.1.1': - dependencies: - '@lit-labs/ssr-dom-shim': 1.4.0 + antlr4ts@0.5.0-alpha.4: {} - '@metamask/eth-json-rpc-provider@1.0.1': - dependencies: - '@metamask/json-rpc-engine': 7.3.3 - '@metamask/safe-event-emitter': 3.1.2 - '@metamask/utils': 5.0.2 - transitivePeerDependencies: - - supports-color + any-promise@1.3.0: {} - '@metamask/json-rpc-engine@7.3.3': + anymatch@3.1.3: dependencies: - '@metamask/rpc-errors': 6.4.0 - '@metamask/safe-event-emitter': 3.1.2 - '@metamask/utils': 8.5.0 - transitivePeerDependencies: - - supports-color + normalize-path: 3.0.0 + picomatch: 2.3.1 - '@metamask/json-rpc-engine@8.0.2': - dependencies: - '@metamask/rpc-errors': 6.4.0 - '@metamask/safe-event-emitter': 3.1.2 - '@metamask/utils': 8.5.0 - transitivePeerDependencies: - - supports-color + arg@4.1.3: {} - '@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 + arg@5.0.2: {} - '@metamask/object-multiplex@2.1.0': + argparse@1.0.10: dependencies: - once: 1.4.0 - readable-stream: 3.6.2 + sprintf-js: 1.0.3 - '@metamask/onboarding@1.0.1': - dependencies: - bowser: 2.13.1 + argparse@2.0.1: {} - '@metamask/providers@16.1.0': + array-back@3.1.0: {} + + array-back@4.0.2: {} + + array-flatten@1.1.1: {} + + array-union@2.1.0: {} + + array-uniq@1.0.3: {} + + asap@2.0.6: {} + + asn1js@3.0.7: 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 + pvtsutils: 1.3.6 + pvutils: 1.1.5 + tslib: 2.8.1 - '@metamask/rpc-errors@6.4.0': + assertion-error@1.1.0: {} + + assertion-error@2.0.1: {} + + astral-regex@2.0.0: {} + + astring@1.9.0: {} + + async-mutex@0.2.6: dependencies: - '@metamask/utils': 9.3.0 - fast-safe-stringify: 2.1.1 - transitivePeerDependencies: - - supports-color + tslib: 2.8.1 - '@metamask/rpc-errors@7.0.2': + async-retry@1.3.3: dependencies: - '@metamask/utils': 11.9.0 - fast-safe-stringify: 2.1.1 - transitivePeerDependencies: - - supports-color + retry: 0.13.1 - '@metamask/safe-event-emitter@2.0.0': {} + async@1.5.2: {} - '@metamask/safe-event-emitter@3.1.2': {} + asynckit@0.4.0: {} - '@metamask/sdk-analytics@0.0.5': + at-least-node@1.0.0: {} + + atomic-sleep@1.0.0: {} + + autoprefixer@10.4.23(postcss@8.5.6): dependencies: - openapi-fetch: 0.13.8 + browserslist: 4.28.1 + caniuse-lite: 1.0.30001760 + fraction.js: 5.3.4 + picocolors: 1.1.1 + postcss: 8.5.6 + postcss-value-parser: 4.2.0 - '@metamask/sdk-communication-layer@0.33.1(cross-fetch@4.1.0)(eciesjs@0.4.16)(eventemitter2@6.4.9)(readable-stream@3.6.2)(socket.io-client@4.8.1(bufferutil@4.0.9)(utf-8-validate@5.0.10))': + available-typed-arrays@1.0.7: dependencies: - '@metamask/sdk-analytics': 0.0.5 - bufferutil: 4.0.9 - cross-fetch: 4.1.0 - date-fns: 2.30.0 - debug: 4.3.4 - eciesjs: 0.4.16 - eventemitter2: 6.4.9 - readable-stream: 3.6.2 - socket.io-client: 4.8.1(bufferutil@4.0.9)(utf-8-validate@5.0.10) - utf-8-validate: 5.0.10 - uuid: 8.3.2 - transitivePeerDependencies: - - supports-color + possible-typed-array-names: 1.1.0 - '@metamask/sdk-install-modal-web@0.32.1': + axios-retry@4.5.0(axios@1.13.2): dependencies: - '@paulmillr/qr': 0.2.1 + axios: 1.13.2(debug@4.4.3) + is-retry-allowed: 2.2.0 - '@metamask/sdk@0.33.1(bufferutil@4.0.9)(utf-8-validate@5.0.10)': + axios@1.13.2(debug@4.4.3): dependencies: - '@babel/runtime': 7.28.4 - '@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.16)(eventemitter2@6.4.9)(readable-stream@3.6.2)(socket.io-client@4.8.1(bufferutil@4.0.9)(utf-8-validate@5.0.10)) - '@metamask/sdk-install-modal-web': 0.32.1 - '@paulmillr/qr': 0.2.1 - bowser: 2.13.1 - cross-fetch: 4.1.0 - debug: 4.3.4 - eciesjs: 0.4.16 - 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.1(bufferutil@4.0.9)(utf-8-validate@5.0.10) - tslib: 2.8.1 - util: 0.12.5 - uuid: 8.3.2 + follow-redirects: 1.15.11(debug@4.4.3) + form-data: 4.0.5 + proxy-from-env: 1.1.0 transitivePeerDependencies: - - bufferutil - - encoding - - supports-color - - utf-8-validate + - debug - '@metamask/superstruct@3.2.1': {} + babel-loader@9.2.1(@babel/core@7.28.5)(webpack@5.104.1): + dependencies: + '@babel/core': 7.28.5 + find-cache-dir: 4.0.0 + schema-utils: 4.3.3 + webpack: 5.104.1 - '@metamask/utils@11.9.0': + babel-plugin-dynamic-import-node@2.3.3: 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.21 - debug: 4.4.3(supports-color@8.1.1) - lodash: 4.17.21 - pony-cause: 2.1.11 - semver: 7.7.3 - uuid: 9.0.1 - transitivePeerDependencies: - - supports-color + object.assign: 4.1.7 - '@metamask/utils@5.0.2': + babel-plugin-polyfill-corejs2@0.4.14(@babel/core@7.28.5): dependencies: - '@ethereumjs/tx': 4.2.0 - '@types/debug': 4.1.12 - debug: 4.4.3(supports-color@8.1.1) - semver: 7.7.3 - superstruct: 1.0.4 + '@babel/compat-data': 7.28.6 + '@babel/core': 7.28.5 + '@babel/helper-define-polyfill-provider': 0.6.5(@babel/core@7.28.5) + semver: 6.3.1 transitivePeerDependencies: - supports-color - '@metamask/utils@8.5.0': + babel-plugin-polyfill-corejs3@0.13.0(@babel/core@7.28.5): 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.3.4 - pony-cause: 2.1.11 - semver: 7.7.3 - uuid: 9.0.1 + '@babel/core': 7.28.5 + '@babel/helper-define-polyfill-provider': 0.6.5(@babel/core@7.28.5) + core-js-compat: 3.47.0 transitivePeerDependencies: - supports-color - '@metamask/utils@9.3.0': + babel-plugin-polyfill-regenerator@0.6.5(@babel/core@7.28.5): 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.3.4 - pony-cause: 2.1.11 - semver: 7.7.3 - uuid: 9.0.1 + '@babel/core': 7.28.5 + '@babel/helper-define-polyfill-provider': 0.6.5(@babel/core@7.28.5) transitivePeerDependencies: - supports-color - '@noble/ciphers@1.2.1': {} - - '@noble/ciphers@1.3.0': {} + bail@2.0.2: {} - '@noble/curves@1.2.0': - dependencies: - '@noble/hashes': 1.3.2 + balanced-match@1.0.2: {} - '@noble/curves@1.4.2': + base-x@3.0.11: dependencies: - '@noble/hashes': 1.4.0 + safe-buffer: 5.2.1 - '@noble/curves@1.8.0': - dependencies: - '@noble/hashes': 1.7.0 + base-x@5.0.1: {} - '@noble/curves@1.8.1': - dependencies: - '@noble/hashes': 1.7.1 + base64-js@1.5.1: {} - '@noble/curves@1.8.2': - dependencies: - '@noble/hashes': 1.7.2 + base64-sol@1.0.1: {} - '@noble/curves@1.9.1': - dependencies: - '@noble/hashes': 1.8.0 + baseline-browser-mapping@2.9.10: {} - '@noble/curves@1.9.7': - dependencies: - '@noble/hashes': 1.8.0 + batch@0.6.1: {} - '@noble/hashes@1.2.0': {} + bech32@1.1.4: {} - '@noble/hashes@1.3.2': {} + big.js@5.2.2: {} - '@noble/hashes@1.4.0': {} + big.js@6.2.2: {} - '@noble/hashes@1.7.0': {} + bignumber.js@9.3.1: {} - '@noble/hashes@1.7.1': {} + binary-extensions@2.3.0: {} - '@noble/hashes@1.7.2': {} + blakejs@1.2.1: {} - '@noble/hashes@1.8.0': {} + bn.js@4.11.6: {} - '@noble/secp256k1@1.7.1': {} + bn.js@4.12.2: {} - '@noble/secp256k1@2.3.0': {} + bn.js@5.2.2: {} - '@nodelib/fs.scandir@2.1.5': + body-parser@1.20.4: dependencies: - '@nodelib/fs.stat': 2.0.5 - run-parallel: 1.2.0 - - '@nodelib/fs.stat@2.0.5': {} + bytes: 3.1.2 + content-type: 1.0.5 + debug: 2.6.9 + depd: 2.0.0 + destroy: 1.2.0 + http-errors: 2.0.1 + iconv-lite: 0.4.24 + on-finished: 2.4.1 + qs: 6.14.0 + raw-body: 2.5.3 + type-is: 1.6.18 + unpipe: 1.0.0 + transitivePeerDependencies: + - supports-color - '@nodelib/fs.walk@1.2.8': + bonjour-service@1.3.0: dependencies: - '@nodelib/fs.scandir': 2.1.5 - fastq: 1.19.1 - - '@nomicfoundation/edr-darwin-arm64@0.12.0-next.17': {} + fast-deep-equal: 3.1.3 + multicast-dns: 7.2.5 - '@nomicfoundation/edr-darwin-x64@0.12.0-next.17': {} + boolbase@1.0.0: {} - '@nomicfoundation/edr-linux-arm64-gnu@0.12.0-next.17': {} + borsh@0.7.0: + dependencies: + bn.js: 5.2.2 + bs58: 4.0.1 + text-encoding-utf-8: 1.0.2 - '@nomicfoundation/edr-linux-arm64-musl@0.12.0-next.17': {} + bowser@2.13.1: {} - '@nomicfoundation/edr-linux-x64-gnu@0.12.0-next.17': {} + boxen@5.1.2: + dependencies: + ansi-align: 3.0.1 + camelcase: 6.3.0 + chalk: 4.1.2 + cli-boxes: 2.2.1 + string-width: 4.2.3 + type-fest: 0.20.2 + widest-line: 3.1.0 + wrap-ansi: 7.0.0 - '@nomicfoundation/edr-linux-x64-musl@0.12.0-next.17': {} + boxen@6.2.1: + dependencies: + ansi-align: 3.0.1 + camelcase: 6.3.0 + chalk: 4.1.2 + cli-boxes: 3.0.0 + string-width: 5.1.2 + type-fest: 2.19.0 + widest-line: 4.0.1 + wrap-ansi: 8.1.0 - '@nomicfoundation/edr-win32-x64-msvc@0.12.0-next.17': {} + boxen@7.1.1: + dependencies: + ansi-align: 3.0.1 + camelcase: 7.0.1 + chalk: 5.6.2 + cli-boxes: 3.0.0 + string-width: 5.1.2 + type-fest: 2.19.0 + widest-line: 4.0.1 + wrap-ansi: 8.1.0 - '@nomicfoundation/edr@0.12.0-next.17': + brace-expansion@1.1.12: dependencies: - '@nomicfoundation/edr-darwin-arm64': 0.12.0-next.17 - '@nomicfoundation/edr-darwin-x64': 0.12.0-next.17 - '@nomicfoundation/edr-linux-arm64-gnu': 0.12.0-next.17 - '@nomicfoundation/edr-linux-arm64-musl': 0.12.0-next.17 - '@nomicfoundation/edr-linux-x64-gnu': 0.12.0-next.17 - '@nomicfoundation/edr-linux-x64-musl': 0.12.0-next.17 - '@nomicfoundation/edr-win32-x64-msvc': 0.12.0-next.17 + balanced-match: 1.0.2 + concat-map: 0.0.1 - '@nomicfoundation/hardhat-chai-matchers@2.1.0(@nomicfoundation/hardhat-ethers@3.1.3(ethers@6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10)))(chai@4.5.0)(ethers@6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10))': + brace-expansion@2.0.2: dependencies: - '@nomicfoundation/hardhat-ethers': 3.1.3(ethers@6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10)) - '@types/chai-as-promised': 7.1.8 - chai: 4.5.0 - chai-as-promised: 7.1.2(chai@4.5.0) - deep-eql: 4.1.4 - ethers: 6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) - hardhat: 2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10) - ordinal: 1.0.3 + balanced-match: 1.0.2 - '@nomicfoundation/hardhat-ethers@3.1.3(ethers@6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10))': + braces@3.0.3: dependencies: - debug: 4.4.3(supports-color@8.1.1) - ethers: 6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) - hardhat: 2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10) - lodash.isequal: 4.5.0 - transitivePeerDependencies: - - supports-color + fill-range: 7.1.1 + + brorand@1.1.0: {} + + browser-stdout@1.3.1: {} - '@nomicfoundation/hardhat-ignition-ethers@0.15.17(@nomicfoundation/hardhat-ethers@3.1.3(ethers@6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10)))(@nomicfoundation/hardhat-ignition@0.15.16(@nomicfoundation/hardhat-verify@2.1.3(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10))(@nomicfoundation/ignition-core@0.15.15(bufferutil@4.0.9)(utf-8-validate@5.0.10))(ethers@6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10))': + browserify-aes@1.2.0: dependencies: - '@nomicfoundation/hardhat-ethers': 3.1.3(ethers@6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10)) - '@nomicfoundation/hardhat-ignition': 0.15.16(@nomicfoundation/hardhat-verify@2.1.3(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) - '@nomicfoundation/ignition-core': 0.15.15(bufferutil@4.0.9)(utf-8-validate@5.0.10) - ethers: 6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) - hardhat: 2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10) + buffer-xor: 1.0.3 + cipher-base: 1.0.7 + create-hash: 1.2.0 + evp_bytestokey: 1.0.3 + inherits: 2.0.4 + safe-buffer: 5.2.1 - '@nomicfoundation/hardhat-ignition@0.15.16(@nomicfoundation/hardhat-verify@2.1.3(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10)': + browserslist@4.28.1: dependencies: - '@nomicfoundation/hardhat-verify': 2.1.3(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10)) - '@nomicfoundation/ignition-core': 0.15.15(bufferutil@4.0.9)(utf-8-validate@5.0.10) - '@nomicfoundation/ignition-ui': 0.15.13 - chalk: 4.1.2 - debug: 4.4.3(supports-color@8.1.1) - fs-extra: 10.1.0 - hardhat: 2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10) - json5: 2.2.3 - prompts: 2.4.2 - transitivePeerDependencies: - - bufferutil - - supports-color - - utf-8-validate + baseline-browser-mapping: 2.9.10 + caniuse-lite: 1.0.30001760 + electron-to-chromium: 1.5.267 + node-releases: 2.0.27 + update-browserslist-db: 1.2.3(browserslist@4.28.1) + + bs58@4.0.1: + dependencies: + base-x: 3.0.11 - '@nomicfoundation/hardhat-network-helpers@1.1.2(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10))': + bs58@6.0.0: dependencies: - ethereumjs-util: 7.1.5 - hardhat: 2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10) + base-x: 5.0.1 - '@nomicfoundation/hardhat-toolbox@5.0.0(718d8c1f3463e528ebfebd4ac5f4e994)': + bs58check@2.1.2: dependencies: - '@nomicfoundation/hardhat-chai-matchers': 2.1.0(@nomicfoundation/hardhat-ethers@3.1.3(ethers@6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10)))(chai@4.5.0)(ethers@6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10)) - '@nomicfoundation/hardhat-ethers': 3.1.3(ethers@6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10)) - '@nomicfoundation/hardhat-ignition-ethers': 0.15.17(@nomicfoundation/hardhat-ethers@3.1.3(ethers@6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10)))(@nomicfoundation/hardhat-ignition@0.15.16(@nomicfoundation/hardhat-verify@2.1.3(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10))(@nomicfoundation/ignition-core@0.15.15(bufferutil@4.0.9)(utf-8-validate@5.0.10))(ethers@6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10)) - '@nomicfoundation/hardhat-network-helpers': 1.1.2(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10)) - '@nomicfoundation/hardhat-verify': 2.1.3(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10)) - '@typechain/ethers-v6': 0.5.1(ethers@6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(typechain@8.3.2(typescript@5.9.3))(typescript@5.9.3) - '@typechain/hardhat': 9.1.0(@typechain/ethers-v6@0.5.1(ethers@6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(typechain@8.3.2(typescript@5.9.3))(typescript@5.9.3))(ethers@6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10))(typechain@8.3.2(typescript@5.9.3)) - '@types/chai': 4.3.20 - '@types/mocha': 10.0.10 - '@types/node': 22.7.5 - chai: 4.5.0 - ethers: 6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) - hardhat: 2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10) - hardhat-gas-reporter: 1.0.10(bufferutil@4.0.9)(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) - solidity-coverage: 0.8.17(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10)) - ts-node: 10.9.2(@types/node@22.7.5)(typescript@5.9.3) - typechain: 8.3.2(typescript@5.9.3) - typescript: 5.9.3 + bs58: 4.0.1 + create-hash: 1.2.0 + safe-buffer: 5.2.1 + + buffer-from@1.1.2: {} + + buffer-xor@1.0.3: {} - '@nomicfoundation/hardhat-verify@2.1.3(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10))': + buffer@4.9.2: dependencies: - '@ethersproject/abi': 5.8.0 - '@ethersproject/address': 5.8.0 - cbor: 8.1.0 - debug: 4.4.3(supports-color@8.1.1) - hardhat: 2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10) - lodash.clonedeep: 4.5.0 - picocolors: 1.1.1 - semver: 6.3.1 - table: 6.9.0 - undici: 5.29.0 - transitivePeerDependencies: - - supports-color + base64-js: 1.5.1 + ieee754: 1.2.1 + isarray: 1.0.0 - '@nomicfoundation/ignition-core@0.15.15(bufferutil@4.0.9)(utf-8-validate@5.0.10)': + buffer@6.0.3: dependencies: - '@ethersproject/address': 5.6.1 - '@nomicfoundation/solidity-analyzer': 0.1.2 - cbor: 9.0.2 - debug: 4.4.3(supports-color@8.1.1) - ethers: 6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) - fs-extra: 10.1.0 - immer: 10.0.2 - lodash: 4.17.21 - ndjson: 2.0.0 - transitivePeerDependencies: - - bufferutil - - supports-color - - utf-8-validate + base64-js: 1.5.1 + ieee754: 1.2.1 - '@nomicfoundation/ignition-ui@0.15.13': {} + bufferutil@4.0.9: + dependencies: + node-gyp-build: 4.8.4 - '@nomicfoundation/slang@0.18.3': + bundle-name@4.1.0: dependencies: - '@bytecodealliance/preview2-shim': 0.17.0 + run-applescript: 7.1.0 - '@nomicfoundation/solidity-analyzer-darwin-arm64@0.1.2': - optional: true + bytes@3.0.0: {} - '@nomicfoundation/solidity-analyzer-darwin-x64@0.1.2': - optional: true + bytes@3.1.2: {} - '@nomicfoundation/solidity-analyzer-linux-arm64-gnu@0.1.2': - optional: true + bytestreamjs@2.0.1: {} - '@nomicfoundation/solidity-analyzer-linux-arm64-musl@0.1.2': - optional: true + cac@6.7.14: {} - '@nomicfoundation/solidity-analyzer-linux-x64-gnu@0.1.2': - optional: true + cacheable-lookup@7.0.0: {} - '@nomicfoundation/solidity-analyzer-linux-x64-musl@0.1.2': - optional: true + cacheable-request@10.2.14: + dependencies: + '@types/http-cache-semantics': 4.0.4 + get-stream: 6.0.1 + http-cache-semantics: 4.2.0 + keyv: 4.5.4 + mimic-response: 4.0.0 + normalize-url: 8.1.1 + responselike: 3.0.0 - '@nomicfoundation/solidity-analyzer-win32-x64-msvc@0.1.2': - optional: true + call-bind-apply-helpers@1.0.2: + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 - '@nomicfoundation/solidity-analyzer@0.1.2': - optionalDependencies: - '@nomicfoundation/solidity-analyzer-darwin-arm64': 0.1.2 - '@nomicfoundation/solidity-analyzer-darwin-x64': 0.1.2 - '@nomicfoundation/solidity-analyzer-linux-arm64-gnu': 0.1.2 - '@nomicfoundation/solidity-analyzer-linux-arm64-musl': 0.1.2 - '@nomicfoundation/solidity-analyzer-linux-x64-gnu': 0.1.2 - '@nomicfoundation/solidity-analyzer-linux-x64-musl': 0.1.2 - '@nomicfoundation/solidity-analyzer-win32-x64-msvc': 0.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 - '@openzeppelin/community-contracts@https://codeload.github.com/OpenZeppelin/openzeppelin-community-contracts/tar.gz/7322fa7de0beabe0e0cf7e8663f879d406bb3f42': {} + callsites@3.1.0: {} - '@openzeppelin/contracts-upgradeable@5.4.0(@openzeppelin/contracts@5.4.0)': + camel-case@4.1.2: dependencies: - '@openzeppelin/contracts': 5.4.0 + pascal-case: 3.1.2 + tslib: 2.8.1 - '@openzeppelin/contracts@3.4.2-solc-0.7': {} + camelcase-css@2.0.1: {} - '@openzeppelin/contracts@5.4.0': {} + camelcase@5.3.1: {} - '@openzeppelin/defender-sdk-base-client@2.7.0': - dependencies: - '@aws-sdk/client-lambda': 3.954.0 - amazon-cognito-identity-js: 6.3.16 - async-retry: 1.3.3 - transitivePeerDependencies: - - aws-crt - - encoding + camelcase@6.3.0: {} - '@openzeppelin/defender-sdk-deploy-client@2.7.0(debug@4.4.3)': - dependencies: - '@openzeppelin/defender-sdk-base-client': 2.7.0 - axios: 1.13.2(debug@4.4.3) - lodash: 4.17.21 - transitivePeerDependencies: - - aws-crt - - debug - - encoding + camelcase@7.0.1: {} - '@openzeppelin/defender-sdk-network-client@2.7.0(debug@4.4.3)': + caniuse-api@3.0.0: dependencies: - '@openzeppelin/defender-sdk-base-client': 2.7.0 - axios: 1.13.2(debug@4.4.3) - lodash: 4.17.21 - transitivePeerDependencies: - - aws-crt - - debug - - encoding + browserslist: 4.28.1 + caniuse-lite: 1.0.30001760 + lodash.memoize: 4.1.2 + lodash.uniq: 4.5.0 - '@openzeppelin/hardhat-upgrades@3.9.1(@nomicfoundation/hardhat-ethers@3.1.3(ethers@6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10)))(@nomicfoundation/hardhat-verify@2.1.3(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10)))(ethers@6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10))': - dependencies: - '@nomicfoundation/hardhat-ethers': 3.1.3(ethers@6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10)) - '@openzeppelin/defender-sdk-base-client': 2.7.0 - '@openzeppelin/defender-sdk-deploy-client': 2.7.0(debug@4.4.3) - '@openzeppelin/defender-sdk-network-client': 2.7.0(debug@4.4.3) - '@openzeppelin/upgrades-core': 1.44.2 - chalk: 4.1.2 - debug: 4.4.3(supports-color@8.1.1) - ethereumjs-util: 7.1.5 - ethers: 6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) - hardhat: 2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10) - proper-lockfile: 4.1.2 - undici: 6.22.0 - optionalDependencies: - '@nomicfoundation/hardhat-verify': 2.1.3(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10)) - transitivePeerDependencies: - - aws-crt - - encoding - - supports-color + caniuse-lite@1.0.30001760: {} - '@openzeppelin/upgrades-core@1.44.2': + caseless@0.12.0: {} + + cbor@10.0.11: dependencies: - '@nomicfoundation/slang': 0.18.3 - bignumber.js: 9.3.1 - cbor: 10.0.11 - chalk: 4.1.2 - compare-versions: 6.1.1 - debug: 4.4.3(supports-color@8.1.1) - ethereumjs-util: 7.1.5 - minimatch: 9.0.5 - minimist: 1.2.8 - proper-lockfile: 4.1.2 - solidity-ast: 0.4.61 - transitivePeerDependencies: - - supports-color + nofilter: 3.1.0 - '@paulmillr/qr@0.2.1': {} + cbor@8.1.0: + dependencies: + nofilter: 3.1.0 - '@peculiar/asn1-schema@2.6.0': + cbor@9.0.2: dependencies: - asn1js: 3.0.7 - pvtsutils: 1.3.6 - tslib: 2.8.1 - optional: true + nofilter: 3.1.0 + + ccount@2.0.1: {} - '@rainbow-me/rainbowkit@2.2.10(@tanstack/react-query@5.90.12(react@18.3.1))(@types/react@18.3.27)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3)(viem@2.43.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1))(wagmi@2.19.5(@tanstack/query-core@5.90.12)(@tanstack/react-query@5.90.12(react@18.3.1))(@types/react@18.3.27)(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(immer@10.0.2)(react@18.3.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.43.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1))(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@4.2.1))': + chai-as-promised@7.1.2(chai@4.5.0): dependencies: - '@tanstack/react-query': 5.90.12(react@18.3.1) - '@vanilla-extract/css': 1.17.3 - '@vanilla-extract/dynamic': 2.1.4 - '@vanilla-extract/sprinkles': 1.6.4(@vanilla-extract/css@1.17.3) - clsx: 2.1.1 - cuer: 0.0.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - react-remove-scroll: 2.6.2(@types/react@18.3.27)(react@18.3.1) - ua-parser-js: 1.0.41 - viem: 2.43.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) - wagmi: 2.19.5(@tanstack/query-core@5.90.12)(@tanstack/react-query@5.90.12(react@18.3.1))(@types/react@18.3.27)(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(immer@10.0.2)(react@18.3.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.43.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1))(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@4.2.1) - transitivePeerDependencies: - - '@types/react' - - babel-plugin-macros - - typescript + chai: 4.5.0 + check-error: 1.0.3 - '@reown/appkit-common@1.7.8(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.22.4)': + chai@4.5.0: dependencies: - big.js: 6.2.2 - dayjs: 1.11.13 - viem: 2.43.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.22.4) - transitivePeerDependencies: - - bufferutil - - typescript - - utf-8-validate - - zod + assertion-error: 1.1.0 + check-error: 1.0.3 + deep-eql: 4.1.4 + get-func-name: 2.0.2 + loupe: 2.3.7 + pathval: 1.1.1 + type-detect: 4.1.0 - '@reown/appkit-common@1.7.8(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1)': + chai@5.3.3: dependencies: - big.js: 6.2.2 - dayjs: 1.11.13 - viem: 2.43.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) - transitivePeerDependencies: - - bufferutil - - typescript - - utf-8-validate - - zod + assertion-error: 2.0.1 + check-error: 2.1.1 + deep-eql: 5.0.2 + loupe: 3.2.1 + pathval: 2.0.1 - '@reown/appkit-controllers@1.7.8(@types/react@18.3.27)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1)': + chalk@2.4.2: dependencies: - '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) - '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10) - '@walletconnect/universal-provider': 2.21.0(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) - valtio: 1.13.2(@types/react@18.3.27)(react@18.3.1) - viem: 2.43.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.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 + ansi-styles: 3.2.1 + escape-string-regexp: 1.0.5 + supports-color: 5.5.0 - '@reown/appkit-pay@1.7.8(@types/react@18.3.27)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1)': + chalk@4.1.2: dependencies: - '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) - '@reown/appkit-controllers': 1.7.8(@types/react@18.3.27)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) - '@reown/appkit-ui': 1.7.8(@types/react@18.3.27)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) - '@reown/appkit-utils': 1.7.8(@types/react@18.3.27)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@18.3.27)(react@18.3.1))(zod@4.2.1) - lit: 3.3.0 - valtio: 1.13.2(@types/react@18.3.27)(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 + ansi-styles: 4.3.0 + supports-color: 7.2.0 - '@reown/appkit-polyfills@1.7.8': + chalk@5.6.2: {} + + char-regex@1.0.2: {} + + character-entities-html4@2.1.0: {} + + character-entities-legacy@3.0.0: {} + + character-entities@2.0.2: {} + + character-reference-invalid@2.0.1: {} + + charenc@0.0.2: {} + + check-error@1.0.3: dependencies: - buffer: 6.0.3 + get-func-name: 2.0.2 + + check-error@2.1.1: {} - '@reown/appkit-scaffold-ui@1.7.8(@types/react@18.3.27)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@18.3.27)(react@18.3.1))(zod@4.2.1)': + cheerio-select@2.1.0: dependencies: - '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) - '@reown/appkit-controllers': 1.7.8(@types/react@18.3.27)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) - '@reown/appkit-ui': 1.7.8(@types/react@18.3.27)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) - '@reown/appkit-utils': 1.7.8(@types/react@18.3.27)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@18.3.27)(react@18.3.1))(zod@4.2.1) - '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10) - lit: 3.3.0 - transitivePeerDependencies: - - '@azure/app-configuration' - - '@azure/cosmos' - - '@azure/data-tables' - - '@azure/identity' - - '@azure/keyvault-secrets' - - '@azure/storage-blob' - - '@capacitor/preferences' - - '@deno/kv' - - '@netlify/blobs' - - '@planetscale/database' - - '@react-native-async-storage/async-storage' - - '@types/react' - - '@upstash/redis' - - '@vercel/blob' - - '@vercel/functions' - - '@vercel/kv' - - aws4fetch - - bufferutil - - db0 - - encoding - - ioredis - - react - - typescript - - uploadthing - - utf-8-validate - - valtio - - zod + boolbase: 1.0.0 + css-select: 5.2.2 + css-what: 6.2.2 + domelementtype: 2.3.0 + domhandler: 5.0.3 + domutils: 3.2.2 - '@reown/appkit-ui@1.7.8(@types/react@18.3.27)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1)': + cheerio@1.0.0-rc.12: dependencies: - '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) - '@reown/appkit-controllers': 1.7.8(@types/react@18.3.27)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) - '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10) - lit: 3.3.0 - qrcode: 1.5.3 - transitivePeerDependencies: - - '@azure/app-configuration' - - '@azure/cosmos' - - '@azure/data-tables' - - '@azure/identity' - - '@azure/keyvault-secrets' - - '@azure/storage-blob' - - '@capacitor/preferences' - - '@deno/kv' - - '@netlify/blobs' - - '@planetscale/database' - - '@react-native-async-storage/async-storage' - - '@types/react' - - '@upstash/redis' - - '@vercel/blob' - - '@vercel/functions' - - '@vercel/kv' - - aws4fetch - - bufferutil - - db0 - - encoding - - ioredis - - react - - typescript - - uploadthing - - utf-8-validate - - zod + cheerio-select: 2.1.0 + dom-serializer: 2.0.0 + domhandler: 5.0.3 + domutils: 3.2.2 + htmlparser2: 8.0.2 + parse5: 7.3.0 + parse5-htmlparser2-tree-adapter: 7.1.0 - '@reown/appkit-utils@1.7.8(@types/react@18.3.27)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@18.3.27)(react@18.3.1))(zod@4.2.1)': + chokidar@3.6.0: dependencies: - '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) - '@reown/appkit-controllers': 1.7.8(@types/react@18.3.27)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) - '@reown/appkit-polyfills': 1.7.8 - '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10) - '@walletconnect/logger': 2.1.2 - '@walletconnect/universal-provider': 2.21.0(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) - valtio: 1.13.2(@types/react@18.3.27)(react@18.3.1) - viem: 2.43.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.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 + anymatch: 3.1.3 + braces: 3.0.3 + glob-parent: 5.1.2 + is-binary-path: 2.1.0 + is-glob: 4.0.3 + normalize-path: 3.0.0 + readdirp: 3.6.0 + optionalDependencies: + fsevents: 2.3.3 - '@reown/appkit-wallet@1.7.8(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)': + chokidar@4.0.3: dependencies: - '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.22.4) - '@reown/appkit-polyfills': 1.7.8 - '@walletconnect/logger': 2.1.2 - zod: 3.22.4 - transitivePeerDependencies: - - bufferutil - - typescript - - utf-8-validate + readdirp: 4.1.2 + + chrome-trace-event@1.0.4: {} - '@reown/appkit@1.7.8(@types/react@18.3.27)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1)': + ci-info@2.0.0: {} + + ci-info@3.9.0: {} + + cipher-base@1.0.7: dependencies: - '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) - '@reown/appkit-controllers': 1.7.8(@types/react@18.3.27)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) - '@reown/appkit-pay': 1.7.8(@types/react@18.3.27)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) - '@reown/appkit-polyfills': 1.7.8 - '@reown/appkit-scaffold-ui': 1.7.8(@types/react@18.3.27)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@18.3.27)(react@18.3.1))(zod@4.2.1) - '@reown/appkit-ui': 1.7.8(@types/react@18.3.27)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) - '@reown/appkit-utils': 1.7.8(@types/react@18.3.27)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@18.3.27)(react@18.3.1))(zod@4.2.1) - '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10) - '@walletconnect/types': 2.21.0 - '@walletconnect/universal-provider': 2.21.0(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) - bs58: 6.0.0 - valtio: 1.13.2(@types/react@18.3.27)(react@18.3.1) - viem: 2.43.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.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 + inherits: 2.0.4 + safe-buffer: 5.2.1 + to-buffer: 1.2.2 - '@rolldown/pluginutils@1.0.0-beta.27': {} + clean-css@5.3.3: + dependencies: + source-map: 0.6.1 - '@rollup/rollup-android-arm-eabi@4.53.5': - optional: true + clean-stack@2.2.0: {} - '@rollup/rollup-android-arm64@4.53.5': - optional: true + cli-boxes@2.2.1: {} - '@rollup/rollup-darwin-arm64@4.53.5': - optional: true + cli-boxes@3.0.0: {} - '@rollup/rollup-darwin-x64@4.53.5': - optional: true + cli-table3@0.5.1: + dependencies: + object-assign: 4.1.1 + string-width: 2.1.1 + optionalDependencies: + colors: 1.4.0 - '@rollup/rollup-freebsd-arm64@4.53.5': - optional: true + cli-table3@0.6.5: + dependencies: + string-width: 4.2.3 + optionalDependencies: + '@colors/colors': 1.5.0 - '@rollup/rollup-freebsd-x64@4.53.5': - optional: true + cliui@6.0.0: + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 6.2.0 - '@rollup/rollup-linux-arm-gnueabihf@4.53.5': - optional: true + cliui@7.0.4: + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 - '@rollup/rollup-linux-arm-musleabihf@4.53.5': - optional: true + clone-deep@4.0.1: + dependencies: + is-plain-object: 2.0.4 + kind-of: 6.0.3 + shallow-clone: 3.0.1 - '@rollup/rollup-linux-arm64-gnu@4.53.5': - optional: true + clsx@1.2.1: {} - '@rollup/rollup-linux-arm64-musl@4.53.5': - optional: true + clsx@2.1.1: {} - '@rollup/rollup-linux-loong64-gnu@4.53.5': - optional: true + collapse-white-space@2.1.0: {} - '@rollup/rollup-linux-ppc64-gnu@4.53.5': - optional: true + color-convert@1.9.3: + dependencies: + color-name: 1.1.3 - '@rollup/rollup-linux-riscv64-gnu@4.53.5': - optional: true + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 - '@rollup/rollup-linux-riscv64-musl@4.53.5': - optional: true + color-name@1.1.3: {} - '@rollup/rollup-linux-s390x-gnu@4.53.5': - optional: true + color-name@1.1.4: {} - '@rollup/rollup-linux-x64-gnu@4.53.5': - optional: true + colord@2.9.3: {} - '@rollup/rollup-linux-x64-musl@4.53.5': - optional: true + colorette@2.0.20: {} - '@rollup/rollup-openharmony-arm64@4.53.5': - optional: true + colors@1.4.0: {} - '@rollup/rollup-win32-arm64-msvc@4.53.5': - optional: true + combine-promises@1.2.0: {} - '@rollup/rollup-win32-ia32-msvc@4.53.5': - optional: true + combined-stream@1.0.8: + dependencies: + delayed-stream: 1.0.0 - '@rollup/rollup-win32-x64-gnu@4.53.5': - optional: true + comma-separated-tokens@2.0.3: {} - '@rollup/rollup-win32-x64-msvc@4.53.5': - optional: true + command-exists@1.2.9: {} - '@safe-global/api-kit@4.0.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1)': + command-line-args@5.2.1: dependencies: - '@safe-global/protocol-kit': 6.1.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) - '@safe-global/types-kit': 3.0.0(typescript@5.9.3)(zod@4.2.1) - node-fetch: 2.7.0 - viem: 2.43.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) - transitivePeerDependencies: - - bufferutil - - encoding - - typescript - - utf-8-validate - - zod + array-back: 3.1.0 + find-replace: 3.0.0 + lodash.camelcase: 4.3.0 + typical: 4.0.0 - '@safe-global/protocol-kit@6.1.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1)': + command-line-usage@6.1.3: dependencies: - '@safe-global/safe-deployments': 1.37.49 - '@safe-global/safe-modules-deployments': 2.2.21 - '@safe-global/types-kit': 3.0.0(typescript@5.9.3)(zod@4.2.1) - abitype: 1.2.3(typescript@5.9.3)(zod@4.2.1) - semver: 7.7.3 - viem: 2.43.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) - optionalDependencies: - '@noble/curves': 1.9.7 - '@peculiar/asn1-schema': 2.6.0 - transitivePeerDependencies: - - bufferutil - - typescript - - utf-8-validate - - zod + array-back: 4.0.2 + chalk: 2.4.2 + table-layout: 1.0.2 + typical: 5.2.0 - '@safe-global/safe-apps-provider@0.18.6(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1)': - dependencies: - '@safe-global/safe-apps-sdk': 9.1.0(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) - events: 3.3.0 - transitivePeerDependencies: - - bufferutil - - typescript - - utf-8-validate - - zod + commander@10.0.1: {} - '@safe-global/safe-apps-sdk@9.1.0(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1)': - dependencies: - '@safe-global/safe-gateway-typescript-sdk': 3.23.1 - viem: 2.43.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) - transitivePeerDependencies: - - bufferutil - - typescript - - utf-8-validate - - zod + commander@14.0.0: {} - '@safe-global/safe-deployments@1.37.49': - dependencies: - semver: 7.7.3 + commander@14.0.2: {} - '@safe-global/safe-gateway-typescript-sdk@3.23.1': {} + commander@2.20.3: {} - '@safe-global/safe-modules-deployments@2.2.21': {} + commander@4.1.1: {} - '@safe-global/types-kit@3.0.0(typescript@5.9.3)(zod@4.2.1)': - dependencies: - abitype: 1.2.3(typescript@5.9.3)(zod@4.2.1) - transitivePeerDependencies: - - typescript - - zod + commander@5.1.0: {} - '@scure/base@1.1.9': {} + commander@7.2.0: {} - '@scure/base@1.2.6': {} + commander@8.3.0: {} - '@scure/bip32@1.1.5': - dependencies: - '@noble/hashes': 1.2.0 - '@noble/secp256k1': 1.7.1 - '@scure/base': 1.1.9 + common-path-prefix@3.0.0: {} - '@scure/bip32@1.4.0': - dependencies: - '@noble/curves': 1.4.2 - '@noble/hashes': 1.4.0 - '@scure/base': 1.1.9 + compare-versions@6.1.1: {} - '@scure/bip32@1.6.2': + compressible@2.0.18: dependencies: - '@noble/curves': 1.8.1 - '@noble/hashes': 1.7.1 - '@scure/base': 1.2.6 + mime-db: 1.52.0 - '@scure/bip32@1.7.0': + compression@1.8.1: dependencies: - '@noble/curves': 1.9.1 - '@noble/hashes': 1.8.0 - '@scure/base': 1.2.6 + bytes: 3.1.2 + compressible: 2.0.18 + debug: 2.6.9 + negotiator: 0.6.4 + on-headers: 1.1.0 + safe-buffer: 5.2.1 + vary: 1.1.2 + transitivePeerDependencies: + - supports-color - '@scure/bip39@1.1.1': - dependencies: - '@noble/hashes': 1.2.0 - '@scure/base': 1.1.9 + concat-map@0.0.1: {} - '@scure/bip39@1.3.0': + concat-stream@1.6.2: dependencies: - '@noble/hashes': 1.4.0 - '@scure/base': 1.1.9 + buffer-from: 1.1.2 + inherits: 2.0.4 + readable-stream: 2.3.8 + typedarray: 0.0.6 - '@scure/bip39@1.5.4': + config-chain@1.1.13: dependencies: - '@noble/hashes': 1.7.1 - '@scure/base': 1.2.6 + ini: 1.3.8 + proto-list: 1.2.4 - '@scure/bip39@1.6.0': + configstore@6.0.0: dependencies: - '@noble/hashes': 1.8.0 - '@scure/base': 1.2.6 + dot-prop: 6.0.1 + graceful-fs: 4.2.11 + unique-string: 3.0.0 + write-file-atomic: 3.0.3 + xdg-basedir: 5.1.0 - '@sentry/core@5.30.0': - dependencies: - '@sentry/hub': 5.30.0 - '@sentry/minimal': 5.30.0 - '@sentry/types': 5.30.0 - '@sentry/utils': 5.30.0 - tslib: 1.14.1 + connect-history-api-fallback@2.0.0: {} - '@sentry/hub@5.30.0': - dependencies: - '@sentry/types': 5.30.0 - '@sentry/utils': 5.30.0 - tslib: 1.14.1 + consola@3.4.2: {} - '@sentry/minimal@5.30.0': - dependencies: - '@sentry/hub': 5.30.0 - '@sentry/types': 5.30.0 - tslib: 1.14.1 + content-disposition@0.5.2: {} - '@sentry/node@5.30.0': + content-disposition@0.5.4: dependencies: - '@sentry/core': 5.30.0 - '@sentry/hub': 5.30.0 - '@sentry/tracing': 5.30.0 - '@sentry/types': 5.30.0 - '@sentry/utils': 5.30.0 - cookie: 0.4.2 - https-proxy-agent: 5.0.1 - lru_map: 0.3.3 - tslib: 1.14.1 - transitivePeerDependencies: - - supports-color + safe-buffer: 5.2.1 - '@sentry/tracing@5.30.0': - dependencies: - '@sentry/hub': 5.30.0 - '@sentry/minimal': 5.30.0 - '@sentry/types': 5.30.0 - '@sentry/utils': 5.30.0 - tslib: 1.14.1 + content-type@1.0.5: {} - '@sentry/types@5.30.0': {} + convert-source-map@2.0.0: {} - '@sentry/utils@5.30.0': - dependencies: - '@sentry/types': 5.30.0 - tslib: 1.14.1 + cookie-es@1.2.2: {} - '@smithy/abort-controller@4.2.6': - dependencies: - '@smithy/types': 4.10.0 - tslib: 2.8.1 + cookie-signature@1.0.7: {} - '@smithy/config-resolver@4.4.4': - dependencies: - '@smithy/node-config-provider': 4.3.6 - '@smithy/types': 4.10.0 - '@smithy/util-config-provider': 4.2.0 - '@smithy/util-endpoints': 3.2.6 - '@smithy/util-middleware': 4.2.6 - tslib: 2.8.1 + cookie@0.4.2: {} - '@smithy/core@3.19.0': - dependencies: - '@smithy/middleware-serde': 4.2.7 - '@smithy/protocol-http': 5.3.6 - '@smithy/types': 4.10.0 - '@smithy/util-base64': 4.3.0 - '@smithy/util-body-length-browser': 4.2.0 - '@smithy/util-middleware': 4.2.6 - '@smithy/util-stream': 4.5.7 - '@smithy/util-utf8': 4.2.0 - '@smithy/uuid': 1.1.0 - tslib: 2.8.1 + cookie@0.7.2: {} - '@smithy/credential-provider-imds@4.2.6': + copy-webpack-plugin@11.0.0(webpack@5.104.1): dependencies: - '@smithy/node-config-provider': 4.3.6 - '@smithy/property-provider': 4.2.6 - '@smithy/types': 4.10.0 - '@smithy/url-parser': 4.2.6 - tslib: 2.8.1 + fast-glob: 3.3.3 + glob-parent: 6.0.2 + globby: 13.2.2 + normalize-path: 3.0.0 + schema-utils: 4.3.3 + serialize-javascript: 6.0.2 + webpack: 5.104.1 - '@smithy/eventstream-codec@4.2.6': + core-js-compat@3.47.0: dependencies: - '@aws-crypto/crc32': 5.2.0 - '@smithy/types': 4.10.0 - '@smithy/util-hex-encoding': 4.2.0 - tslib: 2.8.1 + browserslist: 4.28.1 - '@smithy/eventstream-serde-browser@4.2.6': - dependencies: - '@smithy/eventstream-serde-universal': 4.2.6 - '@smithy/types': 4.10.0 - tslib: 2.8.1 + core-js-pure@3.47.0: {} - '@smithy/eventstream-serde-config-resolver@4.3.6': - dependencies: - '@smithy/types': 4.10.0 - tslib: 2.8.1 + core-js@3.47.0: {} - '@smithy/eventstream-serde-node@4.2.6': + core-util-is@1.0.3: {} + + cosmiconfig@8.3.6(typescript@5.6.3): dependencies: - '@smithy/eventstream-serde-universal': 4.2.6 - '@smithy/types': 4.10.0 - tslib: 2.8.1 + import-fresh: 3.3.1 + js-yaml: 4.1.1 + parse-json: 5.2.0 + path-type: 4.0.0 + optionalDependencies: + typescript: 5.6.3 - '@smithy/eventstream-serde-universal@4.2.6': + crc-32@1.2.2: {} + + create-hash@1.2.0: dependencies: - '@smithy/eventstream-codec': 4.2.6 - '@smithy/types': 4.10.0 - tslib: 2.8.1 + cipher-base: 1.0.7 + inherits: 2.0.4 + md5.js: 1.3.5 + ripemd160: 2.0.3 + sha.js: 2.4.12 - '@smithy/fetch-http-handler@5.3.7': + create-hmac@1.1.7: dependencies: - '@smithy/protocol-http': 5.3.6 - '@smithy/querystring-builder': 4.2.6 - '@smithy/types': 4.10.0 - '@smithy/util-base64': 4.3.0 - tslib: 2.8.1 + cipher-base: 1.0.7 + create-hash: 1.2.0 + inherits: 2.0.4 + ripemd160: 2.0.3 + safe-buffer: 5.2.1 + sha.js: 2.4.12 + + create-require@1.1.1: {} - '@smithy/hash-node@4.2.6': + cross-fetch@3.2.0: dependencies: - '@smithy/types': 4.10.0 - '@smithy/util-buffer-from': 4.2.0 - '@smithy/util-utf8': 4.2.0 - tslib: 2.8.1 + node-fetch: 2.7.0 + transitivePeerDependencies: + - encoding - '@smithy/invalid-dependency@4.2.6': + cross-fetch@4.1.0: dependencies: - '@smithy/types': 4.10.0 - tslib: 2.8.1 + node-fetch: 2.7.0 + transitivePeerDependencies: + - encoding - '@smithy/is-array-buffer@2.2.0': + cross-spawn@7.0.6: dependencies: - tslib: 2.8.1 + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 - '@smithy/is-array-buffer@4.2.0': + crossws@0.3.5: dependencies: - tslib: 2.8.1 + uncrypto: 0.1.3 - '@smithy/middleware-content-length@4.2.6': - dependencies: - '@smithy/protocol-http': 5.3.6 - '@smithy/types': 4.10.0 - tslib: 2.8.1 + crypt@0.0.2: {} - '@smithy/middleware-endpoint@4.4.0': + crypto-random-string@4.0.0: dependencies: - '@smithy/core': 3.19.0 - '@smithy/middleware-serde': 4.2.7 - '@smithy/node-config-provider': 4.3.6 - '@smithy/shared-ini-file-loader': 4.4.1 - '@smithy/types': 4.10.0 - '@smithy/url-parser': 4.2.6 - '@smithy/util-middleware': 4.2.6 - tslib: 2.8.1 + type-fest: 1.4.0 - '@smithy/middleware-retry@4.4.16': + css-blank-pseudo@7.0.1(postcss@8.5.6): dependencies: - '@smithy/node-config-provider': 4.3.6 - '@smithy/protocol-http': 5.3.6 - '@smithy/service-error-classification': 4.2.6 - '@smithy/smithy-client': 4.10.1 - '@smithy/types': 4.10.0 - '@smithy/util-middleware': 4.2.6 - '@smithy/util-retry': 4.2.6 - '@smithy/uuid': 1.1.0 - tslib: 2.8.1 + postcss: 8.5.6 + postcss-selector-parser: 7.1.1 - '@smithy/middleware-serde@4.2.7': + css-declaration-sorter@7.3.1(postcss@8.5.6): dependencies: - '@smithy/protocol-http': 5.3.6 - '@smithy/types': 4.10.0 - tslib: 2.8.1 + postcss: 8.5.6 - '@smithy/middleware-stack@4.2.6': + css-has-pseudo@7.0.3(postcss@8.5.6): dependencies: - '@smithy/types': 4.10.0 - tslib: 2.8.1 + '@csstools/selector-specificity': 5.0.0(postcss-selector-parser@7.1.1) + postcss: 8.5.6 + postcss-selector-parser: 7.1.1 + postcss-value-parser: 4.2.0 - '@smithy/node-config-provider@4.3.6': + css-loader@6.11.0(webpack@5.104.1): dependencies: - '@smithy/property-provider': 4.2.6 - '@smithy/shared-ini-file-loader': 4.4.1 - '@smithy/types': 4.10.0 - tslib: 2.8.1 + icss-utils: 5.1.0(postcss@8.5.6) + postcss: 8.5.6 + postcss-modules-extract-imports: 3.1.0(postcss@8.5.6) + postcss-modules-local-by-default: 4.2.0(postcss@8.5.6) + postcss-modules-scope: 3.2.1(postcss@8.5.6) + postcss-modules-values: 4.0.0(postcss@8.5.6) + postcss-value-parser: 4.2.0 + semver: 7.7.3 + optionalDependencies: + webpack: 5.104.1 - '@smithy/node-http-handler@4.4.6': + css-minimizer-webpack-plugin@5.0.1(clean-css@5.3.3)(webpack@5.104.1): dependencies: - '@smithy/abort-controller': 4.2.6 - '@smithy/protocol-http': 5.3.6 - '@smithy/querystring-builder': 4.2.6 - '@smithy/types': 4.10.0 - tslib: 2.8.1 + '@jridgewell/trace-mapping': 0.3.31 + cssnano: 6.1.2(postcss@8.5.6) + jest-worker: 29.7.0 + postcss: 8.5.6 + schema-utils: 4.3.3 + serialize-javascript: 6.0.2 + webpack: 5.104.1 + optionalDependencies: + clean-css: 5.3.3 - '@smithy/property-provider@4.2.6': + css-prefers-color-scheme@10.0.0(postcss@8.5.6): dependencies: - '@smithy/types': 4.10.0 - tslib: 2.8.1 + postcss: 8.5.6 - '@smithy/protocol-http@5.3.6': + css-select@4.3.0: dependencies: - '@smithy/types': 4.10.0 - tslib: 2.8.1 + boolbase: 1.0.0 + css-what: 6.2.2 + domhandler: 4.3.1 + domutils: 2.8.0 + nth-check: 2.1.1 - '@smithy/querystring-builder@4.2.6': + css-select@5.2.2: dependencies: - '@smithy/types': 4.10.0 - '@smithy/util-uri-escape': 4.2.0 - tslib: 2.8.1 + boolbase: 1.0.0 + css-what: 6.2.2 + domhandler: 5.0.3 + domutils: 3.2.2 + nth-check: 2.1.1 - '@smithy/querystring-parser@4.2.6': + css-tree@2.2.1: dependencies: - '@smithy/types': 4.10.0 - tslib: 2.8.1 + mdn-data: 2.0.28 + source-map-js: 1.2.1 - '@smithy/service-error-classification@4.2.6': + css-tree@2.3.1: dependencies: - '@smithy/types': 4.10.0 + mdn-data: 2.0.30 + source-map-js: 1.2.1 - '@smithy/shared-ini-file-loader@4.4.1': - dependencies: - '@smithy/types': 4.10.0 - tslib: 2.8.1 + css-what@6.2.2: {} - '@smithy/signature-v4@5.3.6': - dependencies: - '@smithy/is-array-buffer': 4.2.0 - '@smithy/protocol-http': 5.3.6 - '@smithy/types': 4.10.0 - '@smithy/util-hex-encoding': 4.2.0 - '@smithy/util-middleware': 4.2.6 - '@smithy/util-uri-escape': 4.2.0 - '@smithy/util-utf8': 4.2.0 - tslib: 2.8.1 + cssdb@8.7.0: {} - '@smithy/smithy-client@4.10.1': - dependencies: - '@smithy/core': 3.19.0 - '@smithy/middleware-endpoint': 4.4.0 - '@smithy/middleware-stack': 4.2.6 - '@smithy/protocol-http': 5.3.6 - '@smithy/types': 4.10.0 - '@smithy/util-stream': 4.5.7 - tslib: 2.8.1 + cssesc@3.0.0: {} - '@smithy/types@4.10.0': + cssnano-preset-advanced@6.1.2(postcss@8.5.6): dependencies: - tslib: 2.8.1 + autoprefixer: 10.4.23(postcss@8.5.6) + browserslist: 4.28.1 + cssnano-preset-default: 6.1.2(postcss@8.5.6) + postcss: 8.5.6 + postcss-discard-unused: 6.0.5(postcss@8.5.6) + postcss-merge-idents: 6.0.3(postcss@8.5.6) + postcss-reduce-idents: 6.0.3(postcss@8.5.6) + postcss-zindex: 6.0.2(postcss@8.5.6) - '@smithy/url-parser@4.2.6': + cssnano-preset-default@6.1.2(postcss@8.5.6): dependencies: - '@smithy/querystring-parser': 4.2.6 - '@smithy/types': 4.10.0 - tslib: 2.8.1 - - '@smithy/util-base64@4.3.0': + browserslist: 4.28.1 + css-declaration-sorter: 7.3.1(postcss@8.5.6) + cssnano-utils: 4.0.2(postcss@8.5.6) + postcss: 8.5.6 + postcss-calc: 9.0.1(postcss@8.5.6) + postcss-colormin: 6.1.0(postcss@8.5.6) + postcss-convert-values: 6.1.0(postcss@8.5.6) + postcss-discard-comments: 6.0.2(postcss@8.5.6) + postcss-discard-duplicates: 6.0.3(postcss@8.5.6) + postcss-discard-empty: 6.0.3(postcss@8.5.6) + postcss-discard-overridden: 6.0.2(postcss@8.5.6) + postcss-merge-longhand: 6.0.5(postcss@8.5.6) + postcss-merge-rules: 6.1.1(postcss@8.5.6) + postcss-minify-font-values: 6.1.0(postcss@8.5.6) + postcss-minify-gradients: 6.0.3(postcss@8.5.6) + postcss-minify-params: 6.1.0(postcss@8.5.6) + postcss-minify-selectors: 6.0.4(postcss@8.5.6) + postcss-normalize-charset: 6.0.2(postcss@8.5.6) + postcss-normalize-display-values: 6.0.2(postcss@8.5.6) + postcss-normalize-positions: 6.0.2(postcss@8.5.6) + postcss-normalize-repeat-style: 6.0.2(postcss@8.5.6) + postcss-normalize-string: 6.0.2(postcss@8.5.6) + postcss-normalize-timing-functions: 6.0.2(postcss@8.5.6) + postcss-normalize-unicode: 6.1.0(postcss@8.5.6) + postcss-normalize-url: 6.0.2(postcss@8.5.6) + postcss-normalize-whitespace: 6.0.2(postcss@8.5.6) + postcss-ordered-values: 6.0.2(postcss@8.5.6) + postcss-reduce-initial: 6.1.0(postcss@8.5.6) + postcss-reduce-transforms: 6.0.2(postcss@8.5.6) + postcss-svgo: 6.0.3(postcss@8.5.6) + postcss-unique-selectors: 6.0.4(postcss@8.5.6) + + cssnano-utils@4.0.2(postcss@8.5.6): dependencies: - '@smithy/util-buffer-from': 4.2.0 - '@smithy/util-utf8': 4.2.0 - tslib: 2.8.1 + postcss: 8.5.6 - '@smithy/util-body-length-browser@4.2.0': + cssnano@6.1.2(postcss@8.5.6): dependencies: - tslib: 2.8.1 + cssnano-preset-default: 6.1.2(postcss@8.5.6) + lilconfig: 3.1.3 + postcss: 8.5.6 - '@smithy/util-body-length-node@4.2.1': + csso@5.0.5: dependencies: - tslib: 2.8.1 + css-tree: 2.2.1 - '@smithy/util-buffer-from@2.2.0': - dependencies: - '@smithy/is-array-buffer': 2.2.0 - tslib: 2.8.1 + csstype@3.2.3: {} - '@smithy/util-buffer-from@4.2.0': + cuer@0.0.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3): dependencies: - '@smithy/is-array-buffer': 4.2.0 - tslib: 2.8.1 + qr: 0.5.3 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + typescript: 5.6.3 - '@smithy/util-config-provider@4.2.0': + date-fns@2.30.0: dependencies: - tslib: 2.8.1 + '@babel/runtime': 7.28.4 - '@smithy/util-defaults-mode-browser@4.3.15': - dependencies: - '@smithy/property-provider': 4.2.6 - '@smithy/smithy-client': 4.10.1 - '@smithy/types': 4.10.0 - tslib: 2.8.1 + dayjs@1.11.13: {} - '@smithy/util-defaults-mode-node@4.2.18': - dependencies: - '@smithy/config-resolver': 4.4.4 - '@smithy/credential-provider-imds': 4.2.6 - '@smithy/node-config-provider': 4.3.6 - '@smithy/property-provider': 4.2.6 - '@smithy/smithy-client': 4.10.1 - '@smithy/types': 4.10.0 - tslib: 2.8.1 + death@1.1.0: {} - '@smithy/util-endpoints@3.2.6': - dependencies: - '@smithy/node-config-provider': 4.3.6 - '@smithy/types': 4.10.0 - tslib: 2.8.1 + debounce@1.2.1: {} - '@smithy/util-hex-encoding@4.2.0': + debug@2.6.9: dependencies: - tslib: 2.8.1 + ms: 2.0.0 - '@smithy/util-middleware@4.2.6': + debug@4.3.4: dependencies: - '@smithy/types': 4.10.0 - tslib: 2.8.1 + ms: 2.1.2 - '@smithy/util-retry@4.2.6': + debug@4.4.3(supports-color@8.1.1): dependencies: - '@smithy/service-error-classification': 4.2.6 - '@smithy/types': 4.10.0 - tslib: 2.8.1 + ms: 2.1.3 + optionalDependencies: + supports-color: 8.1.1 - '@smithy/util-stream@4.5.7': - dependencies: - '@smithy/fetch-http-handler': 5.3.7 - '@smithy/node-http-handler': 4.4.6 - '@smithy/types': 4.10.0 - '@smithy/util-base64': 4.3.0 - '@smithy/util-buffer-from': 4.2.0 - '@smithy/util-hex-encoding': 4.2.0 - '@smithy/util-utf8': 4.2.0 - tslib: 2.8.1 + decamelize@1.2.0: {} - '@smithy/util-uri-escape@4.2.0': - dependencies: - tslib: 2.8.1 + decamelize@4.0.0: {} - '@smithy/util-utf8@2.3.0': + decode-named-character-reference@1.3.0: dependencies: - '@smithy/util-buffer-from': 2.2.0 - tslib: 2.8.1 + character-entities: 2.0.2 - '@smithy/util-utf8@4.2.0': - dependencies: - '@smithy/util-buffer-from': 4.2.0 - tslib: 2.8.1 + decode-uri-component@0.2.2: {} - '@smithy/util-waiter@4.2.6': + decompress-response@6.0.0: dependencies: - '@smithy/abort-controller': 4.2.6 - '@smithy/types': 4.10.0 - tslib: 2.8.1 + mimic-response: 3.1.0 - '@smithy/uuid@1.1.0': + dedent@1.7.1: {} + + deep-eql@4.1.4: dependencies: - tslib: 2.8.1 + type-detect: 4.1.0 - '@socket.io/component-emitter@3.1.2': {} + deep-eql@5.0.2: {} - '@solana-program/system@0.8.1(@solana/kit@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)))': - dependencies: - '@solana/kit': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + deep-extend@0.6.0: {} - '@solana-program/token@0.6.0(@solana/kit@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)))': - dependencies: - '@solana/kit': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + deep-is@0.1.4: {} - '@solana/accounts@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)': - dependencies: - '@solana/addresses': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) - '@solana/codecs-core': 3.0.3(typescript@5.9.3) - '@solana/codecs-strings': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) - '@solana/errors': 3.0.3(typescript@5.9.3) - '@solana/rpc-spec': 3.0.3(typescript@5.9.3) - '@solana/rpc-types': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) - typescript: 5.9.3 - transitivePeerDependencies: - - fastestsmallesttextencoderdecoder + deep-object-diff@1.1.9: {} - '@solana/addresses@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)': + deepmerge@4.3.1: {} + + default-browser-id@5.0.1: {} + + default-browser@5.4.0: dependencies: - '@solana/assertions': 3.0.3(typescript@5.9.3) - '@solana/codecs-core': 3.0.3(typescript@5.9.3) - '@solana/codecs-strings': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) - '@solana/errors': 3.0.3(typescript@5.9.3) - '@solana/nominal-types': 3.0.3(typescript@5.9.3) - typescript: 5.9.3 - transitivePeerDependencies: - - fastestsmallesttextencoderdecoder + bundle-name: 4.1.0 + default-browser-id: 5.0.1 + + defer-to-connect@2.0.1: {} - '@solana/assertions@3.0.3(typescript@5.9.3)': + define-data-property@1.1.4: dependencies: - '@solana/errors': 3.0.3(typescript@5.9.3) - typescript: 5.9.3 + es-define-property: 1.0.1 + es-errors: 1.3.0 + gopd: 1.2.0 - '@solana/buffer-layout@4.0.1': + define-lazy-prop@2.0.0: {} + + define-lazy-prop@3.0.0: {} + + define-properties@1.2.1: dependencies: - buffer: 6.0.3 + define-data-property: 1.1.4 + has-property-descriptors: 1.0.2 + object-keys: 1.1.1 - '@solana/codecs-core@2.3.0(typescript@5.9.3)': - dependencies: - '@solana/errors': 2.3.0(typescript@5.9.3) - typescript: 5.9.3 + defu@6.1.4: {} - '@solana/codecs-core@3.0.3(typescript@5.9.3)': - dependencies: - '@solana/errors': 3.0.3(typescript@5.9.3) - typescript: 5.9.3 + delay@5.0.0: {} - '@solana/codecs-data-structures@3.0.3(typescript@5.9.3)': - dependencies: - '@solana/codecs-core': 3.0.3(typescript@5.9.3) - '@solana/codecs-numbers': 3.0.3(typescript@5.9.3) - '@solana/errors': 3.0.3(typescript@5.9.3) - typescript: 5.9.3 + delayed-stream@1.0.0: {} - '@solana/codecs-numbers@2.3.0(typescript@5.9.3)': - dependencies: - '@solana/codecs-core': 2.3.0(typescript@5.9.3) - '@solana/errors': 2.3.0(typescript@5.9.3) - typescript: 5.9.3 + depd@1.1.2: {} - '@solana/codecs-numbers@3.0.3(typescript@5.9.3)': - dependencies: - '@solana/codecs-core': 3.0.3(typescript@5.9.3) - '@solana/errors': 3.0.3(typescript@5.9.3) - typescript: 5.9.3 + depd@2.0.0: {} - '@solana/codecs-strings@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)': - dependencies: - '@solana/codecs-core': 3.0.3(typescript@5.9.3) - '@solana/codecs-numbers': 3.0.3(typescript@5.9.3) - '@solana/errors': 3.0.3(typescript@5.9.3) - fastestsmallesttextencoderdecoder: 1.0.22 - typescript: 5.9.3 + dequal@2.0.3: {} - '@solana/codecs@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)': + derive-valtio@0.1.0(valtio@1.13.2(@types/react@18.3.27)(react@18.3.1)): dependencies: - '@solana/codecs-core': 3.0.3(typescript@5.9.3) - '@solana/codecs-data-structures': 3.0.3(typescript@5.9.3) - '@solana/codecs-numbers': 3.0.3(typescript@5.9.3) - '@solana/codecs-strings': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) - '@solana/options': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) - typescript: 5.9.3 - transitivePeerDependencies: - - fastestsmallesttextencoderdecoder + valtio: 1.13.2(@types/react@18.3.27)(react@18.3.1) - '@solana/errors@2.3.0(typescript@5.9.3)': - dependencies: - chalk: 5.6.2 - commander: 14.0.2 - typescript: 5.9.3 + destr@2.0.5: {} - '@solana/errors@3.0.3(typescript@5.9.3)': - dependencies: - chalk: 5.6.2 - commander: 14.0.0 - typescript: 5.9.3 + destroy@1.2.0: {} - '@solana/fast-stable-stringify@3.0.3(typescript@5.9.3)': - dependencies: - typescript: 5.9.3 + detect-browser@5.3.0: {} - '@solana/functional@3.0.3(typescript@5.9.3)': - dependencies: - typescript: 5.9.3 + detect-node-es@1.1.0: {} - '@solana/instruction-plans@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)': + detect-node@2.1.0: {} + + detect-port@1.6.1: dependencies: - '@solana/errors': 3.0.3(typescript@5.9.3) - '@solana/instructions': 3.0.3(typescript@5.9.3) - '@solana/promises': 3.0.3(typescript@5.9.3) - '@solana/transaction-messages': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) - '@solana/transactions': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) - typescript: 5.9.3 + address: 1.2.2 + debug: 4.4.3(supports-color@8.1.1) transitivePeerDependencies: - - fastestsmallesttextencoderdecoder + - supports-color - '@solana/instructions@3.0.3(typescript@5.9.3)': + devlop@1.1.0: dependencies: - '@solana/codecs-core': 3.0.3(typescript@5.9.3) - '@solana/errors': 3.0.3(typescript@5.9.3) - typescript: 5.9.3 + dequal: 2.0.3 - '@solana/keys@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)': - dependencies: - '@solana/assertions': 3.0.3(typescript@5.9.3) - '@solana/codecs-core': 3.0.3(typescript@5.9.3) - '@solana/codecs-strings': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) - '@solana/errors': 3.0.3(typescript@5.9.3) - '@solana/nominal-types': 3.0.3(typescript@5.9.3) - typescript: 5.9.3 - transitivePeerDependencies: - - fastestsmallesttextencoderdecoder + dexie@4.2.1: {} - '@solana/kit@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))': - dependencies: - '@solana/accounts': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) - '@solana/addresses': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) - '@solana/codecs': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) - '@solana/errors': 3.0.3(typescript@5.9.3) - '@solana/functional': 3.0.3(typescript@5.9.3) - '@solana/instruction-plans': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) - '@solana/instructions': 3.0.3(typescript@5.9.3) - '@solana/keys': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) - '@solana/programs': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) - '@solana/rpc': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) - '@solana/rpc-parsed-types': 3.0.3(typescript@5.9.3) - '@solana/rpc-spec-types': 3.0.3(typescript@5.9.3) - '@solana/rpc-subscriptions': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) - '@solana/rpc-types': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) - '@solana/signers': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) - '@solana/sysvars': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) - '@solana/transaction-confirmation': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) - '@solana/transaction-messages': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) - '@solana/transactions': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) - typescript: 5.9.3 - transitivePeerDependencies: - - fastestsmallesttextencoderdecoder - - ws + didyoumean@1.2.2: {} - '@solana/nominal-types@3.0.3(typescript@5.9.3)': - dependencies: - typescript: 5.9.3 + diff@4.0.2: {} - '@solana/options@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)': - dependencies: - '@solana/codecs-core': 3.0.3(typescript@5.9.3) - '@solana/codecs-data-structures': 3.0.3(typescript@5.9.3) - '@solana/codecs-numbers': 3.0.3(typescript@5.9.3) - '@solana/codecs-strings': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) - '@solana/errors': 3.0.3(typescript@5.9.3) - typescript: 5.9.3 - transitivePeerDependencies: - - fastestsmallesttextencoderdecoder + diff@5.2.0: {} - '@solana/programs@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)': + difflib@0.2.4: dependencies: - '@solana/addresses': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) - '@solana/errors': 3.0.3(typescript@5.9.3) - typescript: 5.9.3 - transitivePeerDependencies: - - fastestsmallesttextencoderdecoder + heap: 0.2.7 - '@solana/promises@3.0.3(typescript@5.9.3)': - dependencies: - typescript: 5.9.3 + dijkstrajs@1.0.3: {} - '@solana/rpc-api@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)': + dir-glob@3.0.1: dependencies: - '@solana/addresses': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) - '@solana/codecs-core': 3.0.3(typescript@5.9.3) - '@solana/codecs-strings': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) - '@solana/errors': 3.0.3(typescript@5.9.3) - '@solana/keys': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) - '@solana/rpc-parsed-types': 3.0.3(typescript@5.9.3) - '@solana/rpc-spec': 3.0.3(typescript@5.9.3) - '@solana/rpc-transformers': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) - '@solana/rpc-types': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) - '@solana/transaction-messages': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) - '@solana/transactions': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) - typescript: 5.9.3 - transitivePeerDependencies: - - fastestsmallesttextencoderdecoder + path-type: 4.0.0 - '@solana/rpc-parsed-types@3.0.3(typescript@5.9.3)': - dependencies: - typescript: 5.9.3 + dlv@1.1.3: {} - '@solana/rpc-spec-types@3.0.3(typescript@5.9.3)': + dns-packet@5.6.1: dependencies: - typescript: 5.9.3 + '@leichtgewicht/ip-codec': 2.0.5 - '@solana/rpc-spec@3.0.3(typescript@5.9.3)': + dom-converter@0.2.0: dependencies: - '@solana/errors': 3.0.3(typescript@5.9.3) - '@solana/rpc-spec-types': 3.0.3(typescript@5.9.3) - typescript: 5.9.3 + utila: 0.4.0 - '@solana/rpc-subscriptions-api@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)': + dom-serializer@1.4.1: dependencies: - '@solana/addresses': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) - '@solana/keys': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) - '@solana/rpc-subscriptions-spec': 3.0.3(typescript@5.9.3) - '@solana/rpc-transformers': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) - '@solana/rpc-types': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) - '@solana/transaction-messages': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) - '@solana/transactions': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) - typescript: 5.9.3 - transitivePeerDependencies: - - fastestsmallesttextencoderdecoder + domelementtype: 2.3.0 + domhandler: 4.3.1 + entities: 2.2.0 - '@solana/rpc-subscriptions-channel-websocket@3.0.3(typescript@5.9.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))': + dom-serializer@2.0.0: dependencies: - '@solana/errors': 3.0.3(typescript@5.9.3) - '@solana/functional': 3.0.3(typescript@5.9.3) - '@solana/rpc-subscriptions-spec': 3.0.3(typescript@5.9.3) - '@solana/subscribable': 3.0.3(typescript@5.9.3) - typescript: 5.9.3 - ws: 8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + domelementtype: 2.3.0 + domhandler: 5.0.3 + entities: 4.5.0 - '@solana/rpc-subscriptions-spec@3.0.3(typescript@5.9.3)': - dependencies: - '@solana/errors': 3.0.3(typescript@5.9.3) - '@solana/promises': 3.0.3(typescript@5.9.3) - '@solana/rpc-spec-types': 3.0.3(typescript@5.9.3) - '@solana/subscribable': 3.0.3(typescript@5.9.3) - typescript: 5.9.3 - - '@solana/rpc-subscriptions@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))': - dependencies: - '@solana/errors': 3.0.3(typescript@5.9.3) - '@solana/fast-stable-stringify': 3.0.3(typescript@5.9.3) - '@solana/functional': 3.0.3(typescript@5.9.3) - '@solana/promises': 3.0.3(typescript@5.9.3) - '@solana/rpc-spec-types': 3.0.3(typescript@5.9.3) - '@solana/rpc-subscriptions-api': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) - '@solana/rpc-subscriptions-channel-websocket': 3.0.3(typescript@5.9.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) - '@solana/rpc-subscriptions-spec': 3.0.3(typescript@5.9.3) - '@solana/rpc-transformers': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) - '@solana/rpc-types': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) - '@solana/subscribable': 3.0.3(typescript@5.9.3) - typescript: 5.9.3 - transitivePeerDependencies: - - fastestsmallesttextencoderdecoder - - ws + domelementtype@2.3.0: {} - '@solana/rpc-transformers@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)': + domhandler@4.3.1: dependencies: - '@solana/errors': 3.0.3(typescript@5.9.3) - '@solana/functional': 3.0.3(typescript@5.9.3) - '@solana/nominal-types': 3.0.3(typescript@5.9.3) - '@solana/rpc-spec-types': 3.0.3(typescript@5.9.3) - '@solana/rpc-types': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) - typescript: 5.9.3 - transitivePeerDependencies: - - fastestsmallesttextencoderdecoder + domelementtype: 2.3.0 - '@solana/rpc-transport-http@3.0.3(typescript@5.9.3)': + domhandler@5.0.3: dependencies: - '@solana/errors': 3.0.3(typescript@5.9.3) - '@solana/rpc-spec': 3.0.3(typescript@5.9.3) - '@solana/rpc-spec-types': 3.0.3(typescript@5.9.3) - typescript: 5.9.3 - undici-types: 7.16.0 + domelementtype: 2.3.0 - '@solana/rpc-types@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)': + domutils@2.8.0: dependencies: - '@solana/addresses': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) - '@solana/codecs-core': 3.0.3(typescript@5.9.3) - '@solana/codecs-numbers': 3.0.3(typescript@5.9.3) - '@solana/codecs-strings': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) - '@solana/errors': 3.0.3(typescript@5.9.3) - '@solana/nominal-types': 3.0.3(typescript@5.9.3) - typescript: 5.9.3 - transitivePeerDependencies: - - fastestsmallesttextencoderdecoder + dom-serializer: 1.4.1 + domelementtype: 2.3.0 + domhandler: 4.3.1 - '@solana/rpc@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)': + domutils@3.2.2: dependencies: - '@solana/errors': 3.0.3(typescript@5.9.3) - '@solana/fast-stable-stringify': 3.0.3(typescript@5.9.3) - '@solana/functional': 3.0.3(typescript@5.9.3) - '@solana/rpc-api': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) - '@solana/rpc-spec': 3.0.3(typescript@5.9.3) - '@solana/rpc-spec-types': 3.0.3(typescript@5.9.3) - '@solana/rpc-transformers': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) - '@solana/rpc-transport-http': 3.0.3(typescript@5.9.3) - '@solana/rpc-types': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) - typescript: 5.9.3 - transitivePeerDependencies: - - fastestsmallesttextencoderdecoder + dom-serializer: 2.0.0 + domelementtype: 2.3.0 + domhandler: 5.0.3 - '@solana/signers@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)': + dot-case@3.0.4: dependencies: - '@solana/addresses': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) - '@solana/codecs-core': 3.0.3(typescript@5.9.3) - '@solana/errors': 3.0.3(typescript@5.9.3) - '@solana/instructions': 3.0.3(typescript@5.9.3) - '@solana/keys': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) - '@solana/nominal-types': 3.0.3(typescript@5.9.3) - '@solana/transaction-messages': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) - '@solana/transactions': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) - typescript: 5.9.3 - transitivePeerDependencies: - - fastestsmallesttextencoderdecoder + no-case: 3.0.4 + tslib: 2.8.1 - '@solana/subscribable@3.0.3(typescript@5.9.3)': + dot-prop@6.0.1: dependencies: - '@solana/errors': 3.0.3(typescript@5.9.3) - typescript: 5.9.3 + is-obj: 2.0.0 - '@solana/sysvars@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)': - dependencies: - '@solana/accounts': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) - '@solana/codecs': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) - '@solana/errors': 3.0.3(typescript@5.9.3) - '@solana/rpc-types': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) - typescript: 5.9.3 - transitivePeerDependencies: - - fastestsmallesttextencoderdecoder + dotenv@16.6.1: {} - '@solana/transaction-confirmation@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))': + dunder-proto@1.0.1: dependencies: - '@solana/addresses': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) - '@solana/codecs-strings': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) - '@solana/errors': 3.0.3(typescript@5.9.3) - '@solana/keys': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) - '@solana/promises': 3.0.3(typescript@5.9.3) - '@solana/rpc': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) - '@solana/rpc-subscriptions': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) - '@solana/rpc-types': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) - '@solana/transaction-messages': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) - '@solana/transactions': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) - typescript: 5.9.3 - transitivePeerDependencies: - - fastestsmallesttextencoderdecoder - - ws + call-bind-apply-helpers: 1.0.2 + es-errors: 1.3.0 + gopd: 1.2.0 + + duplexer@0.1.2: {} - '@solana/transaction-messages@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)': + duplexify@4.1.3: dependencies: - '@solana/addresses': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) - '@solana/codecs-core': 3.0.3(typescript@5.9.3) - '@solana/codecs-data-structures': 3.0.3(typescript@5.9.3) - '@solana/codecs-numbers': 3.0.3(typescript@5.9.3) - '@solana/errors': 3.0.3(typescript@5.9.3) - '@solana/functional': 3.0.3(typescript@5.9.3) - '@solana/instructions': 3.0.3(typescript@5.9.3) - '@solana/nominal-types': 3.0.3(typescript@5.9.3) - '@solana/rpc-types': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) - typescript: 5.9.3 - transitivePeerDependencies: - - fastestsmallesttextencoderdecoder + end-of-stream: 1.4.5 + inherits: 2.0.4 + readable-stream: 3.6.2 + stream-shift: 1.0.3 - '@solana/transactions@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)': - dependencies: - '@solana/addresses': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) - '@solana/codecs-core': 3.0.3(typescript@5.9.3) - '@solana/codecs-data-structures': 3.0.3(typescript@5.9.3) - '@solana/codecs-numbers': 3.0.3(typescript@5.9.3) - '@solana/codecs-strings': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) - '@solana/errors': 3.0.3(typescript@5.9.3) - '@solana/functional': 3.0.3(typescript@5.9.3) - '@solana/instructions': 3.0.3(typescript@5.9.3) - '@solana/keys': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) - '@solana/nominal-types': 3.0.3(typescript@5.9.3) - '@solana/rpc-types': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) - '@solana/transaction-messages': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) - typescript: 5.9.3 - transitivePeerDependencies: - - fastestsmallesttextencoderdecoder + eastasianwidth@0.2.0: {} - '@solana/web3.js@1.98.4(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)': + eciesjs@0.4.16: dependencies: - '@babel/runtime': 7.28.4 + '@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 - '@solana/buffer-layout': 4.0.1 - '@solana/codecs-numbers': 2.3.0(typescript@5.9.3) - agentkeepalive: 4.6.0 - bn.js: 5.2.2 - borsh: 0.7.0 - bs58: 4.0.1 - buffer: 6.0.3 - fast-stable-stringify: 1.0.0 - jayson: 4.2.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) - node-fetch: 2.7.0 - rpc-websockets: 9.3.2 - superstruct: 2.0.2 - transitivePeerDependencies: - - bufferutil - - encoding - - typescript - - utf-8-validate - '@solidity-parser/parser@0.14.5': - dependencies: - antlr4ts: 0.5.0-alpha.4 + ee-first@1.1.1: {} - '@solidity-parser/parser@0.20.2': {} + electron-to-chromium@1.5.267: {} - '@swc/helpers@0.5.17': + elliptic@6.6.1: dependencies: - tslib: 2.8.1 - - '@tanstack/query-core@5.90.12': {} + bn.js: 4.12.2 + brorand: 1.1.0 + hash.js: 1.1.7 + hmac-drbg: 1.0.1 + inherits: 2.0.4 + minimalistic-assert: 1.0.1 + minimalistic-crypto-utils: 1.0.1 - '@tanstack/react-query@5.90.12(react@18.3.1)': - dependencies: - '@tanstack/query-core': 5.90.12 - react: 18.3.1 + emoji-regex@8.0.0: {} - '@tsconfig/node10@1.0.12': {} + emoji-regex@9.2.2: {} - '@tsconfig/node12@1.0.11': {} + emojilib@2.4.0: {} - '@tsconfig/node14@1.0.3': {} + emojis-list@3.0.0: {} - '@tsconfig/node16@1.0.4': {} + emoticon@4.1.0: {} - '@typechain/ethers-v6@0.5.1(ethers@6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(typechain@8.3.2(typescript@5.9.3))(typescript@5.9.3)': - dependencies: - ethers: 6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) - lodash: 4.17.21 - ts-essentials: 7.0.3(typescript@5.9.3) - typechain: 8.3.2(typescript@5.9.3) - typescript: 5.9.3 + encode-utf8@1.0.3: {} - '@typechain/hardhat@9.1.0(@typechain/ethers-v6@0.5.1(ethers@6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(typechain@8.3.2(typescript@5.9.3))(typescript@5.9.3))(ethers@6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10))(typechain@8.3.2(typescript@5.9.3))': - dependencies: - '@typechain/ethers-v6': 0.5.1(ethers@6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(typechain@8.3.2(typescript@5.9.3))(typescript@5.9.3) - ethers: 6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) - fs-extra: 9.1.0 - hardhat: 2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10) - typechain: 8.3.2(typescript@5.9.3) + encodeurl@2.0.0: {} - '@types/babel__core@7.20.5': + end-of-stream@1.4.5: dependencies: - '@babel/parser': 7.28.5 - '@babel/types': 7.28.5 - '@types/babel__generator': 7.27.0 - '@types/babel__template': 7.4.4 - '@types/babel__traverse': 7.28.0 + once: 1.4.0 - '@types/babel__generator@7.27.0': + engine.io-client@6.6.3(bufferutil@4.0.9)(utf-8-validate@5.0.10): dependencies: - '@babel/types': 7.28.5 + '@socket.io/component-emitter': 3.1.2 + debug: 4.3.4 + engine.io-parser: 5.2.3 + ws: 8.17.1(bufferutil@4.0.9)(utf-8-validate@5.0.10) + xmlhttprequest-ssl: 2.1.2 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate - '@types/babel__template@7.4.4': - dependencies: - '@babel/parser': 7.28.5 - '@babel/types': 7.28.5 + engine.io-parser@5.2.3: {} - '@types/babel__traverse@7.28.0': + enhanced-resolve@5.18.4: dependencies: - '@babel/types': 7.28.5 + graceful-fs: 4.2.11 + tapable: 2.3.0 - '@types/bn.js@5.2.0': + enquirer@2.4.1: dependencies: - '@types/node': 20.19.27 + ansi-colors: 4.1.3 + strip-ansi: 6.0.1 - '@types/chai-as-promised@7.1.8': - dependencies: - '@types/chai': 4.3.20 + entities@2.2.0: {} - '@types/chai@4.3.20': {} + entities@4.5.0: {} - '@types/chai@5.2.3': - dependencies: - '@types/deep-eql': 4.0.2 - assertion-error: 2.0.1 + entities@6.0.1: {} - '@types/concat-stream@1.6.1': - dependencies: - '@types/node': 20.19.27 + env-paths@2.2.1: {} - '@types/connect@3.4.38': + error-ex@1.3.4: dependencies: - '@types/node': 20.19.27 + is-arrayish: 0.2.1 - '@types/debug@4.1.12': - dependencies: - '@types/ms': 2.1.0 + es-define-property@1.0.1: {} - '@types/deep-eql@4.0.2': {} + es-errors@1.3.0: {} - '@types/estree@1.0.8': {} + es-module-lexer@1.7.0: {} - '@types/form-data@0.0.33': - dependencies: - '@types/node': 20.19.27 + es-module-lexer@2.0.0: {} - '@types/glob@7.2.0': + es-object-atoms@1.1.1: dependencies: - '@types/minimatch': 6.0.0 - '@types/node': 20.19.27 - - '@types/lodash@4.17.21': {} + es-errors: 1.3.0 - '@types/minimatch@6.0.0': + es-set-tostringtag@2.1.0: dependencies: - minimatch: 10.1.1 - - '@types/mocha@10.0.10': {} + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + has-tostringtag: 1.0.2 + hasown: 2.0.2 - '@types/ms@2.1.0': {} + es-toolkit@1.33.0: {} - '@types/node@10.17.60': {} + es6-promise@4.2.8: {} - '@types/node@12.20.55': {} + es6-promisify@5.0.0: + dependencies: + es6-promise: 4.2.8 - '@types/node@20.19.27': + esast-util-from-estree@2.0.0: dependencies: - undici-types: 6.21.0 + '@types/estree-jsx': 1.0.5 + devlop: 1.1.0 + estree-util-visit: 2.0.0 + unist-util-position-from-estree: 2.0.0 - '@types/node@22.7.5': + esast-util-from-js@2.0.1: dependencies: - undici-types: 6.19.8 + '@types/estree-jsx': 1.0.5 + acorn: 8.15.0 + esast-util-from-estree: 2.0.0 + vfile-message: 4.0.3 + + esbuild@0.21.5: + optionalDependencies: + '@esbuild/aix-ppc64': 0.21.5 + '@esbuild/android-arm': 0.21.5 + '@esbuild/android-arm64': 0.21.5 + '@esbuild/android-x64': 0.21.5 + '@esbuild/darwin-arm64': 0.21.5 + '@esbuild/darwin-x64': 0.21.5 + '@esbuild/freebsd-arm64': 0.21.5 + '@esbuild/freebsd-x64': 0.21.5 + '@esbuild/linux-arm': 0.21.5 + '@esbuild/linux-arm64': 0.21.5 + '@esbuild/linux-ia32': 0.21.5 + '@esbuild/linux-loong64': 0.21.5 + '@esbuild/linux-mips64el': 0.21.5 + '@esbuild/linux-ppc64': 0.21.5 + '@esbuild/linux-riscv64': 0.21.5 + '@esbuild/linux-s390x': 0.21.5 + '@esbuild/linux-x64': 0.21.5 + '@esbuild/netbsd-x64': 0.21.5 + '@esbuild/openbsd-x64': 0.21.5 + '@esbuild/sunos-x64': 0.21.5 + '@esbuild/win32-arm64': 0.21.5 + '@esbuild/win32-ia32': 0.21.5 + '@esbuild/win32-x64': 0.21.5 - '@types/node@8.10.66': {} + escalade@3.2.0: {} - '@types/pbkdf2@3.1.2': - dependencies: - '@types/node': 20.19.27 + escape-goat@4.0.0: {} - '@types/prettier@2.7.3': {} + escape-html@1.0.3: {} - '@types/prop-types@15.7.15': {} + escape-string-regexp@1.0.5: {} - '@types/qs@6.14.0': {} + escape-string-regexp@4.0.0: {} - '@types/react-dom@18.3.7(@types/react@18.3.27)': - dependencies: - '@types/react': 18.3.27 + escape-string-regexp@5.0.0: {} - '@types/react@18.3.27': + escodegen@1.8.1: dependencies: - '@types/prop-types': 15.7.15 - csstype: 3.2.3 + esprima: 2.7.3 + estraverse: 1.9.3 + esutils: 2.0.3 + optionator: 0.8.3 + optionalDependencies: + source-map: 0.2.0 - '@types/secp256k1@4.0.7': + eslint-scope@5.1.1: dependencies: - '@types/node': 20.19.27 + esrecurse: 4.3.0 + estraverse: 4.3.0 - '@types/trusted-types@2.0.7': {} - - '@types/uuid@8.3.4': {} + esprima@2.7.3: {} - '@types/ws@7.4.7': - dependencies: - '@types/node': 20.19.27 + esprima@4.0.1: {} - '@types/ws@8.18.1': + esrecurse@4.3.0: dependencies: - '@types/node': 20.19.27 - - '@uniswap/lib@4.0.1-alpha': {} + estraverse: 5.3.0 - '@uniswap/v2-core@1.0.1': {} + estraverse@1.9.3: {} - '@uniswap/v3-core@1.0.1': {} + estraverse@4.3.0: {} - '@uniswap/v3-periphery@1.4.4': - dependencies: - '@openzeppelin/contracts': 3.4.2-solc-0.7 - '@uniswap/lib': 4.0.1-alpha - '@uniswap/v2-core': 1.0.1 - '@uniswap/v3-core': 1.0.1 - base64-sol: 1.0.1 + estraverse@5.3.0: {} - '@vanilla-extract/css@1.17.3': + estree-util-attach-comments@3.0.0: dependencies: - '@emotion/hash': 0.9.2 - '@vanilla-extract/private': 1.0.9 - css-what: 6.2.2 - cssesc: 3.0.0 - csstype: 3.2.3 - dedent: 1.7.1 - deep-object-diff: 1.1.9 - deepmerge: 4.3.1 - lru-cache: 10.4.3 - media-query-parser: 2.0.2 - modern-ahocorasick: 1.1.0 - picocolors: 1.1.1 - transitivePeerDependencies: - - babel-plugin-macros + '@types/estree': 1.0.8 - '@vanilla-extract/dynamic@2.1.4': + estree-util-build-jsx@3.0.1: dependencies: - '@vanilla-extract/private': 1.0.9 - - '@vanilla-extract/private@1.0.9': {} + '@types/estree-jsx': 1.0.5 + devlop: 1.1.0 + estree-util-is-identifier-name: 3.0.0 + estree-walker: 3.0.3 - '@vanilla-extract/sprinkles@1.6.4(@vanilla-extract/css@1.17.3)': - dependencies: - '@vanilla-extract/css': 1.17.3 + estree-util-is-identifier-name@3.0.0: {} - '@vitejs/plugin-react@4.7.0(vite@5.4.21(@types/node@22.7.5))': + estree-util-scope@1.0.0: dependencies: - '@babel/core': 7.28.5 - '@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-react-jsx-source': 7.27.1(@babel/core@7.28.5) - '@rolldown/pluginutils': 1.0.0-beta.27 - '@types/babel__core': 7.20.5 - react-refresh: 0.17.0 - vite: 5.4.21(@types/node@22.7.5) - transitivePeerDependencies: - - supports-color + '@types/estree': 1.0.8 + devlop: 1.1.0 - '@vitest/expect@3.2.4': + estree-util-to-js@2.0.0: dependencies: - '@types/chai': 5.2.3 - '@vitest/spy': 3.2.4 - '@vitest/utils': 3.2.4 - chai: 5.3.3 - tinyrainbow: 2.0.0 + '@types/estree-jsx': 1.0.5 + astring: 1.9.0 + source-map: 0.7.6 - '@vitest/mocker@3.2.4(vite@5.4.21(@types/node@20.19.27))': + estree-util-value-to-estree@3.5.0: dependencies: - '@vitest/spy': 3.2.4 - estree-walker: 3.0.3 - magic-string: 0.30.21 - optionalDependencies: - vite: 5.4.21(@types/node@20.19.27) + '@types/estree': 1.0.8 - '@vitest/pretty-format@3.2.4': + estree-util-visit@2.0.0: dependencies: - tinyrainbow: 2.0.0 + '@types/estree-jsx': 1.0.5 + '@types/unist': 3.0.3 - '@vitest/runner@3.2.4': + estree-walker@3.0.3: dependencies: - '@vitest/utils': 3.2.4 - pathe: 2.0.3 - strip-literal: 3.1.0 + '@types/estree': 1.0.8 - '@vitest/snapshot@3.2.4': - dependencies: - '@vitest/pretty-format': 3.2.4 - magic-string: 0.30.21 - pathe: 2.0.3 + esutils@2.0.3: {} - '@vitest/spy@3.2.4': - dependencies: - tinyspy: 4.0.4 + eta@2.2.0: {} - '@vitest/utils@3.2.4': - dependencies: - '@vitest/pretty-format': 3.2.4 - loupe: 3.2.1 - tinyrainbow: 2.0.0 + etag@1.8.1: {} - '@wagmi/connectors@6.2.0(3e683225d0eaab4e1b5a92e5a7d66afa)': + eth-block-tracker@7.1.0: dependencies: - '@base-org/account': 2.4.0(@types/react@18.3.27)(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(immer@10.0.2)(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)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@4.2.1) - '@coinbase/wallet-sdk': 4.3.6(@types/react@18.3.27)(bufferutil@4.0.9)(immer@10.0.2)(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.2.1) - '@gemini-wallet/core': 0.3.2(viem@2.43.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1)) - '@metamask/sdk': 0.33.1(bufferutil@4.0.9)(utf-8-validate@5.0.10) - '@safe-global/safe-apps-provider': 0.18.6(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) - '@safe-global/safe-apps-sdk': 9.1.0(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) - '@wagmi/core': 2.22.1(@tanstack/query-core@5.90.12)(@types/react@18.3.27)(immer@10.0.2)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@18.3.1))(viem@2.43.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1)) - '@walletconnect/ethereum-provider': 2.21.1(@types/react@18.3.27)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) - cbw-sdk: '@coinbase/wallet-sdk@3.9.3' - porto: 0.2.35(@tanstack/react-query@5.90.12(react@18.3.1))(@types/react@18.3.27)(@wagmi/core@2.22.1(@tanstack/query-core@5.90.12)(@types/react@18.3.27)(immer@10.0.2)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@18.3.1))(viem@2.43.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1)))(immer@10.0.2)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@18.3.1))(viem@2.43.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1))(wagmi@2.19.5(@tanstack/query-core@5.90.12)(@tanstack/react-query@5.90.12(react@18.3.1))(@types/react@18.3.27)(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(immer@10.0.2)(react@18.3.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.43.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1))(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@4.2.1)) - viem: 2.43.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) - optionalDependencies: - typescript: 5.9.3 + '@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: - - '@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 - - ws - - zod - - '@wagmi/core@2.22.1(@tanstack/query-core@5.90.12)(@types/react@18.3.27)(immer@10.0.2)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@18.3.1))(viem@2.43.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1))': - dependencies: - eventemitter3: 5.0.1 - mipd: 0.0.7(typescript@5.9.3) - viem: 2.43.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) - zustand: 5.0.0(@types/react@18.3.27)(immer@10.0.2)(react@18.3.1)(use-sync-external-store@1.4.0(react@18.3.1)) - optionalDependencies: - '@tanstack/query-core': 5.90.12 - typescript: 5.9.3 - transitivePeerDependencies: - - '@types/react' - - immer - - react - - use-sync-external-store - - '@walletconnect/core@2.21.0(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1)': - dependencies: - '@walletconnect/heartbeat': 1.2.2 - '@walletconnect/jsonrpc-provider': 1.0.14 - '@walletconnect/jsonrpc-types': 1.0.4 - '@walletconnect/jsonrpc-utils': 1.0.8 - '@walletconnect/jsonrpc-ws-connection': 1.0.16(bufferutil@4.0.9)(utf-8-validate@5.0.10) - '@walletconnect/keyvaluestorage': 1.1.1 - '@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.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) - '@walletconnect/window-getters': 1.0.1 - es-toolkit: 1.33.0 - events: 3.3.0 - uint8arrays: 3.1.0 - transitivePeerDependencies: - - '@azure/app-configuration' - - '@azure/cosmos' - - '@azure/data-tables' - - '@azure/identity' - - '@azure/keyvault-secrets' - - '@azure/storage-blob' - - '@capacitor/preferences' - - '@deno/kv' - - '@netlify/blobs' - - '@planetscale/database' - - '@react-native-async-storage/async-storage' - - '@upstash/redis' - - '@vercel/blob' - - '@vercel/functions' - - '@vercel/kv' - - aws4fetch - - bufferutil - - db0 - - ioredis - - typescript - - uploadthing - - utf-8-validate - - zod - '@walletconnect/core@2.21.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1)': + eth-gas-reporter@0.2.27(bufferutil@4.0.9)(utf-8-validate@5.0.10): dependencies: - '@walletconnect/heartbeat': 1.2.2 - '@walletconnect/jsonrpc-provider': 1.0.14 - '@walletconnect/jsonrpc-types': 1.0.4 - '@walletconnect/jsonrpc-utils': 1.0.8 - '@walletconnect/jsonrpc-ws-connection': 1.0.16(bufferutil@4.0.9)(utf-8-validate@5.0.10) - '@walletconnect/keyvaluestorage': 1.1.1 - '@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.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) - '@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 + '@solidity-parser/parser': 0.14.5 + axios: 1.13.2(debug@4.4.3) + cli-table3: 0.5.1 + colors: 1.4.0 + ethereum-cryptography: 1.2.0 + ethers: 5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + fs-readdir-recursive: 1.1.0 + lodash: 4.17.21 + markdown-table: 1.1.3 + mocha: 10.8.2 + req-cwd: 2.0.0 + sha1: 1.1.1 + sync-request: 6.1.0 + transitivePeerDependencies: - bufferutil - - db0 - - ioredis - - typescript - - uploadthing + - debug - utf-8-validate - - zod - '@walletconnect/environment@1.0.1': + eth-json-rpc-filters@6.0.1: dependencies: - tslib: 1.14.1 + '@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 - '@walletconnect/ethereum-provider@2.21.1(@types/react@18.3.27)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1)': + eth-query@2.1.2: dependencies: - '@reown/appkit': 1.7.8(@types/react@18.3.27)(bufferutil@4.0.9)(react@18.3.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.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/sign-client': 2.21.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) - '@walletconnect/types': 2.21.1 - '@walletconnect/universal-provider': 2.21.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) - '@walletconnect/utils': 2.21.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) - 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 + json-rpc-random-id: 1.0.1 + xtend: 4.0.2 - '@walletconnect/events@1.0.1': + eth-rpc-errors@4.0.3: dependencies: - keyvaluestorage-interface: 1.0.0 - tslib: 1.14.1 + fast-safe-stringify: 2.1.1 - '@walletconnect/heartbeat@1.2.2': + ethereum-bloom-filters@1.2.0: dependencies: - '@walletconnect/events': 1.0.1 - '@walletconnect/time': 1.0.2 - events: 3.3.0 + '@noble/hashes': 1.8.0 - '@walletconnect/jsonrpc-http-connection@1.0.8': + ethereum-cryptography@0.1.3: dependencies: - '@walletconnect/jsonrpc-utils': 1.0.8 - '@walletconnect/safe-json': 1.0.2 - cross-fetch: 3.2.0 - events: 3.3.0 - transitivePeerDependencies: - - encoding + '@types/pbkdf2': 3.1.2 + '@types/secp256k1': 4.0.7 + blakejs: 1.2.1 + browserify-aes: 1.2.0 + bs58check: 2.1.2 + create-hash: 1.2.0 + create-hmac: 1.1.7 + hash.js: 1.1.7 + keccak: 3.0.4 + pbkdf2: 3.1.5 + randombytes: 2.1.0 + safe-buffer: 5.2.1 + scrypt-js: 3.0.1 + secp256k1: 4.0.4 + setimmediate: 1.0.5 - '@walletconnect/jsonrpc-provider@1.0.14': + ethereum-cryptography@1.2.0: dependencies: - '@walletconnect/jsonrpc-utils': 1.0.8 - '@walletconnect/safe-json': 1.0.2 - events: 3.3.0 + '@noble/hashes': 1.2.0 + '@noble/secp256k1': 1.7.1 + '@scure/bip32': 1.1.5 + '@scure/bip39': 1.1.1 - '@walletconnect/jsonrpc-types@1.0.4': + ethereum-cryptography@2.2.1: dependencies: - events: 3.3.0 - keyvaluestorage-interface: 1.0.0 + '@noble/curves': 1.4.2 + '@noble/hashes': 1.4.0 + '@scure/bip32': 1.4.0 + '@scure/bip39': 1.3.0 - '@walletconnect/jsonrpc-utils@1.0.8': + ethereumjs-util@7.1.5: dependencies: - '@walletconnect/environment': 1.0.1 - '@walletconnect/jsonrpc-types': 1.0.4 - tslib: 1.14.1 + '@types/bn.js': 5.2.0 + bn.js: 5.2.2 + create-hash: 1.2.0 + ethereum-cryptography: 0.1.3 + rlp: 2.2.7 - '@walletconnect/jsonrpc-ws-connection@1.0.16(bufferutil@4.0.9)(utf-8-validate@5.0.10)': + ethers@5.8.0(bufferutil@4.0.9)(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.0.9)(utf-8-validate@5.0.10) + '@ethersproject/abi': 5.8.0 + '@ethersproject/abstract-provider': 5.8.0 + '@ethersproject/abstract-signer': 5.8.0 + '@ethersproject/address': 5.8.0 + '@ethersproject/base64': 5.8.0 + '@ethersproject/basex': 5.8.0 + '@ethersproject/bignumber': 5.8.0 + '@ethersproject/bytes': 5.8.0 + '@ethersproject/constants': 5.8.0 + '@ethersproject/contracts': 5.8.0 + '@ethersproject/hash': 5.8.0 + '@ethersproject/hdnode': 5.8.0 + '@ethersproject/json-wallets': 5.8.0 + '@ethersproject/keccak256': 5.8.0 + '@ethersproject/logger': 5.8.0 + '@ethersproject/networks': 5.8.0 + '@ethersproject/pbkdf2': 5.8.0 + '@ethersproject/properties': 5.8.0 + '@ethersproject/providers': 5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@ethersproject/random': 5.8.0 + '@ethersproject/rlp': 5.8.0 + '@ethersproject/sha2': 5.8.0 + '@ethersproject/signing-key': 5.8.0 + '@ethersproject/solidity': 5.8.0 + '@ethersproject/strings': 5.8.0 + '@ethersproject/transactions': 5.8.0 + '@ethersproject/units': 5.8.0 + '@ethersproject/wallet': 5.8.0 + '@ethersproject/web': 5.8.0 + '@ethersproject/wordlists': 5.8.0 transitivePeerDependencies: - bufferutil - utf-8-validate - '@walletconnect/keyvaluestorage@1.1.1': + ethers@6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10): dependencies: - '@walletconnect/safe-json': 1.0.2 - idb-keyval: 6.2.2 - unstorage: 1.17.3(idb-keyval@6.2.2) + '@adraffy/ens-normalize': 1.10.1 + '@noble/curves': 1.2.0 + '@noble/hashes': 1.3.2 + '@types/node': 22.7.5 + aes-js: 4.0.0-beta.5 + tslib: 2.7.0 + ws: 8.17.1(bufferutil@4.0.9)(utf-8-validate@5.0.10) 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 + - bufferutil + - utf-8-validate - '@walletconnect/logger@2.1.2': + ethjs-unit@0.1.6: dependencies: - '@walletconnect/safe-json': 1.0.2 - pino: 7.11.0 + bn.js: 4.11.6 + number-to-bn: 1.7.0 + + eval@0.1.8: + dependencies: + '@types/node': 20.19.27 + require-like: 0.1.2 + + eventemitter2@6.4.9: {} + + eventemitter3@4.0.7: {} + + eventemitter3@5.0.1: {} + + events@3.3.0: {} + + evp_bytestokey@1.0.3: + dependencies: + md5.js: 1.3.5 + safe-buffer: 5.2.1 + + execa@5.1.1: + dependencies: + cross-spawn: 7.0.6 + get-stream: 6.0.1 + human-signals: 2.1.0 + is-stream: 2.0.1 + merge-stream: 2.0.0 + npm-run-path: 4.0.1 + onetime: 5.1.2 + signal-exit: 3.0.7 + strip-final-newline: 2.0.0 + + expect-type@1.3.0: {} + + express@4.22.1: + dependencies: + accepts: 1.3.8 + array-flatten: 1.1.1 + body-parser: 1.20.4 + content-disposition: 0.5.4 + content-type: 1.0.5 + cookie: 0.7.2 + cookie-signature: 1.0.7 + debug: 2.6.9 + depd: 2.0.0 + encodeurl: 2.0.0 + escape-html: 1.0.3 + etag: 1.8.1 + finalhandler: 1.3.2 + fresh: 0.5.2 + http-errors: 2.0.1 + merge-descriptors: 1.0.3 + methods: 1.1.2 + on-finished: 2.4.1 + parseurl: 1.3.3 + path-to-regexp: 0.1.12 + proxy-addr: 2.0.7 + qs: 6.14.0 + range-parser: 1.2.1 + safe-buffer: 5.2.1 + send: 0.19.2 + serve-static: 1.16.3 + setprototypeof: 1.2.0 + statuses: 2.0.2 + type-is: 1.6.18 + utils-merge: 1.0.1 + vary: 1.1.2 + transitivePeerDependencies: + - supports-color + + extend-shallow@2.0.1: + dependencies: + is-extendable: 0.1.1 + + extend@3.0.2: {} + + extension-port-stream@3.0.0: + dependencies: + readable-stream: 3.6.2 + webextension-polyfill: 0.10.0 + + eyes@0.1.8: {} + + fast-base64-decode@1.0.0: {} + + fast-deep-equal@3.1.3: {} + + fast-glob@3.3.3: + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.8 + + fast-json-stable-stringify@2.1.0: {} + + fast-levenshtein@2.0.6: {} + + fast-redact@3.5.0: {} + + fast-safe-stringify@2.1.1: {} + + fast-stable-stringify@1.0.0: {} + + fast-uri@3.1.0: {} - '@walletconnect/relay-api@1.0.11': + fast-xml-parser@5.2.5: dependencies: - '@walletconnect/jsonrpc-types': 1.0.4 + strnum: 2.1.2 - '@walletconnect/relay-auth@1.1.0': + fastestsmallesttextencoderdecoder@1.0.22: {} + + fastq@1.19.1: 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 + reusify: 1.1.0 - '@walletconnect/safe-json@1.0.2': + fault@2.0.1: dependencies: - tslib: 1.14.1 + format: 0.2.2 - '@walletconnect/sign-client@2.21.0(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1)': + faye-websocket@0.11.4: dependencies: - '@walletconnect/core': 2.21.0(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) - '@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.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) - 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 + websocket-driver: 0.7.4 + + fdir@6.5.0(picomatch@4.0.3): + optionalDependencies: + picomatch: 4.0.3 - '@walletconnect/sign-client@2.21.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1)': + feed@4.2.2: dependencies: - '@walletconnect/core': 2.21.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) - '@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.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) - 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 + xml-js: 1.6.11 - '@walletconnect/time@1.0.2': + figures@3.2.0: dependencies: - tslib: 1.14.1 + escape-string-regexp: 1.0.5 - '@walletconnect/types@2.21.0': + file-loader@6.2.0(webpack@5.104.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 + loader-utils: 2.0.4 + schema-utils: 3.3.0 + webpack: 5.104.1 - '@walletconnect/types@2.21.1': + fill-range@7.1.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 + to-regex-range: 5.0.1 + + filter-obj@1.1.0: {} - '@walletconnect/universal-provider@2.21.0(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1)': + finalhandler@1.3.2: 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.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) - '@walletconnect/types': 2.21.0 - '@walletconnect/utils': 2.21.0(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) - es-toolkit: 1.33.0 - events: 3.3.0 + debug: 2.6.9 + encodeurl: 2.0.0 + escape-html: 1.0.3 + on-finished: 2.4.1 + parseurl: 1.3.3 + statuses: 2.0.2 + unpipe: 1.0.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 + - supports-color - '@walletconnect/universal-provider@2.21.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1)': + find-cache-dir@4.0.0: 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.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) - '@walletconnect/types': 2.21.1 - '@walletconnect/utils': 2.21.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) - 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 + common-path-prefix: 3.0.0 + pkg-dir: 7.0.0 - '@walletconnect/utils@2.21.0(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1)': + find-replace@3.0.0: 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.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) - transitivePeerDependencies: - - '@azure/app-configuration' - - '@azure/cosmos' - - '@azure/data-tables' - - '@azure/identity' - - '@azure/keyvault-secrets' - - '@azure/storage-blob' - - '@capacitor/preferences' - - '@deno/kv' - - '@netlify/blobs' - - '@planetscale/database' - - '@react-native-async-storage/async-storage' - - '@upstash/redis' - - '@vercel/blob' - - '@vercel/functions' - - '@vercel/kv' - - aws4fetch - - bufferutil - - db0 - - ioredis - - typescript - - uploadthing - - utf-8-validate - - zod + array-back: 3.1.0 - '@walletconnect/utils@2.21.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1)': + find-up@4.1.0: 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.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) - transitivePeerDependencies: - - '@azure/app-configuration' - - '@azure/cosmos' - - '@azure/data-tables' - - '@azure/identity' - - '@azure/keyvault-secrets' - - '@azure/storage-blob' - - '@capacitor/preferences' - - '@deno/kv' - - '@netlify/blobs' - - '@planetscale/database' - - '@react-native-async-storage/async-storage' - - '@upstash/redis' - - '@vercel/blob' - - '@vercel/functions' - - '@vercel/kv' - - aws4fetch - - bufferutil - - db0 - - ioredis - - typescript - - uploadthing - - utf-8-validate - - zod + locate-path: 5.0.0 + path-exists: 4.0.0 - '@walletconnect/window-getters@1.0.1': + find-up@5.0.0: dependencies: - tslib: 1.14.1 + locate-path: 6.0.0 + path-exists: 4.0.0 - '@walletconnect/window-metadata@1.0.1': + find-up@6.3.0: dependencies: - '@walletconnect/window-getters': 1.0.1 - tslib: 1.14.1 + locate-path: 7.2.0 + path-exists: 5.0.0 - abbrev@1.0.9: {} + flat@5.0.2: {} - abitype@1.0.6(typescript@5.9.3)(zod@3.25.76): + follow-redirects@1.15.11(debug@4.4.3): optionalDependencies: - typescript: 5.9.3 - zod: 3.25.76 + debug: 4.4.3(supports-color@8.1.1) - abitype@1.0.8(typescript@5.9.3)(zod@4.2.1): - optionalDependencies: - typescript: 5.9.3 - zod: 4.2.1 + for-each@0.3.5: + dependencies: + is-callable: 1.2.7 - abitype@1.2.3(typescript@5.9.3)(zod@3.22.4): - optionalDependencies: - typescript: 5.9.3 - zod: 3.22.4 + form-data-encoder@2.1.4: {} - abitype@1.2.3(typescript@5.9.3)(zod@3.25.76): - optionalDependencies: - typescript: 5.9.3 - zod: 3.25.76 + form-data@2.5.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 + safe-buffer: 5.2.1 + + 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 + + format@0.2.2: {} + + forwarded@0.2.0: {} + + fp-ts@1.19.3: {} + + fraction.js@5.3.4: {} - abitype@1.2.3(typescript@5.9.3)(zod@4.2.1): + framer-motion@12.23.26(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + motion-dom: 12.23.23 + motion-utils: 12.23.6 + tslib: 2.8.1 optionalDependencies: - typescript: 5.9.3 - zod: 4.2.1 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) - acorn-walk@8.3.4: + fresh@0.5.2: {} + + fs-extra@10.1.0: dependencies: - acorn: 8.15.0 + graceful-fs: 4.2.11 + jsonfile: 6.2.0 + universalify: 2.0.1 - acorn@8.15.0: {} + fs-extra@11.3.3: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 6.2.0 + universalify: 2.0.1 - adm-zip@0.4.16: {} + fs-extra@7.0.1: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 4.0.0 + universalify: 0.1.2 - aes-js@3.0.0: {} + fs-extra@8.1.0: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 4.0.0 + universalify: 0.1.2 - aes-js@4.0.0-beta.5: {} + fs-extra@9.1.0: + dependencies: + at-least-node: 1.0.0 + graceful-fs: 4.2.11 + jsonfile: 6.2.0 + universalify: 2.0.1 - agent-base@6.0.2: + fs-readdir-recursive@1.1.0: {} + + 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: - debug: 4.4.3(supports-color@8.1.1) - transitivePeerDependencies: - - supports-color + 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 - agentkeepalive@4.6.0: + get-nonce@1.0.1: {} + + get-own-enumerable-property-symbols@3.0.2: {} + + get-port@3.2.0: {} + + get-proto@1.0.1: dependencies: - humanize-ms: 1.2.1 + dunder-proto: 1.0.1 + es-object-atoms: 1.1.1 - aggregate-error@3.1.0: + get-stream@6.0.1: {} + + ghost-testrpc@0.0.2: dependencies: - clean-stack: 2.2.0 - indent-string: 4.0.0 + chalk: 2.4.2 + node-emoji: 1.11.0 - ajv@8.17.1: + github-slugger@1.5.0: {} + + glob-parent@5.1.2: dependencies: - fast-deep-equal: 3.1.3 - fast-uri: 3.1.0 - json-schema-traverse: 1.0.0 - require-from-string: 2.0.2 + is-glob: 4.0.3 - amazon-cognito-identity-js@6.3.16: + glob-parent@6.0.2: dependencies: - '@aws-crypto/sha256-js': 1.2.2 - buffer: 4.9.2 - fast-base64-decode: 1.0.0 - isomorphic-unfetch: 3.1.0 - js-cookie: 2.2.1 - transitivePeerDependencies: - - encoding + is-glob: 4.0.3 - amdefine@1.0.1: - optional: true + glob-to-regex.js@1.2.0(tslib@2.8.1): + dependencies: + tslib: 2.8.1 + + glob-to-regexp@0.4.1: {} + + glob@5.0.15: + dependencies: + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.2 + once: 1.4.0 + path-is-absolute: 1.0.1 + + glob@7.1.7: + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.2 + once: 1.4.0 + path-is-absolute: 1.0.1 + + glob@7.2.3: + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.2 + once: 1.4.0 + path-is-absolute: 1.0.1 + + glob@8.1.0: + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 5.1.6 + once: 1.4.0 + + global-dirs@3.0.1: + dependencies: + ini: 2.0.0 + + global-modules@2.0.0: + dependencies: + global-prefix: 3.0.0 + + global-prefix@3.0.0: + dependencies: + ini: 1.3.8 + kind-of: 6.0.3 + which: 1.3.1 + + globby@10.0.2: + dependencies: + '@types/glob': 7.2.0 + array-union: 2.1.0 + dir-glob: 3.0.1 + fast-glob: 3.3.3 + glob: 7.2.3 + ignore: 5.3.2 + merge2: 1.4.1 + slash: 3.0.0 - ansi-align@3.0.1: + globby@11.1.0: dependencies: - string-width: 4.2.3 + array-union: 2.1.0 + dir-glob: 3.0.1 + fast-glob: 3.3.3 + ignore: 5.3.2 + merge2: 1.4.1 + slash: 3.0.0 - ansi-colors@4.1.3: {} + globby@13.2.2: + dependencies: + dir-glob: 3.0.1 + fast-glob: 3.3.3 + ignore: 5.3.2 + merge2: 1.4.1 + slash: 4.0.0 - ansi-escapes@4.3.2: + gopd@1.2.0: {} + + got@12.6.1: dependencies: - type-fest: 0.21.3 + '@sindresorhus/is': 5.6.0 + '@szmarczak/http-timer': 5.0.1 + cacheable-lookup: 7.0.0 + cacheable-request: 10.2.14 + decompress-response: 6.0.0 + form-data-encoder: 2.1.4 + get-stream: 6.0.1 + http2-wrapper: 2.2.1 + lowercase-keys: 3.0.0 + p-cancelable: 3.0.0 + responselike: 3.0.0 - ansi-regex@3.0.1: {} + graceful-fs@4.2.10: {} - ansi-regex@5.0.1: {} + graceful-fs@4.2.11: {} - ansi-styles@3.2.1: + gray-matter@4.0.3: dependencies: - color-convert: 1.9.3 + js-yaml: 3.14.2 + kind-of: 6.0.3 + section-matter: 1.0.0 + strip-bom-string: 1.0.0 - ansi-styles@4.3.0: + gzip-size@6.0.0: dependencies: - color-convert: 2.0.1 + duplexer: 0.1.2 - antlr4ts@0.5.0-alpha.4: {} + h3@1.15.4: + dependencies: + cookie-es: 1.2.2 + crossws: 0.3.5 + defu: 6.1.4 + destr: 2.0.5 + iron-webcrypto: 1.2.1 + node-mock-http: 1.0.4 + radix3: 1.1.2 + ufo: 1.6.1 + uncrypto: 0.1.3 - any-promise@1.3.0: {} + handle-thing@2.0.1: {} - anymatch@3.1.3: + handlebars@4.7.8: dependencies: - normalize-path: 3.0.0 - picomatch: 2.3.1 + minimist: 1.2.8 + neo-async: 2.6.2 + source-map: 0.6.1 + wordwrap: 1.0.0 + optionalDependencies: + uglify-js: 3.19.3 - arg@4.1.3: {} + hardhat-dependency-compiler@1.2.1(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.6.3))(typescript@5.6.3)(utf-8-validate@5.0.10)): + dependencies: + hardhat: 2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.6.3))(typescript@5.6.3)(utf-8-validate@5.0.10) - arg@5.0.2: {} + hardhat-gas-reporter@1.0.10(bufferutil@4.0.9)(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.6.3))(typescript@5.6.3)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10): + dependencies: + array-uniq: 1.0.3 + eth-gas-reporter: 0.2.27(bufferutil@4.0.9)(utf-8-validate@5.0.10) + hardhat: 2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.6.3))(typescript@5.6.3)(utf-8-validate@5.0.10) + sha1: 1.1.1 + transitivePeerDependencies: + - '@codechecks/client' + - bufferutil + - debug + - utf-8-validate - argparse@1.0.10: + hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.6.3))(typescript@5.6.3)(utf-8-validate@5.0.10): dependencies: - sprintf-js: 1.0.3 + '@ethereumjs/util': 9.1.0 + '@ethersproject/abi': 5.8.0 + '@nomicfoundation/edr': 0.12.0-next.17 + '@nomicfoundation/solidity-analyzer': 0.1.2 + '@sentry/node': 5.30.0 + adm-zip: 0.4.16 + aggregate-error: 3.1.0 + ansi-escapes: 4.3.2 + boxen: 5.1.2 + chokidar: 4.0.3 + ci-info: 2.0.0 + debug: 4.4.3(supports-color@8.1.1) + enquirer: 2.4.1 + env-paths: 2.2.1 + ethereum-cryptography: 1.2.0 + find-up: 5.0.0 + fp-ts: 1.19.3 + fs-extra: 7.0.1 + immutable: 4.3.7 + io-ts: 1.10.4 + json-stream-stringify: 3.1.6 + keccak: 3.0.4 + lodash: 4.17.21 + micro-eth-signer: 0.14.0 + mnemonist: 0.38.5 + mocha: 10.8.2 + p-map: 4.0.0 + picocolors: 1.1.1 + raw-body: 2.5.3 + resolve: 1.17.0 + semver: 6.3.1 + solc: 0.8.26(debug@4.4.3) + source-map-support: 0.5.21 + stacktrace-parser: 0.1.11 + tinyglobby: 0.2.15 + tsort: 0.0.1 + undici: 5.29.0 + uuid: 8.3.2 + ws: 7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10) + optionalDependencies: + ts-node: 10.9.2(@types/node@22.7.5)(typescript@5.6.3) + typescript: 5.6.3 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate - argparse@2.0.1: {} + has-flag@1.0.0: {} - array-back@3.1.0: {} + has-flag@3.0.0: {} - array-back@4.0.2: {} + has-flag@4.0.0: {} - array-union@2.1.0: {} + has-property-descriptors@1.0.2: + dependencies: + es-define-property: 1.0.1 - array-uniq@1.0.3: {} + has-symbols@1.1.0: {} - asap@2.0.6: {} + has-tostringtag@1.0.2: + dependencies: + has-symbols: 1.1.0 - asn1js@3.0.7: + has-yarn@3.0.0: {} + + hash-base@3.1.2: dependencies: - pvtsutils: 1.3.6 - pvutils: 1.1.5 - tslib: 2.8.1 - optional: true + inherits: 2.0.4 + readable-stream: 2.3.8 + safe-buffer: 5.2.1 + to-buffer: 1.2.2 - assertion-error@1.1.0: {} + hash.js@1.1.7: + dependencies: + inherits: 2.0.4 + minimalistic-assert: 1.0.1 - assertion-error@2.0.1: {} + hasown@2.0.2: + dependencies: + function-bind: 1.1.2 - astral-regex@2.0.0: {} + hast-util-from-parse5@8.0.3: + dependencies: + '@types/hast': 3.0.4 + '@types/unist': 3.0.3 + devlop: 1.1.0 + hastscript: 9.0.1 + property-information: 7.1.0 + vfile: 6.0.3 + vfile-location: 5.0.3 + web-namespaces: 2.0.1 - async-mutex@0.2.6: + hast-util-parse-selector@4.0.0: dependencies: - tslib: 2.8.1 + '@types/hast': 3.0.4 - async-retry@1.3.3: + hast-util-raw@9.1.0: dependencies: - retry: 0.13.1 + '@types/hast': 3.0.4 + '@types/unist': 3.0.3 + '@ungap/structured-clone': 1.3.0 + hast-util-from-parse5: 8.0.3 + hast-util-to-parse5: 8.0.1 + html-void-elements: 3.0.0 + mdast-util-to-hast: 13.2.1 + parse5: 7.3.0 + unist-util-position: 5.0.0 + unist-util-visit: 5.0.0 + vfile: 6.0.3 + web-namespaces: 2.0.1 + zwitch: 2.0.4 - async@1.5.2: {} + hast-util-to-estree@3.1.3: + dependencies: + '@types/estree': 1.0.8 + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + comma-separated-tokens: 2.0.3 + devlop: 1.1.0 + estree-util-attach-comments: 3.0.0 + estree-util-is-identifier-name: 3.0.0 + hast-util-whitespace: 3.0.0 + mdast-util-mdx-expression: 2.0.1 + mdast-util-mdx-jsx: 3.2.0 + mdast-util-mdxjs-esm: 2.0.1 + property-information: 7.1.0 + space-separated-tokens: 2.0.2 + style-to-js: 1.1.21 + unist-util-position: 5.0.0 + zwitch: 2.0.4 + transitivePeerDependencies: + - supports-color - asynckit@0.4.0: {} + hast-util-to-jsx-runtime@2.3.6: + dependencies: + '@types/estree': 1.0.8 + '@types/hast': 3.0.4 + '@types/unist': 3.0.3 + comma-separated-tokens: 2.0.3 + devlop: 1.1.0 + estree-util-is-identifier-name: 3.0.0 + hast-util-whitespace: 3.0.0 + mdast-util-mdx-expression: 2.0.1 + mdast-util-mdx-jsx: 3.2.0 + mdast-util-mdxjs-esm: 2.0.1 + property-information: 7.1.0 + space-separated-tokens: 2.0.2 + style-to-js: 1.1.21 + unist-util-position: 5.0.0 + vfile-message: 4.0.3 + transitivePeerDependencies: + - supports-color - at-least-node@1.0.0: {} + hast-util-to-parse5@8.0.1: + dependencies: + '@types/hast': 3.0.4 + comma-separated-tokens: 2.0.3 + devlop: 1.1.0 + property-information: 7.1.0 + space-separated-tokens: 2.0.2 + web-namespaces: 2.0.1 + zwitch: 2.0.4 - atomic-sleep@1.0.0: {} + hast-util-whitespace@3.0.0: + dependencies: + '@types/hast': 3.0.4 - autoprefixer@10.4.23(postcss@8.5.6): + hastscript@9.0.1: dependencies: - browserslist: 4.28.1 - caniuse-lite: 1.0.30001760 - fraction.js: 5.3.4 - picocolors: 1.1.1 - postcss: 8.5.6 - postcss-value-parser: 4.2.0 + '@types/hast': 3.0.4 + comma-separated-tokens: 2.0.3 + hast-util-parse-selector: 4.0.0 + property-information: 7.1.0 + space-separated-tokens: 2.0.2 - available-typed-arrays@1.0.7: + he@1.2.0: {} + + heap@0.2.7: {} + + history@4.10.1: dependencies: - possible-typed-array-names: 1.1.0 + '@babel/runtime': 7.28.4 + loose-envify: 1.4.0 + resolve-pathname: 3.0.0 + tiny-invariant: 1.3.3 + tiny-warning: 1.0.3 + value-equal: 1.0.1 - axios-retry@4.5.0(axios@1.13.2): + hmac-drbg@1.0.1: dependencies: - axios: 1.13.2(debug@4.4.3) - is-retry-allowed: 2.2.0 + hash.js: 1.1.7 + minimalistic-assert: 1.0.1 + minimalistic-crypto-utils: 1.0.1 - axios@1.13.2(debug@4.4.3): + hoist-non-react-statics@3.3.2: dependencies: - follow-redirects: 1.15.11(debug@4.4.3) - form-data: 4.0.5 - proxy-from-env: 1.1.0 - transitivePeerDependencies: - - debug + react-is: 16.13.1 - balanced-match@1.0.2: {} + hono@4.11.1: {} - base-x@3.0.11: + hpack.js@2.1.6: dependencies: - safe-buffer: 5.2.1 + inherits: 2.0.4 + obuf: 1.1.2 + readable-stream: 2.3.8 + wbuf: 1.7.3 - base-x@5.0.1: {} + html-escaper@2.0.2: {} - base64-js@1.5.1: {} + html-minifier-terser@6.1.0: + dependencies: + camel-case: 4.1.2 + clean-css: 5.3.3 + commander: 8.3.0 + he: 1.2.0 + param-case: 3.0.4 + relateurl: 0.2.7 + terser: 5.46.0 - base64-sol@1.0.1: {} + html-minifier-terser@7.2.0: + dependencies: + camel-case: 4.1.2 + clean-css: 5.3.3 + commander: 10.0.1 + entities: 4.5.0 + param-case: 3.0.4 + relateurl: 0.2.7 + terser: 5.46.0 - baseline-browser-mapping@2.9.10: {} + html-tags@3.3.1: {} - bech32@1.1.4: {} + html-void-elements@3.0.0: {} - big.js@6.2.2: {} + html-webpack-plugin@5.6.6(webpack@5.104.1): + dependencies: + '@types/html-minifier-terser': 6.1.0 + html-minifier-terser: 6.1.0 + lodash: 4.17.21 + pretty-error: 4.0.0 + tapable: 2.3.0 + optionalDependencies: + webpack: 5.104.1 - bignumber.js@9.3.1: {} + htmlparser2@6.1.0: + dependencies: + domelementtype: 2.3.0 + domhandler: 4.3.1 + domutils: 2.8.0 + entities: 2.2.0 - binary-extensions@2.3.0: {} + htmlparser2@8.0.2: + dependencies: + domelementtype: 2.3.0 + domhandler: 5.0.3 + domutils: 3.2.2 + entities: 4.5.0 - blakejs@1.2.1: {} + http-basic@8.1.3: + dependencies: + caseless: 0.12.0 + concat-stream: 1.6.2 + http-response-object: 3.0.2 + parse-cache-control: 1.0.1 - bn.js@4.11.6: {} + http-cache-semantics@4.2.0: {} - bn.js@4.12.2: {} + http-deceiver@1.2.7: {} - bn.js@5.2.2: {} + http-errors@1.6.3: + dependencies: + depd: 1.1.2 + inherits: 2.0.3 + setprototypeof: 1.1.0 + statuses: 1.5.0 - borsh@0.7.0: + http-errors@2.0.1: dependencies: - bn.js: 5.2.2 - bs58: 4.0.1 - text-encoding-utf-8: 1.0.2 + depd: 2.0.0 + inherits: 2.0.4 + setprototypeof: 1.2.0 + statuses: 2.0.2 + toidentifier: 1.0.1 - bowser@2.13.1: {} + http-parser-js@0.5.10: {} - boxen@5.1.2: + http-proxy-middleware@2.0.9(@types/express@4.17.25): dependencies: - ansi-align: 3.0.1 - camelcase: 6.3.0 - chalk: 4.1.2 - cli-boxes: 2.2.1 - string-width: 4.2.3 - type-fest: 0.20.2 - widest-line: 3.1.0 - wrap-ansi: 7.0.0 + '@types/http-proxy': 1.17.17 + http-proxy: 1.18.1 + is-glob: 4.0.3 + is-plain-obj: 3.0.0 + micromatch: 4.0.8 + optionalDependencies: + '@types/express': 4.17.25 + transitivePeerDependencies: + - debug - brace-expansion@1.1.12: + http-proxy@1.18.1: dependencies: - balanced-match: 1.0.2 - concat-map: 0.0.1 + eventemitter3: 4.0.7 + follow-redirects: 1.15.11(debug@4.4.3) + requires-port: 1.0.0 + transitivePeerDependencies: + - debug - brace-expansion@2.0.2: + http-response-object@3.0.2: dependencies: - balanced-match: 1.0.2 + '@types/node': 10.17.60 - braces@3.0.3: + http2-wrapper@2.2.1: dependencies: - fill-range: 7.1.1 + quick-lru: 5.1.1 + resolve-alpn: 1.2.1 - brorand@1.1.0: {} + https-proxy-agent@5.0.1: + dependencies: + agent-base: 6.0.2 + debug: 4.4.3(supports-color@8.1.1) + transitivePeerDependencies: + - supports-color - browser-stdout@1.3.1: {} + human-signals@2.1.0: {} - browserify-aes@1.2.0: + humanize-ms@1.2.1: dependencies: - buffer-xor: 1.0.3 - cipher-base: 1.0.7 - create-hash: 1.2.0 - evp_bytestokey: 1.0.3 - inherits: 2.0.4 - safe-buffer: 5.2.1 + ms: 2.1.3 - browserslist@4.28.1: - dependencies: - baseline-browser-mapping: 2.9.10 - caniuse-lite: 1.0.30001760 - electron-to-chromium: 1.5.267 - node-releases: 2.0.27 - update-browserslist-db: 1.2.3(browserslist@4.28.1) + hyperdyperid@1.2.0: {} - bs58@4.0.1: + iconv-lite@0.4.24: dependencies: - base-x: 3.0.11 + safer-buffer: 2.1.2 - bs58@6.0.0: + icss-utils@5.1.0(postcss@8.5.6): dependencies: - base-x: 5.0.1 + postcss: 8.5.6 - bs58check@2.1.2: - dependencies: - bs58: 4.0.1 - create-hash: 1.2.0 - safe-buffer: 5.2.1 + idb-keyval@6.2.1: {} - buffer-from@1.1.2: {} + idb-keyval@6.2.2: {} - buffer-xor@1.0.3: {} + ieee754@1.2.1: {} - buffer@4.9.2: - dependencies: - base64-js: 1.5.1 - ieee754: 1.2.1 - isarray: 1.0.0 + ignore@5.3.2: {} - buffer@6.0.3: - dependencies: - base64-js: 1.5.1 - ieee754: 1.2.1 + image-size@2.0.2: {} - bufferutil@4.0.9: + immer@10.0.2: {} + + immutable@4.3.7: {} + + import-fresh@3.3.1: dependencies: - node-gyp-build: 4.8.4 + parent-module: 1.0.1 + resolve-from: 4.0.0 - bytes@3.1.2: {} + import-lazy@4.0.0: {} - cac@6.7.14: {} + imurmurhash@0.1.4: {} - call-bind-apply-helpers@1.0.2: - dependencies: - es-errors: 1.3.0 - function-bind: 1.1.2 + indent-string@4.0.0: {} - 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 + infima@0.2.0-alpha.45: {} - call-bound@1.0.4: + inflight@1.0.6: dependencies: - call-bind-apply-helpers: 1.0.2 - get-intrinsic: 1.3.0 + once: 1.4.0 + wrappy: 1.0.2 - camelcase-css@2.0.1: {} + inherits@2.0.3: {} - camelcase@5.3.1: {} + inherits@2.0.4: {} - camelcase@6.3.0: {} + ini@1.3.8: {} - caniuse-lite@1.0.30001760: {} + ini@2.0.0: {} - caseless@0.12.0: {} + inline-style-parser@0.2.7: {} - cbor@10.0.11: - dependencies: - nofilter: 3.1.0 + interpret@1.4.0: {} - cbor@8.1.0: + invariant@2.2.4: dependencies: - nofilter: 3.1.0 + loose-envify: 1.4.0 - cbor@9.0.2: + io-ts@1.10.4: dependencies: - nofilter: 3.1.0 + fp-ts: 1.19.3 - chai-as-promised@7.1.2(chai@4.5.0): - dependencies: - chai: 4.5.0 - check-error: 1.0.3 + ipaddr.js@1.9.1: {} - chai@4.5.0: - dependencies: - assertion-error: 1.1.0 - check-error: 1.0.3 - deep-eql: 4.1.4 - get-func-name: 2.0.2 - loupe: 2.3.7 - pathval: 1.1.1 - type-detect: 4.1.0 + ipaddr.js@2.3.0: {} - chai@5.3.3: - dependencies: - assertion-error: 2.0.1 - check-error: 2.1.1 - deep-eql: 5.0.2 - loupe: 3.2.1 - pathval: 2.0.1 + iron-webcrypto@1.2.1: {} - chalk@2.4.2: - dependencies: - ansi-styles: 3.2.1 - escape-string-regexp: 1.0.5 - supports-color: 5.5.0 + is-alphabetical@2.0.1: {} - chalk@4.1.2: + is-alphanumerical@2.0.1: dependencies: - ansi-styles: 4.3.0 - supports-color: 7.2.0 + is-alphabetical: 2.0.1 + is-decimal: 2.0.1 - chalk@5.6.2: {} + is-arguments@1.2.0: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 - charenc@0.0.2: {} + is-arrayish@0.2.1: {} - check-error@1.0.3: + is-binary-path@2.1.0: dependencies: - get-func-name: 2.0.2 + binary-extensions: 2.3.0 - check-error@2.1.1: {} + is-buffer@1.1.6: {} - chokidar@3.6.0: - dependencies: - anymatch: 3.1.3 - braces: 3.0.3 - glob-parent: 5.1.2 - is-binary-path: 2.1.0 - is-glob: 4.0.3 - normalize-path: 3.0.0 - readdirp: 3.6.0 - optionalDependencies: - fsevents: 2.3.3 + is-callable@1.2.7: {} - chokidar@4.0.3: + is-ci@3.0.1: dependencies: - readdirp: 4.1.2 + ci-info: 3.9.0 - ci-info@2.0.0: {} - - cipher-base@1.0.7: + is-core-module@2.16.1: dependencies: - inherits: 2.0.4 - safe-buffer: 5.2.1 - to-buffer: 1.2.2 + hasown: 2.0.2 - clean-stack@2.2.0: {} + is-decimal@2.0.1: {} - cli-boxes@2.2.1: {} + is-docker@2.2.1: {} - cli-table3@0.5.1: - dependencies: - object-assign: 4.1.1 - string-width: 2.1.1 - optionalDependencies: - colors: 1.4.0 + is-docker@3.0.0: {} - cliui@6.0.0: - dependencies: - string-width: 4.2.3 - strip-ansi: 6.0.1 - wrap-ansi: 6.2.0 + is-extendable@0.1.1: {} - cliui@7.0.4: - dependencies: - string-width: 4.2.3 - strip-ansi: 6.0.1 - wrap-ansi: 7.0.0 + is-extglob@2.1.1: {} - clsx@1.2.1: {} + is-fullwidth-code-point@2.0.0: {} - clsx@2.1.1: {} + is-fullwidth-code-point@3.0.0: {} - color-convert@1.9.3: + is-generator-function@1.1.2: dependencies: - color-name: 1.1.3 + 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 - color-convert@2.0.1: + is-glob@4.0.3: dependencies: - color-name: 1.1.4 + is-extglob: 2.1.1 - color-name@1.1.3: {} + is-hex-prefixed@1.0.0: {} - color-name@1.1.4: {} + is-hexadecimal@2.0.1: {} - colors@1.4.0: {} + is-inside-container@1.0.0: + dependencies: + is-docker: 3.0.0 - combined-stream@1.0.8: + is-installed-globally@0.4.0: dependencies: - delayed-stream: 1.0.0 + global-dirs: 3.0.1 + is-path-inside: 3.0.3 - command-exists@1.2.9: {} + is-network-error@1.3.0: {} - command-line-args@5.2.1: - dependencies: - array-back: 3.1.0 - find-replace: 3.0.0 - lodash.camelcase: 4.3.0 - typical: 4.0.0 + is-npm@6.1.0: {} - command-line-usage@6.1.3: - dependencies: - array-back: 4.0.2 - chalk: 2.4.2 - table-layout: 1.0.2 - typical: 5.2.0 + is-number@7.0.0: {} - commander@14.0.0: {} + is-obj@1.0.1: {} - commander@14.0.2: {} + is-obj@2.0.0: {} - commander@2.20.3: {} + is-path-inside@3.0.3: {} - commander@4.1.1: {} + is-plain-obj@2.1.0: {} - commander@8.3.0: {} + is-plain-obj@3.0.0: {} - compare-versions@6.1.1: {} + is-plain-obj@4.1.0: {} - concat-map@0.0.1: {} + is-plain-object@2.0.4: + dependencies: + isobject: 3.0.1 - concat-stream@1.6.2: + is-regex@1.2.1: dependencies: - buffer-from: 1.1.2 - inherits: 2.0.4 - readable-stream: 2.3.8 - typedarray: 0.0.6 + call-bound: 1.0.4 + gopd: 1.2.0 + has-tostringtag: 1.0.2 + hasown: 2.0.2 - convert-source-map@2.0.0: {} + is-regexp@1.0.0: {} - cookie-es@1.2.2: {} + is-retry-allowed@2.2.0: {} - cookie@0.4.2: {} + is-stream@2.0.1: {} - core-util-is@1.0.3: {} + is-typed-array@1.1.15: + dependencies: + which-typed-array: 1.1.19 - crc-32@1.2.2: {} + is-typedarray@1.0.0: {} - create-hash@1.2.0: - dependencies: - cipher-base: 1.0.7 - inherits: 2.0.4 - md5.js: 1.3.5 - ripemd160: 2.0.3 - sha.js: 2.4.12 + is-unicode-supported@0.1.0: {} - create-hmac@1.1.7: + is-wsl@2.2.0: dependencies: - cipher-base: 1.0.7 - create-hash: 1.2.0 - inherits: 2.0.4 - ripemd160: 2.0.3 - safe-buffer: 5.2.1 - sha.js: 2.4.12 + is-docker: 2.2.1 - create-require@1.1.1: {} - - cross-fetch@3.2.0: + is-wsl@3.1.0: dependencies: - node-fetch: 2.7.0 - transitivePeerDependencies: - - encoding + is-inside-container: 1.0.0 - cross-fetch@4.1.0: + is-yarn-global@0.4.1: {} + + isarray@0.0.1: {} + + isarray@1.0.0: {} + + isarray@2.0.5: {} + + isexe@2.0.0: {} + + isobject@3.0.1: {} + + isomorphic-unfetch@3.1.0: dependencies: node-fetch: 2.7.0 + unfetch: 4.2.0 transitivePeerDependencies: - encoding - crossws@0.3.5: + isomorphic-ws@4.0.1(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10)): dependencies: - uncrypto: 0.1.3 - - crypt@0.0.2: {} + ws: 7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10) - css-what@6.2.2: {} + isows@1.0.6(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)): + dependencies: + ws: 8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) - cssesc@3.0.0: {} + isows@1.0.7(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)): + dependencies: + ws: 8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10) - csstype@3.2.3: {} + jayson@4.2.0(bufferutil@4.0.9)(utf-8-validate@5.0.10): + dependencies: + '@types/connect': 3.4.38 + '@types/node': 12.20.55 + '@types/ws': 7.4.7 + commander: 2.20.3 + delay: 5.0.0 + es6-promisify: 5.0.0 + eyes: 0.1.8 + isomorphic-ws: 4.0.1(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + json-stringify-safe: 5.0.1 + stream-json: 1.9.1 + uuid: 8.3.2 + ws: 7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10) + transitivePeerDependencies: + - bufferutil + - utf-8-validate - cuer@0.0.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3): + jest-util@29.7.0: dependencies: - qr: 0.5.3 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - optionalDependencies: - typescript: 5.9.3 + '@jest/types': 29.6.3 + '@types/node': 20.19.27 + chalk: 4.1.2 + ci-info: 3.9.0 + graceful-fs: 4.2.11 + picomatch: 2.3.1 - date-fns@2.30.0: + jest-worker@27.5.1: dependencies: - '@babel/runtime': 7.28.4 + '@types/node': 20.19.27 + merge-stream: 2.0.0 + supports-color: 8.1.1 - dayjs@1.11.13: {} + jest-worker@29.7.0: + dependencies: + '@types/node': 20.19.27 + jest-util: 29.7.0 + merge-stream: 2.0.0 + supports-color: 8.1.1 - death@1.1.0: {} + jiti@1.21.7: {} - debug@4.3.4: + joi@17.13.3: dependencies: - ms: 2.1.2 + '@hapi/hoek': 9.3.0 + '@hapi/topo': 5.1.0 + '@sideway/address': 4.1.5 + '@sideway/formula': 3.0.1 + '@sideway/pinpoint': 2.0.0 - debug@4.4.3(supports-color@8.1.1): - dependencies: - ms: 2.1.3 - optionalDependencies: - supports-color: 8.1.1 + jose@6.1.3: {} - decamelize@1.2.0: {} + js-cookie@2.2.1: {} - decamelize@4.0.0: {} + js-sha3@0.8.0: {} - decode-uri-component@0.2.2: {} + js-tokens@4.0.0: {} - dedent@1.7.1: {} + js-tokens@9.0.1: {} - deep-eql@4.1.4: + js-yaml@3.14.2: dependencies: - type-detect: 4.1.0 - - deep-eql@5.0.2: {} + argparse: 1.0.10 + esprima: 4.0.1 - deep-extend@0.6.0: {} + js-yaml@4.1.1: + dependencies: + argparse: 2.0.1 - deep-is@0.1.4: {} + jsesc@3.1.0: {} - deep-object-diff@1.1.9: {} + json-buffer@3.0.1: {} - deepmerge@4.3.1: {} + json-parse-even-better-errors@2.3.1: {} - define-data-property@1.1.4: + json-rpc-engine@6.1.0: dependencies: - es-define-property: 1.0.1 - es-errors: 1.3.0 - gopd: 1.2.0 + '@metamask/safe-event-emitter': 2.0.0 + eth-rpc-errors: 4.0.3 - defu@6.1.4: {} + json-rpc-random-id@1.0.1: {} - delay@5.0.0: {} + json-schema-traverse@0.4.1: {} - delayed-stream@1.0.0: {} + json-schema-traverse@1.0.0: {} - depd@2.0.0: {} + json-stream-stringify@3.1.6: {} - derive-valtio@0.1.0(valtio@1.13.2(@types/react@18.3.27)(react@18.3.1)): + json-stringify-safe@5.0.1: {} + + json5@2.2.3: {} + + jsonfile@4.0.0: + optionalDependencies: + graceful-fs: 4.2.11 + + jsonfile@6.2.0: dependencies: - valtio: 1.13.2(@types/react@18.3.27)(react@18.3.1) + universalify: 2.0.1 + optionalDependencies: + graceful-fs: 4.2.11 - destr@2.0.5: {} + jsonschema@1.5.0: {} - detect-browser@5.3.0: {} + keccak@3.0.4: + dependencies: + node-addon-api: 2.0.2 + node-gyp-build: 4.8.4 + readable-stream: 3.6.2 - detect-node-es@1.1.0: {} + keyv@4.5.4: + dependencies: + json-buffer: 3.0.1 - dexie@4.2.1: {} + keyvaluestorage-interface@1.0.0: {} - didyoumean@1.2.2: {} + kind-of@6.0.3: {} - diff@4.0.2: {} + kleur@3.0.3: {} - diff@5.2.0: {} + latest-version@7.0.0: + dependencies: + package-json: 8.1.1 - difflib@0.2.4: + launch-editor@2.12.0: dependencies: - heap: 0.2.7 + picocolors: 1.1.1 + shell-quote: 1.8.3 - dijkstrajs@1.0.3: {} + leven@3.1.0: {} - dir-glob@3.0.1: + levn@0.3.0: dependencies: - path-type: 4.0.0 + prelude-ls: 1.1.2 + type-check: 0.3.2 - dlv@1.1.3: {} + lilconfig@3.1.3: {} - dotenv@16.6.1: {} + lines-and-columns@1.2.4: {} - dunder-proto@1.0.1: + lit-element@4.2.1: dependencies: - call-bind-apply-helpers: 1.0.2 - es-errors: 1.3.0 - gopd: 1.2.0 + '@lit-labs/ssr-dom-shim': 1.4.0 + '@lit/reactive-element': 2.1.1 + lit-html: 3.3.1 - duplexify@4.1.3: + lit-html@3.3.1: dependencies: - end-of-stream: 1.4.5 - inherits: 2.0.4 - readable-stream: 3.6.2 - stream-shift: 1.0.3 + '@types/trusted-types': 2.0.7 - eciesjs@0.4.16: + lit@3.3.0: 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 + '@lit/reactive-element': 2.1.1 + lit-element: 4.2.1 + lit-html: 3.3.1 - electron-to-chromium@1.5.267: {} + loader-runner@4.3.1: {} - elliptic@6.6.1: + loader-utils@2.0.4: dependencies: - bn.js: 4.12.2 - brorand: 1.1.0 - hash.js: 1.1.7 - hmac-drbg: 1.0.1 - inherits: 2.0.4 - minimalistic-assert: 1.0.1 - minimalistic-crypto-utils: 1.0.1 - - emoji-regex@8.0.0: {} + big.js: 5.2.2 + emojis-list: 3.0.0 + json5: 2.2.3 - encode-utf8@1.0.3: {} + locate-path@5.0.0: + dependencies: + p-locate: 4.1.0 - end-of-stream@1.4.5: + locate-path@6.0.0: dependencies: - once: 1.4.0 + p-locate: 5.0.0 - engine.io-client@6.6.3(bufferutil@4.0.9)(utf-8-validate@5.0.10): + locate-path@7.2.0: dependencies: - '@socket.io/component-emitter': 3.1.2 - debug: 4.3.4 - engine.io-parser: 5.2.3 - ws: 8.17.1(bufferutil@4.0.9)(utf-8-validate@5.0.10) - xmlhttprequest-ssl: 2.1.2 - transitivePeerDependencies: - - bufferutil - - supports-color - - utf-8-validate + p-locate: 6.0.0 - engine.io-parser@5.2.3: {} + lodash.camelcase@4.3.0: {} - enquirer@2.4.1: + lodash.clonedeep@4.5.0: {} + + lodash.debounce@4.0.8: {} + + lodash.isequal@4.5.0: {} + + lodash.memoize@4.1.2: {} + + lodash.truncate@4.4.2: {} + + lodash.uniq@4.5.0: {} + + lodash@4.17.21: {} + + log-symbols@4.1.0: dependencies: - ansi-colors: 4.1.3 - strip-ansi: 6.0.1 + chalk: 4.1.2 + is-unicode-supported: 0.1.0 - env-paths@2.2.1: {} + longest-streak@3.1.0: {} - es-define-property@1.0.1: {} + loose-envify@1.4.0: + dependencies: + js-tokens: 4.0.0 - es-errors@1.3.0: {} + loupe@2.3.7: + dependencies: + get-func-name: 2.0.2 - es-module-lexer@1.7.0: {} + loupe@3.2.1: {} - es-object-atoms@1.1.1: + lower-case@2.0.2: dependencies: - es-errors: 1.3.0 + tslib: 2.8.1 + + lowercase-keys@3.0.0: {} + + lru-cache@10.4.3: {} - es-set-tostringtag@2.1.0: + lru-cache@5.1.1: 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: {} + yallist: 3.1.1 - es6-promise@4.2.8: {} + lru_map@0.3.3: {} - es6-promisify@5.0.0: + lucide-react@0.525.0(react@18.3.1): dependencies: - es6-promise: 4.2.8 + react: 18.3.1 - esbuild@0.21.5: - optionalDependencies: - '@esbuild/aix-ppc64': 0.21.5 - '@esbuild/android-arm': 0.21.5 - '@esbuild/android-arm64': 0.21.5 - '@esbuild/android-x64': 0.21.5 - '@esbuild/darwin-arm64': 0.21.5 - '@esbuild/darwin-x64': 0.21.5 - '@esbuild/freebsd-arm64': 0.21.5 - '@esbuild/freebsd-x64': 0.21.5 - '@esbuild/linux-arm': 0.21.5 - '@esbuild/linux-arm64': 0.21.5 - '@esbuild/linux-ia32': 0.21.5 - '@esbuild/linux-loong64': 0.21.5 - '@esbuild/linux-mips64el': 0.21.5 - '@esbuild/linux-ppc64': 0.21.5 - '@esbuild/linux-riscv64': 0.21.5 - '@esbuild/linux-s390x': 0.21.5 - '@esbuild/linux-x64': 0.21.5 - '@esbuild/netbsd-x64': 0.21.5 - '@esbuild/openbsd-x64': 0.21.5 - '@esbuild/sunos-x64': 0.21.5 - '@esbuild/win32-arm64': 0.21.5 - '@esbuild/win32-ia32': 0.21.5 - '@esbuild/win32-x64': 0.21.5 + magic-string@0.30.21: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 - escalade@3.2.0: {} + make-error@1.3.6: {} - escape-string-regexp@1.0.5: {} + markdown-extensions@2.0.0: {} - escape-string-regexp@4.0.0: {} + markdown-table@1.1.3: {} - escodegen@1.8.1: + markdown-table@2.0.0: dependencies: - esprima: 2.7.3 - estraverse: 1.9.3 - esutils: 2.0.3 - optionator: 0.8.3 - optionalDependencies: - source-map: 0.2.0 + repeat-string: 1.6.1 - esprima@2.7.3: {} + markdown-table@3.0.4: {} - esprima@4.0.1: {} + math-intrinsics@1.1.0: {} - estraverse@1.9.3: {} + md5.js@1.3.5: + dependencies: + hash-base: 3.1.2 + inherits: 2.0.4 + safe-buffer: 5.2.1 - estree-walker@3.0.3: + md5@2.3.0: dependencies: - '@types/estree': 1.0.8 + charenc: 0.0.2 + crypt: 0.0.2 + is-buffer: 1.1.6 - esutils@2.0.3: {} + mdast-util-directive@3.1.0: + dependencies: + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + ccount: 2.0.1 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + parse-entities: 4.0.2 + stringify-entities: 4.0.4 + unist-util-visit-parents: 6.0.2 + transitivePeerDependencies: + - supports-color - 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 + mdast-util-find-and-replace@3.0.2: + dependencies: + '@types/mdast': 4.0.4 + escape-string-regexp: 5.0.0 + unist-util-is: 6.0.1 + unist-util-visit-parents: 6.0.2 + + mdast-util-from-markdown@2.0.2: + dependencies: + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + decode-named-character-reference: 1.3.0 + devlop: 1.1.0 + mdast-util-to-string: 4.0.0 + micromark: 4.0.2 + micromark-util-decode-numeric-character-reference: 2.0.2 + micromark-util-decode-string: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + unist-util-stringify-position: 4.0.0 transitivePeerDependencies: - supports-color - eth-gas-reporter@0.2.27(bufferutil@4.0.9)(utf-8-validate@5.0.10): + mdast-util-frontmatter@2.0.1: dependencies: - '@solidity-parser/parser': 0.14.5 - axios: 1.13.2(debug@4.4.3) - cli-table3: 0.5.1 - colors: 1.4.0 - ethereum-cryptography: 1.2.0 - ethers: 5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) - fs-readdir-recursive: 1.1.0 - lodash: 4.17.21 - markdown-table: 1.1.3 - mocha: 10.8.2 - req-cwd: 2.0.0 - sha1: 1.1.1 - sync-request: 6.1.0 + '@types/mdast': 4.0.4 + devlop: 1.1.0 + escape-string-regexp: 5.0.0 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + micromark-extension-frontmatter: 2.0.0 transitivePeerDependencies: - - bufferutil - - debug - - utf-8-validate + - supports-color - eth-json-rpc-filters@6.0.1: + mdast-util-gfm-autolink-literal@2.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 + '@types/mdast': 4.0.4 + ccount: 2.0.1 + devlop: 1.1.0 + mdast-util-find-and-replace: 3.0.2 + micromark-util-character: 2.1.1 - eth-query@2.1.2: + mdast-util-gfm-footnote@2.1.0: dependencies: - json-rpc-random-id: 1.0.1 - xtend: 4.0.2 + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + micromark-util-normalize-identifier: 2.0.1 + transitivePeerDependencies: + - supports-color - eth-rpc-errors@4.0.3: + mdast-util-gfm-strikethrough@2.0.0: dependencies: - fast-safe-stringify: 2.1.1 + '@types/mdast': 4.0.4 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color - ethereum-bloom-filters@1.2.0: + mdast-util-gfm-table@2.0.0: dependencies: - '@noble/hashes': 1.8.0 + '@types/mdast': 4.0.4 + devlop: 1.1.0 + markdown-table: 3.0.4 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color - ethereum-cryptography@0.1.3: + mdast-util-gfm-task-list-item@2.0.0: dependencies: - '@types/pbkdf2': 3.1.2 - '@types/secp256k1': 4.0.7 - blakejs: 1.2.1 - browserify-aes: 1.2.0 - bs58check: 2.1.2 - create-hash: 1.2.0 - create-hmac: 1.1.7 - hash.js: 1.1.7 - keccak: 3.0.4 - pbkdf2: 3.1.5 - randombytes: 2.1.0 - safe-buffer: 5.2.1 - scrypt-js: 3.0.1 - secp256k1: 4.0.4 - setimmediate: 1.0.5 + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color - ethereum-cryptography@1.2.0: + mdast-util-gfm@3.1.0: dependencies: - '@noble/hashes': 1.2.0 - '@noble/secp256k1': 1.7.1 - '@scure/bip32': 1.1.5 - '@scure/bip39': 1.1.1 + mdast-util-from-markdown: 2.0.2 + mdast-util-gfm-autolink-literal: 2.0.1 + mdast-util-gfm-footnote: 2.1.0 + mdast-util-gfm-strikethrough: 2.0.0 + mdast-util-gfm-table: 2.0.0 + mdast-util-gfm-task-list-item: 2.0.0 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color - ethereum-cryptography@2.2.1: + mdast-util-mdx-expression@2.0.1: dependencies: - '@noble/curves': 1.4.2 - '@noble/hashes': 1.4.0 - '@scure/bip32': 1.4.0 - '@scure/bip39': 1.3.0 + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color - ethereumjs-util@7.1.5: - dependencies: - '@types/bn.js': 5.2.0 - bn.js: 5.2.2 - create-hash: 1.2.0 - ethereum-cryptography: 0.1.3 - rlp: 2.2.7 + mdast-util-mdx-jsx@3.2.0: + dependencies: + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + ccount: 2.0.1 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + parse-entities: 4.0.2 + stringify-entities: 4.0.4 + unist-util-stringify-position: 4.0.0 + vfile-message: 4.0.3 + transitivePeerDependencies: + - supports-color - ethers@5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10): + mdast-util-mdx@3.0.0: dependencies: - '@ethersproject/abi': 5.8.0 - '@ethersproject/abstract-provider': 5.8.0 - '@ethersproject/abstract-signer': 5.8.0 - '@ethersproject/address': 5.8.0 - '@ethersproject/base64': 5.8.0 - '@ethersproject/basex': 5.8.0 - '@ethersproject/bignumber': 5.8.0 - '@ethersproject/bytes': 5.8.0 - '@ethersproject/constants': 5.8.0 - '@ethersproject/contracts': 5.8.0 - '@ethersproject/hash': 5.8.0 - '@ethersproject/hdnode': 5.8.0 - '@ethersproject/json-wallets': 5.8.0 - '@ethersproject/keccak256': 5.8.0 - '@ethersproject/logger': 5.8.0 - '@ethersproject/networks': 5.8.0 - '@ethersproject/pbkdf2': 5.8.0 - '@ethersproject/properties': 5.8.0 - '@ethersproject/providers': 5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) - '@ethersproject/random': 5.8.0 - '@ethersproject/rlp': 5.8.0 - '@ethersproject/sha2': 5.8.0 - '@ethersproject/signing-key': 5.8.0 - '@ethersproject/solidity': 5.8.0 - '@ethersproject/strings': 5.8.0 - '@ethersproject/transactions': 5.8.0 - '@ethersproject/units': 5.8.0 - '@ethersproject/wallet': 5.8.0 - '@ethersproject/web': 5.8.0 - '@ethersproject/wordlists': 5.8.0 + mdast-util-from-markdown: 2.0.2 + mdast-util-mdx-expression: 2.0.1 + mdast-util-mdx-jsx: 3.2.0 + mdast-util-mdxjs-esm: 2.0.1 + mdast-util-to-markdown: 2.1.2 transitivePeerDependencies: - - bufferutil - - utf-8-validate + - supports-color - ethers@6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10): + mdast-util-mdxjs-esm@2.0.1: dependencies: - '@adraffy/ens-normalize': 1.10.1 - '@noble/curves': 1.2.0 - '@noble/hashes': 1.3.2 - '@types/node': 22.7.5 - aes-js: 4.0.0-beta.5 - tslib: 2.7.0 - ws: 8.17.1(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 transitivePeerDependencies: - - bufferutil - - utf-8-validate + - supports-color - ethjs-unit@0.1.6: + mdast-util-phrasing@4.1.0: dependencies: - bn.js: 4.11.6 - number-to-bn: 1.7.0 - - eventemitter2@6.4.9: {} + '@types/mdast': 4.0.4 + unist-util-is: 6.0.1 - eventemitter3@5.0.1: {} - - events@3.3.0: {} - - evp_bytestokey@1.0.3: + mdast-util-to-hast@13.2.1: dependencies: - md5.js: 1.3.5 - safe-buffer: 5.2.1 - - expect-type@1.3.0: {} + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + '@ungap/structured-clone': 1.3.0 + devlop: 1.1.0 + micromark-util-sanitize-uri: 2.0.1 + trim-lines: 3.0.1 + unist-util-position: 5.0.0 + unist-util-visit: 5.0.0 + vfile: 6.0.3 - extension-port-stream@3.0.0: + mdast-util-to-markdown@2.1.2: dependencies: - readable-stream: 3.6.2 - webextension-polyfill: 0.10.0 + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + longest-streak: 3.1.0 + mdast-util-phrasing: 4.1.0 + mdast-util-to-string: 4.0.0 + micromark-util-classify-character: 2.0.1 + micromark-util-decode-string: 2.0.1 + unist-util-visit: 5.0.0 + zwitch: 2.0.4 - eyes@0.1.8: {} + mdast-util-to-string@4.0.0: + dependencies: + '@types/mdast': 4.0.4 - fast-base64-decode@1.0.0: {} + mdn-data@2.0.28: {} - fast-deep-equal@3.1.3: {} + mdn-data@2.0.30: {} - fast-glob@3.3.3: + media-query-parser@2.0.2: dependencies: - '@nodelib/fs.stat': 2.0.5 - '@nodelib/fs.walk': 1.2.8 - glob-parent: 5.1.2 - merge2: 1.4.1 - micromatch: 4.0.8 - - fast-levenshtein@2.0.6: {} + '@babel/runtime': 7.28.4 - fast-redact@3.5.0: {} + media-typer@0.3.0: {} + + memfs@4.56.4(tslib@2.8.1): + dependencies: + '@jsonjoy.com/fs-core': 4.56.4(tslib@2.8.1) + '@jsonjoy.com/fs-fsa': 4.56.4(tslib@2.8.1) + '@jsonjoy.com/fs-node': 4.56.4(tslib@2.8.1) + '@jsonjoy.com/fs-node-builtins': 4.56.4(tslib@2.8.1) + '@jsonjoy.com/fs-node-to-fsa': 4.56.4(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.56.4(tslib@2.8.1) + '@jsonjoy.com/fs-print': 4.56.4(tslib@2.8.1) + '@jsonjoy.com/fs-snapshot': 4.56.4(tslib@2.8.1) + '@jsonjoy.com/json-pack': 1.21.0(tslib@2.8.1) + '@jsonjoy.com/util': 1.9.0(tslib@2.8.1) + glob-to-regex.js: 1.2.0(tslib@2.8.1) + thingies: 2.5.0(tslib@2.8.1) + tree-dump: 1.1.0(tslib@2.8.1) + tslib: 2.8.1 - fast-safe-stringify@2.1.1: {} + memorystream@0.3.1: {} - fast-stable-stringify@1.0.0: {} + merge-descriptors@1.0.3: {} - fast-uri@3.1.0: {} + merge-stream@2.0.0: {} - fast-xml-parser@5.2.5: - dependencies: - strnum: 2.1.2 + merge2@1.4.1: {} - fastestsmallesttextencoderdecoder@1.0.22: {} + methods@1.1.2: {} - fastq@1.19.1: + micro-eth-signer@0.14.0: dependencies: - reusify: 1.1.0 + '@noble/curves': 1.8.2 + '@noble/hashes': 1.7.2 + micro-packed: 0.7.3 - fdir@6.5.0(picomatch@4.0.3): - optionalDependencies: - picomatch: 4.0.3 + micro-ftch@0.3.1: {} + + micro-packed@0.7.3: + dependencies: + '@scure/base': 1.2.6 - fill-range@7.1.1: + micromark-core-commonmark@2.0.3: + dependencies: + decode-named-character-reference: 1.3.0 + devlop: 1.1.0 + micromark-factory-destination: 2.0.1 + micromark-factory-label: 2.0.1 + micromark-factory-space: 2.0.1 + micromark-factory-title: 2.0.1 + micromark-factory-whitespace: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-chunked: 2.0.1 + micromark-util-classify-character: 2.0.1 + micromark-util-html-tag-name: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-subtokenize: 2.1.0 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-directive@3.0.2: + dependencies: + devlop: 1.1.0 + micromark-factory-space: 2.0.1 + micromark-factory-whitespace: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + parse-entities: 4.0.2 + + micromark-extension-frontmatter@2.0.0: + dependencies: + fault: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-autolink-literal@2.1.0: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-sanitize-uri: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-footnote@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-core-commonmark: 2.0.3 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-sanitize-uri: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-strikethrough@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-util-chunked: 2.0.1 + micromark-util-classify-character: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-table@2.1.1: + dependencies: + devlop: 1.1.0 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-tagfilter@2.0.0: + dependencies: + micromark-util-types: 2.0.2 + + micromark-extension-gfm-task-list-item@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm@3.0.0: + dependencies: + micromark-extension-gfm-autolink-literal: 2.1.0 + micromark-extension-gfm-footnote: 2.1.0 + micromark-extension-gfm-strikethrough: 2.1.0 + micromark-extension-gfm-table: 2.1.1 + micromark-extension-gfm-tagfilter: 2.0.0 + micromark-extension-gfm-task-list-item: 2.1.0 + micromark-util-combine-extensions: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-mdx-expression@3.0.1: dependencies: - to-regex-range: 5.0.1 + '@types/estree': 1.0.8 + devlop: 1.1.0 + micromark-factory-mdx-expression: 2.0.3 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-events-to-acorn: 2.0.3 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 - filter-obj@1.1.0: {} + micromark-extension-mdx-jsx@3.0.2: + dependencies: + '@types/estree': 1.0.8 + devlop: 1.1.0 + estree-util-is-identifier-name: 3.0.0 + micromark-factory-mdx-expression: 2.0.3 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-events-to-acorn: 2.0.3 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + vfile-message: 4.0.3 - find-replace@3.0.0: + micromark-extension-mdx-md@2.0.0: dependencies: - array-back: 3.1.0 + micromark-util-types: 2.0.2 - find-up@4.1.0: + micromark-extension-mdxjs-esm@3.0.0: dependencies: - locate-path: 5.0.0 - path-exists: 4.0.0 + '@types/estree': 1.0.8 + devlop: 1.1.0 + micromark-core-commonmark: 2.0.3 + micromark-util-character: 2.1.1 + micromark-util-events-to-acorn: 2.0.3 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + unist-util-position-from-estree: 2.0.0 + vfile-message: 4.0.3 - find-up@5.0.0: + micromark-extension-mdxjs@3.0.0: dependencies: - locate-path: 6.0.0 - path-exists: 4.0.0 + acorn: 8.15.0 + acorn-jsx: 5.3.2(acorn@8.15.0) + micromark-extension-mdx-expression: 3.0.1 + micromark-extension-mdx-jsx: 3.0.2 + micromark-extension-mdx-md: 2.0.0 + micromark-extension-mdxjs-esm: 3.0.0 + micromark-util-combine-extensions: 2.0.1 + micromark-util-types: 2.0.2 - flat@5.0.2: {} + micromark-factory-destination@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 - follow-redirects@1.15.11(debug@4.4.3): - optionalDependencies: - debug: 4.4.3(supports-color@8.1.1) + micromark-factory-label@2.0.1: + dependencies: + devlop: 1.1.0 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 - for-each@0.3.5: + micromark-factory-mdx-expression@2.0.3: dependencies: - is-callable: 1.2.7 + '@types/estree': 1.0.8 + devlop: 1.1.0 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-events-to-acorn: 2.0.3 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + unist-util-position-from-estree: 2.0.0 + vfile-message: 4.0.3 - form-data@2.5.5: + micromark-factory-space@1.1.0: 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 - safe-buffer: 5.2.1 + micromark-util-character: 1.2.0 + micromark-util-types: 1.1.0 - form-data@4.0.5: + micromark-factory-space@2.0.1: 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 + micromark-util-character: 2.1.1 + micromark-util-types: 2.0.2 - fp-ts@1.19.3: {} + micromark-factory-title@2.0.1: + dependencies: + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 - fraction.js@5.3.4: {} + micromark-factory-whitespace@2.0.1: + dependencies: + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 - framer-motion@12.23.26(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + micromark-util-character@1.2.0: dependencies: - motion-dom: 12.23.23 - motion-utils: 12.23.6 - tslib: 2.8.1 - optionalDependencies: - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) + micromark-util-symbol: 1.1.0 + micromark-util-types: 1.1.0 - fs-extra@10.1.0: + micromark-util-character@2.1.1: dependencies: - graceful-fs: 4.2.11 - jsonfile: 6.2.0 - universalify: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 - fs-extra@7.0.1: + micromark-util-chunked@2.0.1: dependencies: - graceful-fs: 4.2.11 - jsonfile: 4.0.0 - universalify: 0.1.2 + micromark-util-symbol: 2.0.1 - fs-extra@8.1.0: + micromark-util-classify-character@2.0.1: dependencies: - graceful-fs: 4.2.11 - jsonfile: 4.0.0 - universalify: 0.1.2 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 - fs-extra@9.1.0: + micromark-util-combine-extensions@2.0.1: dependencies: - at-least-node: 1.0.0 - graceful-fs: 4.2.11 - jsonfile: 6.2.0 - universalify: 2.0.1 + micromark-util-chunked: 2.0.1 + micromark-util-types: 2.0.2 - fs-readdir-recursive@1.1.0: {} + micromark-util-decode-numeric-character-reference@2.0.2: + dependencies: + micromark-util-symbol: 2.0.1 - fs.realpath@1.0.0: {} + micromark-util-decode-string@2.0.1: + dependencies: + decode-named-character-reference: 1.3.0 + micromark-util-character: 2.1.1 + micromark-util-decode-numeric-character-reference: 2.0.2 + micromark-util-symbol: 2.0.1 - fsevents@2.3.3: - optional: true + micromark-util-encode@2.0.1: {} - function-bind@1.1.2: {} + micromark-util-events-to-acorn@2.0.3: + dependencies: + '@types/estree': 1.0.8 + '@types/unist': 3.0.3 + devlop: 1.1.0 + estree-util-visit: 2.0.0 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + vfile-message: 4.0.3 - generator-function@2.0.1: {} + micromark-util-html-tag-name@2.0.1: {} - gensync@1.0.0-beta.2: {} + micromark-util-normalize-identifier@2.0.1: + dependencies: + micromark-util-symbol: 2.0.1 - get-caller-file@2.0.5: {} + micromark-util-resolve-all@2.0.1: + dependencies: + micromark-util-types: 2.0.2 - get-func-name@2.0.2: {} + micromark-util-sanitize-uri@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-encode: 2.0.1 + micromark-util-symbol: 2.0.1 - get-intrinsic@1.3.0: + micromark-util-subtokenize@2.1.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 + devlop: 1.1.0 + micromark-util-chunked: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 - get-nonce@1.0.1: {} + micromark-util-symbol@1.1.0: {} - get-port@3.2.0: {} + micromark-util-symbol@2.0.1: {} - get-proto@1.0.1: - dependencies: - dunder-proto: 1.0.1 - es-object-atoms: 1.1.1 + micromark-util-types@1.1.0: {} - ghost-testrpc@0.0.2: - dependencies: - chalk: 2.4.2 - node-emoji: 1.11.0 + micromark-util-types@2.0.2: {} - glob-parent@5.1.2: + micromark@4.0.2: dependencies: - is-glob: 4.0.3 + '@types/debug': 4.1.12 + debug: 4.4.3(supports-color@8.1.1) + decode-named-character-reference: 1.3.0 + devlop: 1.1.0 + micromark-core-commonmark: 2.0.3 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-chunked: 2.0.1 + micromark-util-combine-extensions: 2.0.1 + micromark-util-decode-numeric-character-reference: 2.0.2 + micromark-util-encode: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-sanitize-uri: 2.0.1 + micromark-util-subtokenize: 2.1.0 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + transitivePeerDependencies: + - supports-color - glob-parent@6.0.2: + micromatch@4.0.8: dependencies: - is-glob: 4.0.3 + braces: 3.0.3 + picomatch: 2.3.1 - glob@5.0.15: - dependencies: - inflight: 1.0.6 - inherits: 2.0.4 - minimatch: 3.1.2 - once: 1.4.0 - path-is-absolute: 1.0.1 + mime-db@1.33.0: {} - glob@7.1.7: - dependencies: - fs.realpath: 1.0.0 - inflight: 1.0.6 - inherits: 2.0.4 - minimatch: 3.1.2 - once: 1.4.0 - path-is-absolute: 1.0.1 + mime-db@1.52.0: {} - glob@7.2.3: - dependencies: - fs.realpath: 1.0.0 - inflight: 1.0.6 - inherits: 2.0.4 - minimatch: 3.1.2 - once: 1.4.0 - path-is-absolute: 1.0.1 + mime-db@1.54.0: {} - glob@8.1.0: + mime-types@2.1.18: dependencies: - fs.realpath: 1.0.0 - inflight: 1.0.6 - inherits: 2.0.4 - minimatch: 5.1.6 - once: 1.4.0 + mime-db: 1.33.0 - global-modules@2.0.0: + mime-types@2.1.35: dependencies: - global-prefix: 3.0.0 + mime-db: 1.52.0 - global-prefix@3.0.0: + mime-types@3.0.2: dependencies: - ini: 1.3.8 - kind-of: 6.0.3 - which: 1.3.1 + mime-db: 1.54.0 - globby@10.0.2: - dependencies: - '@types/glob': 7.2.0 - array-union: 2.1.0 - dir-glob: 3.0.1 - fast-glob: 3.3.3 - glob: 7.2.3 - ignore: 5.3.2 - merge2: 1.4.1 - slash: 3.0.0 + mime@1.6.0: {} - gopd@1.2.0: {} + mimic-fn@2.1.0: {} - graceful-fs@4.2.11: {} + mimic-response@3.1.0: {} - h3@1.15.4: - dependencies: - cookie-es: 1.2.2 - crossws: 0.3.5 - defu: 6.1.4 - destr: 2.0.5 - iron-webcrypto: 1.2.1 - node-mock-http: 1.0.4 - radix3: 1.1.2 - ufo: 1.6.1 - uncrypto: 0.1.3 + mimic-response@4.0.0: {} - handlebars@4.7.8: + mini-css-extract-plugin@2.10.0(webpack@5.104.1): dependencies: - minimist: 1.2.8 - neo-async: 2.6.2 - source-map: 0.6.1 - wordwrap: 1.0.0 - optionalDependencies: - uglify-js: 3.19.3 + schema-utils: 4.3.3 + tapable: 2.3.0 + webpack: 5.104.1 + + minimalistic-assert@1.0.1: {} + + minimalistic-crypto-utils@1.0.1: {} - hardhat-dependency-compiler@1.2.1(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10)): + minimatch@10.1.1: dependencies: - hardhat: 2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10) + '@isaacs/brace-expansion': 5.0.0 - hardhat-gas-reporter@1.0.10(bufferutil@4.0.9)(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10): + minimatch@3.1.2: dependencies: - array-uniq: 1.0.3 - eth-gas-reporter: 0.2.27(bufferutil@4.0.9)(utf-8-validate@5.0.10) - hardhat: 2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10) - sha1: 1.1.1 - transitivePeerDependencies: - - '@codechecks/client' - - bufferutil - - debug - - utf-8-validate + brace-expansion: 1.1.12 - hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10): + minimatch@5.1.6: dependencies: - '@ethereumjs/util': 9.1.0 - '@ethersproject/abi': 5.8.0 - '@nomicfoundation/edr': 0.12.0-next.17 - '@nomicfoundation/solidity-analyzer': 0.1.2 - '@sentry/node': 5.30.0 - adm-zip: 0.4.16 - aggregate-error: 3.1.0 - ansi-escapes: 4.3.2 - boxen: 5.1.2 - chokidar: 4.0.3 - ci-info: 2.0.0 - debug: 4.4.3(supports-color@8.1.1) - enquirer: 2.4.1 - env-paths: 2.2.1 - ethereum-cryptography: 1.2.0 - find-up: 5.0.0 - fp-ts: 1.19.3 - fs-extra: 7.0.1 - immutable: 4.3.7 - io-ts: 1.10.4 - json-stream-stringify: 3.1.6 - keccak: 3.0.4 - lodash: 4.17.21 - micro-eth-signer: 0.14.0 - mnemonist: 0.38.5 - mocha: 10.8.2 - p-map: 4.0.0 - picocolors: 1.1.1 - raw-body: 2.5.3 - resolve: 1.17.0 - semver: 6.3.1 - solc: 0.8.26(debug@4.4.3) - source-map-support: 0.5.21 - stacktrace-parser: 0.1.11 - tinyglobby: 0.2.15 - tsort: 0.0.1 - undici: 5.29.0 - uuid: 8.3.2 - ws: 7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10) - optionalDependencies: - ts-node: 10.9.2(@types/node@22.7.5)(typescript@5.9.3) - typescript: 5.9.3 - transitivePeerDependencies: - - bufferutil - - supports-color - - utf-8-validate + brace-expansion: 2.0.2 - has-flag@1.0.0: {} + minimatch@9.0.5: + dependencies: + brace-expansion: 2.0.2 - has-flag@3.0.0: {} + minimist@1.2.8: {} - has-flag@4.0.0: {} + mipd@0.0.7(typescript@5.6.3): + optionalDependencies: + typescript: 5.6.3 - has-property-descriptors@1.0.2: + mkdirp@0.5.6: dependencies: - es-define-property: 1.0.1 + minimist: 1.2.8 - has-symbols@1.1.0: {} + mkdirp@1.0.4: {} - has-tostringtag@1.0.2: + mnemonist@0.38.5: dependencies: - has-symbols: 1.1.0 + obliterator: 2.0.5 - hash-base@3.1.2: + mocha@10.8.2: dependencies: - inherits: 2.0.4 - readable-stream: 2.3.8 - safe-buffer: 5.2.1 - to-buffer: 1.2.2 + ansi-colors: 4.1.3 + browser-stdout: 1.3.1 + chokidar: 3.6.0 + debug: 4.4.3(supports-color@8.1.1) + diff: 5.2.0 + escape-string-regexp: 4.0.0 + find-up: 5.0.0 + glob: 8.1.0 + he: 1.2.0 + js-yaml: 4.1.1 + log-symbols: 4.1.0 + minimatch: 5.1.6 + ms: 2.1.3 + serialize-javascript: 6.0.2 + strip-json-comments: 3.1.1 + supports-color: 8.1.1 + workerpool: 6.5.1 + yargs: 16.2.0 + yargs-parser: 20.2.9 + yargs-unparser: 2.0.0 - hash.js@1.1.7: - dependencies: - inherits: 2.0.4 - minimalistic-assert: 1.0.1 + modern-ahocorasick@1.1.0: {} - hasown@2.0.2: + motion-dom@12.23.23: dependencies: - function-bind: 1.1.2 + motion-utils: 12.23.6 - he@1.2.0: {} + motion-utils@12.23.6: {} - heap@0.2.7: {} + mrmime@2.0.1: {} - hmac-drbg@1.0.1: - dependencies: - hash.js: 1.1.7 - minimalistic-assert: 1.0.1 - minimalistic-crypto-utils: 1.0.1 + ms@2.0.0: {} - hono@4.11.1: {} + ms@2.1.2: {} - http-basic@8.1.3: - dependencies: - caseless: 0.12.0 - concat-stream: 1.6.2 - http-response-object: 3.0.2 - parse-cache-control: 1.0.1 + ms@2.1.3: {} - http-errors@2.0.1: + multicast-dns@7.2.5: dependencies: - depd: 2.0.0 - inherits: 2.0.4 - setprototypeof: 1.2.0 - statuses: 2.0.2 - toidentifier: 1.0.1 + dns-packet: 5.6.1 + thunky: 1.1.0 - http-response-object@3.0.2: - dependencies: - '@types/node': 10.17.60 + multiformats@9.9.0: {} - https-proxy-agent@5.0.1: + mz@2.7.0: dependencies: - agent-base: 6.0.2 - debug: 4.4.3(supports-color@8.1.1) - transitivePeerDependencies: - - supports-color + any-promise: 1.3.0 + object-assign: 4.1.1 + thenify-all: 1.6.0 - humanize-ms@1.2.1: - dependencies: - ms: 2.1.3 + nanoid@3.3.11: {} - iconv-lite@0.4.24: + ndjson@2.0.0: dependencies: - safer-buffer: 2.1.2 + json-stringify-safe: 5.0.1 + minimist: 1.2.8 + readable-stream: 3.6.2 + split2: 3.2.2 + through2: 4.0.2 - idb-keyval@6.2.1: {} + negotiator@0.6.3: {} - idb-keyval@6.2.2: {} + negotiator@0.6.4: {} - ieee754@1.2.1: {} + neo-async@2.6.2: {} - ignore@5.3.2: {} + no-case@3.0.4: + dependencies: + lower-case: 2.0.2 + tslib: 2.8.1 - immer@10.0.2: {} + node-addon-api@2.0.2: {} - immutable@4.3.7: {} + node-addon-api@5.1.0: {} - indent-string@4.0.0: {} + node-emoji@1.11.0: + dependencies: + lodash: 4.17.21 - inflight@1.0.6: + node-emoji@2.2.0: dependencies: - once: 1.4.0 - wrappy: 1.0.2 + '@sindresorhus/is': 4.6.0 + char-regex: 1.0.2 + emojilib: 2.4.0 + skin-tone: 2.0.0 - inherits@2.0.4: {} + node-fetch-native@1.6.7: {} - ini@1.3.8: {} + node-fetch@2.7.0: + dependencies: + whatwg-url: 5.0.0 - interpret@1.4.0: {} + node-gyp-build@4.8.4: {} - io-ts@1.10.4: - dependencies: - fp-ts: 1.19.3 + node-mock-http@1.0.4: {} - iron-webcrypto@1.2.1: {} + node-releases@2.0.27: {} - is-arguments@1.2.0: - dependencies: - call-bound: 1.0.4 - has-tostringtag: 1.0.2 + nofilter@3.1.0: {} - is-binary-path@2.1.0: + nopt@3.0.6: dependencies: - binary-extensions: 2.3.0 + abbrev: 1.0.9 - is-buffer@1.1.6: {} + normalize-path@3.0.0: {} - is-callable@1.2.7: {} + normalize-url@8.1.1: {} - is-core-module@2.16.1: + npm-run-path@4.0.1: dependencies: - hasown: 2.0.2 + path-key: 3.1.1 - is-extglob@2.1.1: {} + nprogress@0.2.0: {} - is-fullwidth-code-point@2.0.0: {} + nth-check@2.1.1: + dependencies: + boolbase: 1.0.0 - is-fullwidth-code-point@3.0.0: {} + null-loader@4.0.1(webpack@5.104.1): + dependencies: + loader-utils: 2.0.4 + schema-utils: 3.3.0 + webpack: 5.104.1 - is-generator-function@1.1.2: + number-to-bn@1.7.0: 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 + bn.js: 4.11.6 + strip-hex-prefix: 1.0.0 - is-glob@4.0.3: + obj-multiplex@1.0.0: dependencies: - is-extglob: 2.1.1 + end-of-stream: 1.4.5 + once: 1.4.0 + readable-stream: 2.3.8 - is-hex-prefixed@1.0.0: {} + object-assign@4.1.1: {} - is-number@7.0.0: {} + object-hash@3.0.0: {} - is-plain-obj@2.1.0: {} + object-inspect@1.13.4: {} - is-regex@1.2.1: + object-keys@1.1.1: {} + + object.assign@4.1.7: dependencies: + call-bind: 1.0.8 call-bound: 1.0.4 - gopd: 1.2.0 - has-tostringtag: 1.0.2 - hasown: 2.0.2 + define-properties: 1.2.1 + es-object-atoms: 1.1.1 + has-symbols: 1.1.0 + object-keys: 1.1.1 - is-retry-allowed@2.2.0: {} + obliterator@2.0.5: {} - is-stream@2.0.1: {} + obuf@1.1.2: {} - is-typed-array@1.1.15: + ofetch@1.5.1: dependencies: - which-typed-array: 1.1.19 - - is-unicode-supported@0.1.0: {} + destr: 2.0.5 + node-fetch-native: 1.6.7 + ufo: 1.6.1 - isarray@1.0.0: {} + on-exit-leak-free@0.2.0: {} - isarray@2.0.5: {} + on-finished@2.4.1: + dependencies: + ee-first: 1.1.1 - isexe@2.0.0: {} + on-headers@1.1.0: {} - isomorphic-unfetch@3.1.0: + once@1.4.0: dependencies: - node-fetch: 2.7.0 - unfetch: 4.2.0 - transitivePeerDependencies: - - encoding + wrappy: 1.0.2 - isomorphic-ws@4.0.1(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10)): + onetime@5.1.2: dependencies: - ws: 7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10) + mimic-fn: 2.1.0 - isows@1.0.6(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)): + open@10.2.0: dependencies: - ws: 8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + default-browser: 5.4.0 + define-lazy-prop: 3.0.0 + is-inside-container: 1.0.0 + wsl-utils: 0.1.0 - isows@1.0.7(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)): + open@8.4.2: dependencies: - ws: 8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10) + define-lazy-prop: 2.0.0 + is-docker: 2.2.1 + is-wsl: 2.2.0 - jayson@4.2.0(bufferutil@4.0.9)(utf-8-validate@5.0.10): + openapi-fetch@0.13.8: dependencies: - '@types/connect': 3.4.38 - '@types/node': 12.20.55 - '@types/ws': 7.4.7 - commander: 2.20.3 - delay: 5.0.0 - es6-promisify: 5.0.0 - eyes: 0.1.8 - isomorphic-ws: 4.0.1(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10)) - json-stringify-safe: 5.0.1 - stream-json: 1.9.1 - uuid: 8.3.2 - ws: 7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10) - transitivePeerDependencies: - - bufferutil - - utf-8-validate + openapi-typescript-helpers: 0.0.15 - jiti@1.21.7: {} + openapi-typescript-helpers@0.0.15: {} - jose@6.1.3: {} + opener@1.5.2: {} - js-cookie@2.2.1: {} + optionator@0.8.3: + dependencies: + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.3.0 + prelude-ls: 1.1.2 + type-check: 0.3.2 + word-wrap: 1.2.5 - js-sha3@0.8.0: {} + ordinal@1.0.3: {} - js-tokens@4.0.0: {} + os-tmpdir@1.0.2: {} - js-tokens@9.0.1: {} + ox@0.10.5(typescript@5.6.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.6.3)(zod@3.22.4) + eventemitter3: 5.0.1 + optionalDependencies: + typescript: 5.6.3 + transitivePeerDependencies: + - zod - js-yaml@3.14.2: + ox@0.10.5(typescript@5.6.3)(zod@3.25.76): dependencies: - argparse: 1.0.10 - esprima: 4.0.1 + '@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.6.3)(zod@3.25.76) + eventemitter3: 5.0.1 + optionalDependencies: + typescript: 5.6.3 + transitivePeerDependencies: + - zod - js-yaml@4.1.1: + ox@0.10.5(typescript@5.6.3)(zod@4.2.1): dependencies: - argparse: 2.0.1 - - jsesc@3.1.0: {} + '@adraffy/ens-normalize': 1.11.1 + '@noble/ciphers': 1.3.0 + '@noble/curves': 1.9.1 + '@noble/hashes': 1.8.0 + '@scure/bip32': 1.7.0 + '@scure/bip39': 1.6.0 + abitype: 1.2.3(typescript@5.6.3)(zod@4.2.1) + eventemitter3: 5.0.1 + optionalDependencies: + typescript: 5.6.3 + transitivePeerDependencies: + - zod - json-rpc-engine@6.1.0: + ox@0.6.7(typescript@5.6.3)(zod@3.25.76): dependencies: - '@metamask/safe-event-emitter': 2.0.0 - eth-rpc-errors: 4.0.3 - - json-rpc-random-id@1.0.1: {} - - json-schema-traverse@1.0.0: {} - - json-stream-stringify@3.1.6: {} - - json-stringify-safe@5.0.1: {} - - json5@2.2.3: {} - - jsonfile@4.0.0: + '@adraffy/ens-normalize': 1.11.1 + '@noble/curves': 1.9.7 + '@noble/hashes': 1.8.0 + '@scure/bip32': 1.6.2 + '@scure/bip39': 1.5.4 + abitype: 1.0.8(typescript@5.6.3)(zod@3.25.76) + eventemitter3: 5.0.1 optionalDependencies: - graceful-fs: 4.2.11 + typescript: 5.6.3 + transitivePeerDependencies: + - zod - jsonfile@6.2.0: + ox@0.6.9(typescript@5.6.3)(zod@3.25.76): dependencies: - universalify: 2.0.1 + '@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.6.3)(zod@3.25.76) + eventemitter3: 5.0.1 optionalDependencies: - graceful-fs: 4.2.11 - - jsonschema@1.5.0: {} + typescript: 5.6.3 + transitivePeerDependencies: + - zod - keccak@3.0.4: + ox@0.9.17(typescript@5.6.3)(zod@4.2.1): dependencies: - node-addon-api: 2.0.2 - node-gyp-build: 4.8.4 - readable-stream: 3.6.2 - - keyvaluestorage-interface@1.0.0: {} + '@adraffy/ens-normalize': 1.11.1 + '@noble/ciphers': 1.3.0 + '@noble/curves': 1.9.1 + '@noble/hashes': 1.8.0 + '@scure/bip32': 1.7.0 + '@scure/bip39': 1.6.0 + abitype: 1.2.3(typescript@5.6.3)(zod@4.2.1) + eventemitter3: 5.0.1 + optionalDependencies: + typescript: 5.6.3 + transitivePeerDependencies: + - zod - kind-of@6.0.3: {} + p-cancelable@3.0.0: {} - kleur@3.0.3: {} + p-finally@1.0.0: {} - levn@0.3.0: + p-limit@2.3.0: dependencies: - prelude-ls: 1.1.2 - type-check: 0.3.2 - - lilconfig@3.1.3: {} - - lines-and-columns@1.2.4: {} + p-try: 2.2.0 - lit-element@4.2.1: + p-limit@3.1.0: dependencies: - '@lit-labs/ssr-dom-shim': 1.4.0 - '@lit/reactive-element': 2.1.1 - lit-html: 3.3.1 + yocto-queue: 0.1.0 - lit-html@3.3.1: + p-limit@4.0.0: dependencies: - '@types/trusted-types': 2.0.7 + yocto-queue: 1.2.2 - lit@3.3.0: + p-locate@4.1.0: dependencies: - '@lit/reactive-element': 2.1.1 - lit-element: 4.2.1 - lit-html: 3.3.1 + p-limit: 2.3.0 - locate-path@5.0.0: + p-locate@5.0.0: dependencies: - p-locate: 4.1.0 + p-limit: 3.1.0 - locate-path@6.0.0: + p-locate@6.0.0: dependencies: - p-locate: 5.0.0 + p-limit: 4.0.0 - lodash.camelcase@4.3.0: {} + p-map@4.0.0: + dependencies: + aggregate-error: 3.1.0 - lodash.clonedeep@4.5.0: {} + p-queue@6.6.2: + dependencies: + eventemitter3: 4.0.7 + p-timeout: 3.2.0 - lodash.isequal@4.5.0: {} + p-retry@6.2.1: + dependencies: + '@types/retry': 0.12.2 + is-network-error: 1.3.0 + retry: 0.13.1 - lodash.truncate@4.4.2: {} + p-timeout@3.2.0: + dependencies: + p-finally: 1.0.0 - lodash@4.17.21: {} + p-try@2.2.0: {} - log-symbols@4.1.0: + package-json@8.1.1: dependencies: - chalk: 4.1.2 - is-unicode-supported: 0.1.0 + got: 12.6.1 + registry-auth-token: 5.1.1 + registry-url: 6.0.1 + semver: 7.7.3 - loose-envify@1.4.0: + param-case@3.0.4: dependencies: - js-tokens: 4.0.0 + dot-case: 3.0.4 + tslib: 2.8.1 - loupe@2.3.7: + parent-module@1.0.1: dependencies: - get-func-name: 2.0.2 + callsites: 3.1.0 - loupe@3.2.1: {} + parse-cache-control@1.0.1: {} - lru-cache@10.4.3: {} + parse-entities@4.0.2: + dependencies: + '@types/unist': 2.0.11 + character-entities-legacy: 3.0.0 + character-reference-invalid: 2.0.1 + decode-named-character-reference: 1.3.0 + is-alphanumerical: 2.0.1 + is-decimal: 2.0.1 + is-hexadecimal: 2.0.1 - lru-cache@5.1.1: + parse-json@5.2.0: dependencies: - yallist: 3.1.1 + '@babel/code-frame': 7.27.1 + error-ex: 1.3.4 + json-parse-even-better-errors: 2.3.1 + lines-and-columns: 1.2.4 - lru_map@0.3.3: {} + parse-numeric-range@1.3.0: {} - lucide-react@0.525.0(react@18.3.1): + parse5-htmlparser2-tree-adapter@7.1.0: dependencies: - react: 18.3.1 + domhandler: 5.0.3 + parse5: 7.3.0 - magic-string@0.30.21: + parse5@7.3.0: dependencies: - '@jridgewell/sourcemap-codec': 1.5.5 - - make-error@1.3.6: {} - - markdown-table@1.1.3: {} + entities: 6.0.1 - math-intrinsics@1.1.0: {} + parseurl@1.3.3: {} - md5.js@1.3.5: + pascal-case@3.1.2: dependencies: - hash-base: 3.1.2 - inherits: 2.0.4 - safe-buffer: 5.2.1 + no-case: 3.0.4 + tslib: 2.8.1 - md5@2.3.0: - dependencies: - charenc: 0.0.2 - crypt: 0.0.2 - is-buffer: 1.1.6 + path-exists@4.0.0: {} - media-query-parser@2.0.2: - dependencies: - '@babel/runtime': 7.28.4 + path-exists@5.0.0: {} - memorystream@0.3.1: {} + path-is-absolute@1.0.1: {} - merge2@1.4.1: {} + path-is-inside@1.0.2: {} - micro-eth-signer@0.14.0: - dependencies: - '@noble/curves': 1.8.2 - '@noble/hashes': 1.7.2 - micro-packed: 0.7.3 + path-key@3.1.1: {} - micro-ftch@0.3.1: {} + path-parse@1.0.7: {} - micro-packed@0.7.3: - dependencies: - '@scure/base': 1.2.6 + path-to-regexp@0.1.12: {} - micromatch@4.0.8: + path-to-regexp@1.9.0: dependencies: - braces: 3.0.3 - picomatch: 2.3.1 + isarray: 0.0.1 - mime-db@1.52.0: {} + path-to-regexp@3.3.0: {} - mime-types@2.1.35: - dependencies: - mime-db: 1.52.0 + path-type@4.0.0: {} - minimalistic-assert@1.0.1: {} + pathe@2.0.3: {} - minimalistic-crypto-utils@1.0.1: {} + pathval@1.1.1: {} - minimatch@10.1.1: - dependencies: - '@isaacs/brace-expansion': 5.0.0 + pathval@2.0.1: {} - minimatch@3.1.2: + pbkdf2@3.1.5: dependencies: - brace-expansion: 1.1.12 + create-hash: 1.2.0 + create-hmac: 1.1.7 + ripemd160: 2.0.3 + safe-buffer: 5.2.1 + sha.js: 2.4.12 + to-buffer: 1.2.2 - minimatch@5.1.6: - dependencies: - brace-expansion: 2.0.2 + picocolors@1.1.1: {} - minimatch@9.0.5: - dependencies: - brace-expansion: 2.0.2 + picomatch@2.3.1: {} - minimist@1.2.8: {} + picomatch@4.0.3: {} - mipd@0.0.7(typescript@5.9.3): - optionalDependencies: - typescript: 5.9.3 + pify@2.3.0: {} - mkdirp@0.5.6: - dependencies: - minimist: 1.2.8 + pify@3.0.0: {} - mkdirp@1.0.4: {} + pify@4.0.1: {} - mnemonist@0.38.5: + pify@5.0.0: {} + + pino-abstract-transport@0.5.0: dependencies: - obliterator: 2.0.5 + duplexify: 4.1.3 + split2: 4.2.0 - mocha@10.8.2: + pino-std-serializers@4.0.0: {} + + pino@7.11.0: dependencies: - ansi-colors: 4.1.3 - browser-stdout: 1.3.1 - chokidar: 3.6.0 - debug: 4.4.3(supports-color@8.1.1) - diff: 5.2.0 - escape-string-regexp: 4.0.0 - find-up: 5.0.0 - glob: 8.1.0 - he: 1.2.0 - js-yaml: 4.1.1 - log-symbols: 4.1.0 - minimatch: 5.1.6 - ms: 2.1.3 - serialize-javascript: 6.0.2 - strip-json-comments: 3.1.1 - supports-color: 8.1.1 - workerpool: 6.5.1 - yargs: 16.2.0 - yargs-parser: 20.2.9 - yargs-unparser: 2.0.0 + 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 - modern-ahocorasick@1.1.0: {} + pirates@4.0.7: {} - motion-dom@12.23.23: + pkg-dir@7.0.0: dependencies: - motion-utils: 12.23.6 - - motion-utils@12.23.6: {} + find-up: 6.3.0 - ms@2.1.2: {} + pkijs@3.3.3: + dependencies: + '@noble/hashes': 1.4.0 + asn1js: 3.0.7 + bytestreamjs: 2.0.1 + pvtsutils: 1.3.6 + pvutils: 1.1.5 + tslib: 2.8.1 - ms@2.1.3: {} + pngjs@5.0.0: {} - multiformats@9.9.0: {} + pony-cause@2.1.11: {} - mz@2.7.0: + porto@0.2.35(@tanstack/react-query@5.90.12(react@18.3.1))(@types/react@18.3.27)(@wagmi/core@2.22.1(@tanstack/query-core@5.90.12)(@types/react@18.3.27)(immer@10.0.2)(react@18.3.1)(typescript@5.6.3)(use-sync-external-store@1.4.0(react@18.3.1))(viem@2.43.1(bufferutil@4.0.9)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.25.76)))(immer@10.0.2)(react@18.3.1)(typescript@5.6.3)(use-sync-external-store@1.4.0(react@18.3.1))(viem@2.43.1(bufferutil@4.0.9)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.25.76))(wagmi@2.19.5(@tanstack/query-core@5.90.12)(@tanstack/react-query@5.90.12(react@18.3.1))(@types/react@18.3.27)(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(immer@10.0.2)(react@18.3.1)(typescript@5.6.3)(utf-8-validate@5.0.10)(viem@2.43.1(bufferutil@4.0.9)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.25.76))(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)): dependencies: - any-promise: 1.3.0 - object-assign: 4.1.1 - thenify-all: 1.6.0 + '@wagmi/core': 2.22.1(@tanstack/query-core@5.90.12)(@types/react@18.3.27)(immer@10.0.2)(react@18.3.1)(typescript@5.6.3)(use-sync-external-store@1.4.0(react@18.3.1))(viem@2.43.1(bufferutil@4.0.9)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.25.76)) + hono: 4.11.1 + idb-keyval: 6.2.2 + mipd: 0.0.7(typescript@5.6.3) + ox: 0.9.17(typescript@5.6.3)(zod@4.2.1) + viem: 2.43.1(bufferutil@4.0.9)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.25.76) + zod: 4.2.1 + zustand: 5.0.9(@types/react@18.3.27)(immer@10.0.2)(react@18.3.1)(use-sync-external-store@1.4.0(react@18.3.1)) + optionalDependencies: + '@tanstack/react-query': 5.90.12(react@18.3.1) + react: 18.3.1 + typescript: 5.6.3 + wagmi: 2.19.5(@tanstack/query-core@5.90.12)(@tanstack/react-query@5.90.12(react@18.3.1))(@types/react@18.3.27)(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(immer@10.0.2)(react@18.3.1)(typescript@5.6.3)(utf-8-validate@5.0.10)(viem@2.43.1(bufferutil@4.0.9)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.25.76))(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76) + transitivePeerDependencies: + - '@types/react' + - immer + - use-sync-external-store - nanoid@3.3.11: {} + possible-typed-array-names@1.1.0: {} - ndjson@2.0.0: + postcss-attribute-case-insensitive@7.0.1(postcss@8.5.6): dependencies: - json-stringify-safe: 5.0.1 - minimist: 1.2.8 - readable-stream: 3.6.2 - split2: 3.2.2 - through2: 4.0.2 - - neo-async@2.6.2: {} - - node-addon-api@2.0.2: {} - - node-addon-api@5.1.0: {} + postcss: 8.5.6 + postcss-selector-parser: 7.1.1 - node-emoji@1.11.0: + postcss-calc@9.0.1(postcss@8.5.6): dependencies: - lodash: 4.17.21 - - node-fetch-native@1.6.7: {} + postcss: 8.5.6 + postcss-selector-parser: 6.1.2 + postcss-value-parser: 4.2.0 - node-fetch@2.7.0: + postcss-clamp@4.1.0(postcss@8.5.6): dependencies: - whatwg-url: 5.0.0 - - node-gyp-build@4.8.4: {} + postcss: 8.5.6 + postcss-value-parser: 4.2.0 - node-mock-http@1.0.4: {} + postcss-color-functional-notation@7.0.12(postcss@8.5.6): + dependencies: + '@csstools/css-color-parser': 3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + '@csstools/postcss-progressive-custom-properties': 4.2.1(postcss@8.5.6) + '@csstools/utilities': 2.0.0(postcss@8.5.6) + postcss: 8.5.6 - node-releases@2.0.27: {} + postcss-color-hex-alpha@10.0.0(postcss@8.5.6): + dependencies: + '@csstools/utilities': 2.0.0(postcss@8.5.6) + postcss: 8.5.6 + postcss-value-parser: 4.2.0 - nofilter@3.1.0: {} + postcss-color-rebeccapurple@10.0.0(postcss@8.5.6): + dependencies: + '@csstools/utilities': 2.0.0(postcss@8.5.6) + postcss: 8.5.6 + postcss-value-parser: 4.2.0 - nopt@3.0.6: + postcss-colormin@6.1.0(postcss@8.5.6): dependencies: - abbrev: 1.0.9 + browserslist: 4.28.1 + caniuse-api: 3.0.0 + colord: 2.9.3 + postcss: 8.5.6 + postcss-value-parser: 4.2.0 - normalize-path@3.0.0: {} + postcss-convert-values@6.1.0(postcss@8.5.6): + dependencies: + browserslist: 4.28.1 + postcss: 8.5.6 + postcss-value-parser: 4.2.0 - number-to-bn@1.7.0: + postcss-custom-media@11.0.6(postcss@8.5.6): dependencies: - bn.js: 4.11.6 - strip-hex-prefix: 1.0.0 + '@csstools/cascade-layer-name-parser': 2.0.5(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + '@csstools/media-query-list-parser': 4.0.3(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + postcss: 8.5.6 - obj-multiplex@1.0.0: + postcss-custom-properties@14.0.6(postcss@8.5.6): dependencies: - end-of-stream: 1.4.5 - once: 1.4.0 - readable-stream: 2.3.8 + '@csstools/cascade-layer-name-parser': 2.0.5(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + '@csstools/utilities': 2.0.0(postcss@8.5.6) + postcss: 8.5.6 + postcss-value-parser: 4.2.0 - object-assign@4.1.1: {} + postcss-custom-selectors@8.0.5(postcss@8.5.6): + dependencies: + '@csstools/cascade-layer-name-parser': 2.0.5(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + postcss: 8.5.6 + postcss-selector-parser: 7.1.1 - object-hash@3.0.0: {} + postcss-dir-pseudo-class@9.0.1(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + postcss-selector-parser: 7.1.1 - object-inspect@1.13.4: {} + postcss-discard-comments@6.0.2(postcss@8.5.6): + dependencies: + postcss: 8.5.6 - obliterator@2.0.5: {} + postcss-discard-duplicates@6.0.3(postcss@8.5.6): + dependencies: + postcss: 8.5.6 - ofetch@1.5.1: + postcss-discard-empty@6.0.3(postcss@8.5.6): dependencies: - destr: 2.0.5 - node-fetch-native: 1.6.7 - ufo: 1.6.1 + postcss: 8.5.6 - on-exit-leak-free@0.2.0: {} + postcss-discard-overridden@6.0.2(postcss@8.5.6): + dependencies: + postcss: 8.5.6 - once@1.4.0: + postcss-discard-unused@6.0.5(postcss@8.5.6): dependencies: - wrappy: 1.0.2 + postcss: 8.5.6 + postcss-selector-parser: 6.1.2 - openapi-fetch@0.13.8: + postcss-double-position-gradients@6.0.4(postcss@8.5.6): dependencies: - openapi-typescript-helpers: 0.0.15 + '@csstools/postcss-progressive-custom-properties': 4.2.1(postcss@8.5.6) + '@csstools/utilities': 2.0.0(postcss@8.5.6) + postcss: 8.5.6 + postcss-value-parser: 4.2.0 - openapi-typescript-helpers@0.0.15: {} + postcss-focus-visible@10.0.1(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + postcss-selector-parser: 7.1.1 - optionator@0.8.3: + postcss-focus-within@9.0.1(postcss@8.5.6): dependencies: - deep-is: 0.1.4 - fast-levenshtein: 2.0.6 - levn: 0.3.0 - prelude-ls: 1.1.2 - type-check: 0.3.2 - word-wrap: 1.2.5 + postcss: 8.5.6 + postcss-selector-parser: 7.1.1 - ordinal@1.0.3: {} + postcss-font-variant@5.0.0(postcss@8.5.6): + dependencies: + postcss: 8.5.6 - os-tmpdir@1.0.2: {} + postcss-gap-properties@6.0.0(postcss@8.5.6): + dependencies: + postcss: 8.5.6 - ox@0.10.5(typescript@5.9.3)(zod@3.22.4): + postcss-image-set-function@7.0.0(postcss@8.5.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@3.22.4) - eventemitter3: 5.0.1 - optionalDependencies: - typescript: 5.9.3 - transitivePeerDependencies: - - zod + '@csstools/utilities': 2.0.0(postcss@8.5.6) + postcss: 8.5.6 + postcss-value-parser: 4.2.0 - ox@0.10.5(typescript@5.9.3)(zod@3.25.76): + postcss-import@15.1.0(postcss@8.5.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@3.25.76) - eventemitter3: 5.0.1 - optionalDependencies: - typescript: 5.9.3 - transitivePeerDependencies: - - zod + postcss: 8.5.6 + postcss-value-parser: 4.2.0 + read-cache: 1.0.0 + resolve: 1.22.11 - ox@0.10.5(typescript@5.9.3)(zod@4.2.1): + postcss-js@4.1.0(postcss@8.5.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.2.1) - eventemitter3: 5.0.1 - optionalDependencies: - typescript: 5.9.3 - transitivePeerDependencies: - - zod + camelcase-css: 2.0.1 + postcss: 8.5.6 - ox@0.6.7(typescript@5.9.3)(zod@4.2.1): + postcss-lab-function@7.0.12(postcss@8.5.6): dependencies: - '@adraffy/ens-normalize': 1.11.1 - '@noble/curves': 1.8.1 - '@noble/hashes': 1.8.0 - '@scure/bip32': 1.6.2 - '@scure/bip39': 1.5.4 - abitype: 1.0.8(typescript@5.9.3)(zod@4.2.1) - eventemitter3: 5.0.1 - optionalDependencies: - typescript: 5.9.3 - transitivePeerDependencies: - - zod + '@csstools/css-color-parser': 3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + '@csstools/postcss-progressive-custom-properties': 4.2.1(postcss@8.5.6) + '@csstools/utilities': 2.0.0(postcss@8.5.6) + postcss: 8.5.6 - ox@0.6.9(typescript@5.9.3)(zod@4.2.1): + postcss-load-config@6.0.1(jiti@1.21.7)(postcss@8.5.6): dependencies: - '@adraffy/ens-normalize': 1.11.1 - '@noble/curves': 1.9.7 - '@noble/hashes': 1.8.0 - '@scure/bip32': 1.7.0 - '@scure/bip39': 1.6.0 - abitype: 1.2.3(typescript@5.9.3)(zod@4.2.1) - eventemitter3: 5.0.1 + lilconfig: 3.1.3 optionalDependencies: - typescript: 5.9.3 - transitivePeerDependencies: - - zod + jiti: 1.21.7 + postcss: 8.5.6 - ox@0.9.17(typescript@5.9.3)(zod@4.2.1): + postcss-loader@7.3.4(postcss@8.5.6)(typescript@5.6.3)(webpack@5.104.1): 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.2.1) - eventemitter3: 5.0.1 - optionalDependencies: - typescript: 5.9.3 + cosmiconfig: 8.3.6(typescript@5.6.3) + jiti: 1.21.7 + postcss: 8.5.6 + semver: 7.7.3 + webpack: 5.104.1 transitivePeerDependencies: - - zod + - typescript - p-limit@2.3.0: + postcss-logical@8.1.0(postcss@8.5.6): dependencies: - p-try: 2.2.0 + postcss: 8.5.6 + postcss-value-parser: 4.2.0 - p-limit@3.1.0: + postcss-merge-idents@6.0.3(postcss@8.5.6): dependencies: - yocto-queue: 0.1.0 + cssnano-utils: 4.0.2(postcss@8.5.6) + postcss: 8.5.6 + postcss-value-parser: 4.2.0 - p-locate@4.1.0: + postcss-merge-longhand@6.0.5(postcss@8.5.6): dependencies: - p-limit: 2.3.0 + postcss: 8.5.6 + postcss-value-parser: 4.2.0 + stylehacks: 6.1.1(postcss@8.5.6) - p-locate@5.0.0: + postcss-merge-rules@6.1.1(postcss@8.5.6): dependencies: - p-limit: 3.1.0 + browserslist: 4.28.1 + caniuse-api: 3.0.0 + cssnano-utils: 4.0.2(postcss@8.5.6) + postcss: 8.5.6 + postcss-selector-parser: 6.1.2 - p-map@4.0.0: + postcss-minify-font-values@6.1.0(postcss@8.5.6): dependencies: - aggregate-error: 3.1.0 - - p-try@2.2.0: {} + postcss: 8.5.6 + postcss-value-parser: 4.2.0 - parse-cache-control@1.0.1: {} + postcss-minify-gradients@6.0.3(postcss@8.5.6): + dependencies: + colord: 2.9.3 + cssnano-utils: 4.0.2(postcss@8.5.6) + postcss: 8.5.6 + postcss-value-parser: 4.2.0 - path-exists@4.0.0: {} + postcss-minify-params@6.1.0(postcss@8.5.6): + dependencies: + browserslist: 4.28.1 + cssnano-utils: 4.0.2(postcss@8.5.6) + postcss: 8.5.6 + postcss-value-parser: 4.2.0 - path-is-absolute@1.0.1: {} + postcss-minify-selectors@6.0.4(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + postcss-selector-parser: 6.1.2 - path-parse@1.0.7: {} + postcss-modules-extract-imports@3.1.0(postcss@8.5.6): + dependencies: + postcss: 8.5.6 - path-type@4.0.0: {} + postcss-modules-local-by-default@4.2.0(postcss@8.5.6): + dependencies: + icss-utils: 5.1.0(postcss@8.5.6) + postcss: 8.5.6 + postcss-selector-parser: 7.1.1 + postcss-value-parser: 4.2.0 - pathe@2.0.3: {} + postcss-modules-scope@3.2.1(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + postcss-selector-parser: 7.1.1 - pathval@1.1.1: {} + postcss-modules-values@4.0.0(postcss@8.5.6): + dependencies: + icss-utils: 5.1.0(postcss@8.5.6) + postcss: 8.5.6 - pathval@2.0.1: {} + postcss-nested@6.2.0(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + postcss-selector-parser: 6.1.2 - pbkdf2@3.1.5: + postcss-nesting@13.0.2(postcss@8.5.6): dependencies: - create-hash: 1.2.0 - create-hmac: 1.1.7 - ripemd160: 2.0.3 - safe-buffer: 5.2.1 - sha.js: 2.4.12 - to-buffer: 1.2.2 + '@csstools/selector-resolve-nested': 3.1.0(postcss-selector-parser@7.1.1) + '@csstools/selector-specificity': 5.0.0(postcss-selector-parser@7.1.1) + postcss: 8.5.6 + postcss-selector-parser: 7.1.1 - picocolors@1.1.1: {} + postcss-normalize-charset@6.0.2(postcss@8.5.6): + dependencies: + postcss: 8.5.6 - picomatch@2.3.1: {} + postcss-normalize-display-values@6.0.2(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + postcss-value-parser: 4.2.0 - picomatch@4.0.3: {} + postcss-normalize-positions@6.0.2(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + postcss-value-parser: 4.2.0 - pify@2.3.0: {} + postcss-normalize-repeat-style@6.0.2(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + postcss-value-parser: 4.2.0 - pify@3.0.0: {} + postcss-normalize-string@6.0.2(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + postcss-value-parser: 4.2.0 - pify@4.0.1: {} + postcss-normalize-timing-functions@6.0.2(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + postcss-value-parser: 4.2.0 - pify@5.0.0: {} + postcss-normalize-unicode@6.1.0(postcss@8.5.6): + dependencies: + browserslist: 4.28.1 + postcss: 8.5.6 + postcss-value-parser: 4.2.0 - pino-abstract-transport@0.5.0: + postcss-normalize-url@6.0.2(postcss@8.5.6): dependencies: - duplexify: 4.1.3 - split2: 4.2.0 + postcss: 8.5.6 + postcss-value-parser: 4.2.0 - pino-std-serializers@4.0.0: {} + postcss-normalize-whitespace@6.0.2(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + postcss-value-parser: 4.2.0 - pino@7.11.0: + postcss-opacity-percentage@3.0.0(postcss@8.5.6): 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 + postcss: 8.5.6 - pirates@4.0.7: {} + postcss-ordered-values@6.0.2(postcss@8.5.6): + dependencies: + cssnano-utils: 4.0.2(postcss@8.5.6) + postcss: 8.5.6 + postcss-value-parser: 4.2.0 - pngjs@5.0.0: {} + postcss-overflow-shorthand@6.0.0(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + postcss-value-parser: 4.2.0 - pony-cause@2.1.11: {} + postcss-page-break@3.0.4(postcss@8.5.6): + dependencies: + postcss: 8.5.6 - porto@0.2.35(@tanstack/react-query@5.90.12(react@18.3.1))(@types/react@18.3.27)(@wagmi/core@2.22.1(@tanstack/query-core@5.90.12)(@types/react@18.3.27)(immer@10.0.2)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@18.3.1))(viem@2.43.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1)))(immer@10.0.2)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@18.3.1))(viem@2.43.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1))(wagmi@2.19.5(@tanstack/query-core@5.90.12)(@tanstack/react-query@5.90.12(react@18.3.1))(@types/react@18.3.27)(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(immer@10.0.2)(react@18.3.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.43.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1))(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@4.2.1)): + postcss-place@10.0.0(postcss@8.5.6): dependencies: - '@wagmi/core': 2.22.1(@tanstack/query-core@5.90.12)(@types/react@18.3.27)(immer@10.0.2)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@18.3.1))(viem@2.43.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1)) - hono: 4.11.1 - idb-keyval: 6.2.2 - mipd: 0.0.7(typescript@5.9.3) - ox: 0.9.17(typescript@5.9.3)(zod@4.2.1) - viem: 2.43.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) - zod: 4.2.1 - zustand: 5.0.9(@types/react@18.3.27)(immer@10.0.2)(react@18.3.1)(use-sync-external-store@1.4.0(react@18.3.1)) - optionalDependencies: - '@tanstack/react-query': 5.90.12(react@18.3.1) - react: 18.3.1 - typescript: 5.9.3 - wagmi: 2.19.5(@tanstack/query-core@5.90.12)(@tanstack/react-query@5.90.12(react@18.3.1))(@types/react@18.3.27)(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(immer@10.0.2)(react@18.3.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.43.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1))(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@4.2.1) - transitivePeerDependencies: - - '@types/react' - - immer - - use-sync-external-store + postcss: 8.5.6 + postcss-value-parser: 4.2.0 - possible-typed-array-names@1.1.0: {} + postcss-preset-env@10.6.1(postcss@8.5.6): + dependencies: + '@csstools/postcss-alpha-function': 1.0.1(postcss@8.5.6) + '@csstools/postcss-cascade-layers': 5.0.2(postcss@8.5.6) + '@csstools/postcss-color-function': 4.0.12(postcss@8.5.6) + '@csstools/postcss-color-function-display-p3-linear': 1.0.1(postcss@8.5.6) + '@csstools/postcss-color-mix-function': 3.0.12(postcss@8.5.6) + '@csstools/postcss-color-mix-variadic-function-arguments': 1.0.2(postcss@8.5.6) + '@csstools/postcss-content-alt-text': 2.0.8(postcss@8.5.6) + '@csstools/postcss-contrast-color-function': 2.0.12(postcss@8.5.6) + '@csstools/postcss-exponential-functions': 2.0.9(postcss@8.5.6) + '@csstools/postcss-font-format-keywords': 4.0.0(postcss@8.5.6) + '@csstools/postcss-gamut-mapping': 2.0.11(postcss@8.5.6) + '@csstools/postcss-gradients-interpolation-method': 5.0.12(postcss@8.5.6) + '@csstools/postcss-hwb-function': 4.0.12(postcss@8.5.6) + '@csstools/postcss-ic-unit': 4.0.4(postcss@8.5.6) + '@csstools/postcss-initial': 2.0.1(postcss@8.5.6) + '@csstools/postcss-is-pseudo-class': 5.0.3(postcss@8.5.6) + '@csstools/postcss-light-dark-function': 2.0.11(postcss@8.5.6) + '@csstools/postcss-logical-float-and-clear': 3.0.0(postcss@8.5.6) + '@csstools/postcss-logical-overflow': 2.0.0(postcss@8.5.6) + '@csstools/postcss-logical-overscroll-behavior': 2.0.0(postcss@8.5.6) + '@csstools/postcss-logical-resize': 3.0.0(postcss@8.5.6) + '@csstools/postcss-logical-viewport-units': 3.0.4(postcss@8.5.6) + '@csstools/postcss-media-minmax': 2.0.9(postcss@8.5.6) + '@csstools/postcss-media-queries-aspect-ratio-number-values': 3.0.5(postcss@8.5.6) + '@csstools/postcss-nested-calc': 4.0.0(postcss@8.5.6) + '@csstools/postcss-normalize-display-values': 4.0.1(postcss@8.5.6) + '@csstools/postcss-oklab-function': 4.0.12(postcss@8.5.6) + '@csstools/postcss-position-area-property': 1.0.0(postcss@8.5.6) + '@csstools/postcss-progressive-custom-properties': 4.2.1(postcss@8.5.6) + '@csstools/postcss-property-rule-prelude-list': 1.0.0(postcss@8.5.6) + '@csstools/postcss-random-function': 2.0.1(postcss@8.5.6) + '@csstools/postcss-relative-color-syntax': 3.0.12(postcss@8.5.6) + '@csstools/postcss-scope-pseudo-class': 4.0.1(postcss@8.5.6) + '@csstools/postcss-sign-functions': 1.1.4(postcss@8.5.6) + '@csstools/postcss-stepped-value-functions': 4.0.9(postcss@8.5.6) + '@csstools/postcss-syntax-descriptor-syntax-production': 1.0.1(postcss@8.5.6) + '@csstools/postcss-system-ui-font-family': 1.0.0(postcss@8.5.6) + '@csstools/postcss-text-decoration-shorthand': 4.0.3(postcss@8.5.6) + '@csstools/postcss-trigonometric-functions': 4.0.9(postcss@8.5.6) + '@csstools/postcss-unset-value': 4.0.0(postcss@8.5.6) + autoprefixer: 10.4.23(postcss@8.5.6) + browserslist: 4.28.1 + css-blank-pseudo: 7.0.1(postcss@8.5.6) + css-has-pseudo: 7.0.3(postcss@8.5.6) + css-prefers-color-scheme: 10.0.0(postcss@8.5.6) + cssdb: 8.7.0 + postcss: 8.5.6 + postcss-attribute-case-insensitive: 7.0.1(postcss@8.5.6) + postcss-clamp: 4.1.0(postcss@8.5.6) + postcss-color-functional-notation: 7.0.12(postcss@8.5.6) + postcss-color-hex-alpha: 10.0.0(postcss@8.5.6) + postcss-color-rebeccapurple: 10.0.0(postcss@8.5.6) + postcss-custom-media: 11.0.6(postcss@8.5.6) + postcss-custom-properties: 14.0.6(postcss@8.5.6) + postcss-custom-selectors: 8.0.5(postcss@8.5.6) + postcss-dir-pseudo-class: 9.0.1(postcss@8.5.6) + postcss-double-position-gradients: 6.0.4(postcss@8.5.6) + postcss-focus-visible: 10.0.1(postcss@8.5.6) + postcss-focus-within: 9.0.1(postcss@8.5.6) + postcss-font-variant: 5.0.0(postcss@8.5.6) + postcss-gap-properties: 6.0.0(postcss@8.5.6) + postcss-image-set-function: 7.0.0(postcss@8.5.6) + postcss-lab-function: 7.0.12(postcss@8.5.6) + postcss-logical: 8.1.0(postcss@8.5.6) + postcss-nesting: 13.0.2(postcss@8.5.6) + postcss-opacity-percentage: 3.0.0(postcss@8.5.6) + postcss-overflow-shorthand: 6.0.0(postcss@8.5.6) + postcss-page-break: 3.0.4(postcss@8.5.6) + postcss-place: 10.0.0(postcss@8.5.6) + postcss-pseudo-class-any-link: 10.0.1(postcss@8.5.6) + postcss-replace-overflow-wrap: 4.0.0(postcss@8.5.6) + postcss-selector-not: 8.0.1(postcss@8.5.6) + + postcss-pseudo-class-any-link@10.0.1(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + postcss-selector-parser: 7.1.1 - postcss-import@15.1.0(postcss@8.5.6): + postcss-reduce-idents@6.0.3(postcss@8.5.6): dependencies: postcss: 8.5.6 postcss-value-parser: 4.2.0 - read-cache: 1.0.0 - resolve: 1.22.11 - postcss-js@4.1.0(postcss@8.5.6): + postcss-reduce-initial@6.1.0(postcss@8.5.6): dependencies: - camelcase-css: 2.0.1 + browserslist: 4.28.1 + caniuse-api: 3.0.0 postcss: 8.5.6 - postcss-load-config@6.0.1(jiti@1.21.7)(postcss@8.5.6): + postcss-reduce-transforms@6.0.2(postcss@8.5.6): dependencies: - lilconfig: 3.1.3 - optionalDependencies: - jiti: 1.21.7 postcss: 8.5.6 + postcss-value-parser: 4.2.0 - postcss-nested@6.2.0(postcss@8.5.6): + postcss-replace-overflow-wrap@4.0.0(postcss@8.5.6): dependencies: postcss: 8.5.6 - postcss-selector-parser: 6.1.2 + + postcss-selector-not@8.0.1(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + postcss-selector-parser: 7.1.1 postcss-selector-parser@6.1.2: dependencies: cssesc: 3.0.0 util-deprecate: 1.0.2 + postcss-selector-parser@7.1.1: + dependencies: + cssesc: 3.0.0 + util-deprecate: 1.0.2 + + postcss-sort-media-queries@5.2.0(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + sort-css-media-queries: 2.2.0 + + postcss-svgo@6.0.3(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + postcss-value-parser: 4.2.0 + svgo: 3.3.2 + + postcss-unique-selectors@6.0.4(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + postcss-selector-parser: 6.1.2 + postcss-value-parser@4.2.0: {} + postcss-zindex@6.0.2(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + postcss@8.5.6: dependencies: nanoid: 3.3.11 @@ -10891,6 +20002,21 @@ snapshots: prettier@2.8.8: {} + pretty-error@4.0.0: + dependencies: + lodash: 4.17.21 + renderkid: 3.0.0 + + pretty-time@1.1.0: {} + + prism-react-renderer@2.4.1(react@19.2.3): + dependencies: + '@types/prismjs': 1.26.5 + clsx: 2.1.1 + react: 19.2.3 + + prismjs@1.30.0: {} + process-nextick-args@2.0.1: {} process-warning@1.0.0: {} @@ -10904,12 +20030,27 @@ snapshots: kleur: 3.0.3 sisteransi: 1.0.5 + prop-types@15.8.1: + dependencies: + loose-envify: 1.4.0 + object-assign: 4.1.1 + react-is: 16.13.1 + proper-lockfile@4.1.2: dependencies: graceful-fs: 4.2.11 retry: 0.12.0 signal-exit: 3.0.7 + property-information@7.1.0: {} + + proto-list@1.2.4: {} + + proxy-addr@2.0.7: + dependencies: + forwarded: 0.2.0 + ipaddr.js: 1.9.1 + proxy-compare@2.6.0: {} proxy-from-env@1.1.0: {} @@ -10919,13 +20060,17 @@ snapshots: end-of-stream: 1.4.5 once: 1.4.0 + punycode@2.3.1: {} + + pupa@3.3.0: + dependencies: + escape-goat: 4.0.0 + pvtsutils@1.3.6: dependencies: tslib: 2.8.1 - optional: true - pvutils@1.1.5: - optional: true + pvutils@1.1.5: {} qr@0.5.3: {} @@ -10951,12 +20096,18 @@ snapshots: quick-format-unescaped@4.0.4: {} + quick-lru@5.1.1: {} + radix3@1.1.2: {} randombytes@2.1.0: dependencies: safe-buffer: 5.2.1 + range-parser@1.2.0: {} + + range-parser@1.2.1: {} + raw-body@2.5.3: dependencies: bytes: 3.1.2 @@ -10964,12 +20115,38 @@ snapshots: iconv-lite: 0.4.24 unpipe: 1.0.0 + rc@1.2.8: + dependencies: + deep-extend: 0.6.0 + ini: 1.3.8 + minimist: 1.2.8 + strip-json-comments: 2.0.1 + react-dom@18.3.1(react@18.3.1): dependencies: loose-envify: 1.4.0 react: 18.3.1 scheduler: 0.23.2 + react-dom@19.2.3(react@19.2.3): + dependencies: + react: 19.2.3 + scheduler: 0.27.0 + + react-fast-compare@3.2.2: {} + + react-is@16.13.1: {} + + react-json-view-lite@2.5.0(react@19.2.3): + dependencies: + react: 19.2.3 + + react-loadable-ssr-addon-v5-slorber@1.0.1(@docusaurus/react-loadable@6.0.0(react@19.2.3))(webpack@5.104.1): + dependencies: + '@babel/runtime': 7.28.4 + react-loadable: '@docusaurus/react-loadable@6.0.0(react@19.2.3)' + webpack: 5.104.1 + react-refresh@0.17.0: {} react-remove-scroll-bar@2.3.8(@types/react@18.3.27)(react@18.3.1): @@ -10991,6 +20168,36 @@ snapshots: optionalDependencies: '@types/react': 18.3.27 + react-router-config@5.1.1(react-router@5.3.4(react@19.2.3))(react@19.2.3): + dependencies: + '@babel/runtime': 7.28.4 + react: 19.2.3 + react-router: 5.3.4(react@19.2.3) + + react-router-dom@5.3.4(react@19.2.3): + dependencies: + '@babel/runtime': 7.28.4 + history: 4.10.1 + loose-envify: 1.4.0 + prop-types: 15.8.1 + react: 19.2.3 + react-router: 5.3.4(react@19.2.3) + tiny-invariant: 1.3.3 + tiny-warning: 1.0.3 + + react-router@5.3.4(react@19.2.3): + dependencies: + '@babel/runtime': 7.28.4 + history: 4.10.1 + hoist-non-react-statics: 3.3.2 + loose-envify: 1.4.0 + path-to-regexp: 1.9.0 + prop-types: 15.8.1 + react: 19.2.3 + react-is: 16.13.1 + tiny-invariant: 1.3.3 + tiny-warning: 1.0.3 + react-style-singleton@2.2.3(@types/react@18.3.27)(react@18.3.1): dependencies: get-nonce: 1.0.1 @@ -11003,6 +20210,8 @@ snapshots: dependencies: loose-envify: 1.4.0 + react@19.2.3: {} + read-cache@1.0.0: dependencies: pify: 2.3.0 @@ -11035,12 +20244,165 @@ snapshots: dependencies: resolve: 1.22.11 + recma-build-jsx@1.0.0: + dependencies: + '@types/estree': 1.0.8 + estree-util-build-jsx: 3.0.1 + vfile: 6.0.3 + + recma-jsx@1.0.1(acorn@8.15.0): + dependencies: + acorn: 8.15.0 + acorn-jsx: 5.3.2(acorn@8.15.0) + estree-util-to-js: 2.0.0 + recma-parse: 1.0.0 + recma-stringify: 1.0.0 + unified: 11.0.5 + + recma-parse@1.0.0: + dependencies: + '@types/estree': 1.0.8 + esast-util-from-js: 2.0.1 + unified: 11.0.5 + vfile: 6.0.3 + + recma-stringify@1.0.0: + dependencies: + '@types/estree': 1.0.8 + estree-util-to-js: 2.0.0 + unified: 11.0.5 + vfile: 6.0.3 + recursive-readdir@2.2.3: dependencies: minimatch: 3.1.2 reduce-flatten@2.0.0: {} + reflect-metadata@0.2.2: {} + + regenerate-unicode-properties@10.2.2: + dependencies: + regenerate: 1.4.2 + + regenerate@1.4.2: {} + + regexpu-core@6.4.0: + dependencies: + regenerate: 1.4.2 + regenerate-unicode-properties: 10.2.2 + regjsgen: 0.8.0 + regjsparser: 0.13.0 + unicode-match-property-ecmascript: 2.0.0 + unicode-match-property-value-ecmascript: 2.2.1 + + registry-auth-token@5.1.1: + dependencies: + '@pnpm/npm-conf': 3.0.2 + + registry-url@6.0.1: + dependencies: + rc: 1.2.8 + + regjsgen@0.8.0: {} + + regjsparser@0.13.0: + dependencies: + jsesc: 3.1.0 + + rehype-raw@7.0.0: + dependencies: + '@types/hast': 3.0.4 + hast-util-raw: 9.1.0 + vfile: 6.0.3 + + rehype-recma@1.0.0: + dependencies: + '@types/estree': 1.0.8 + '@types/hast': 3.0.4 + hast-util-to-estree: 3.1.3 + transitivePeerDependencies: + - supports-color + + relateurl@0.2.7: {} + + remark-directive@3.0.1: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-directive: 3.1.0 + micromark-extension-directive: 3.0.2 + unified: 11.0.5 + transitivePeerDependencies: + - supports-color + + remark-emoji@4.0.1: + dependencies: + '@types/mdast': 4.0.4 + emoticon: 4.1.0 + mdast-util-find-and-replace: 3.0.2 + node-emoji: 2.2.0 + unified: 11.0.5 + + remark-frontmatter@5.0.0: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-frontmatter: 2.0.1 + micromark-extension-frontmatter: 2.0.0 + unified: 11.0.5 + transitivePeerDependencies: + - supports-color + + remark-gfm@4.0.1: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-gfm: 3.1.0 + micromark-extension-gfm: 3.0.0 + remark-parse: 11.0.0 + remark-stringify: 11.0.0 + unified: 11.0.5 + transitivePeerDependencies: + - supports-color + + remark-mdx@3.1.1: + dependencies: + mdast-util-mdx: 3.0.0 + micromark-extension-mdxjs: 3.0.0 + transitivePeerDependencies: + - supports-color + + remark-parse@11.0.0: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-from-markdown: 2.0.2 + micromark-util-types: 2.0.2 + unified: 11.0.5 + transitivePeerDependencies: + - supports-color + + remark-rehype@11.1.2: + dependencies: + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + mdast-util-to-hast: 13.2.1 + unified: 11.0.5 + vfile: 6.0.3 + + remark-stringify@11.0.0: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-to-markdown: 2.1.2 + unified: 11.0.5 + + renderkid@3.0.0: + dependencies: + css-select: 4.3.0 + dom-converter: 0.2.0 + htmlparser2: 6.1.0 + lodash: 4.17.21 + strip-ansi: 6.0.1 + + repeat-string@1.6.1: {} + req-cwd@2.0.0: dependencies: req-from: 2.0.0 @@ -11053,10 +20415,20 @@ snapshots: require-from-string@2.0.2: {} + require-like@0.1.2: {} + require-main-filename@2.0.0: {} + requires-port@1.0.0: {} + + resolve-alpn@1.2.1: {} + resolve-from@3.0.0: {} + resolve-from@4.0.0: {} + + resolve-pathname@3.0.0: {} + resolve@1.1.7: {} resolve@1.17.0: @@ -11069,6 +20441,10 @@ snapshots: path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 + responselike@3.0.0: + dependencies: + lowercase-keys: 3.0.0 + retry@0.12.0: {} retry@0.13.1: {} @@ -11125,6 +20501,15 @@ snapshots: bufferutil: 4.0.9 utf-8-validate: 5.0.10 + rtlcss@4.3.0: + dependencies: + escalade: 3.2.0 + picocolors: 1.1.1 + postcss: 8.5.6 + strip-json-comments: 3.1.1 + + run-applescript@7.1.0: {} + run-parallel@1.2.0: dependencies: queue-microtask: 1.2.3 @@ -11143,6 +20528,8 @@ snapshots: safer-buffer@2.1.2: {} + sax@1.4.4: {} + sc-istanbul@0.4.6: dependencies: abbrev: 1.0.9 @@ -11164,6 +20551,23 @@ snapshots: dependencies: loose-envify: 1.4.0 + scheduler@0.27.0: {} + + schema-dts@1.1.5: {} + + schema-utils@3.3.0: + dependencies: + '@types/json-schema': 7.0.15 + ajv: 6.12.6 + ajv-keywords: 3.5.2(ajv@6.12.6) + + schema-utils@4.3.3: + dependencies: + '@types/json-schema': 7.0.15 + ajv: 8.17.1 + ajv-formats: 2.1.1(ajv@8.17.1) + ajv-keywords: 5.1.0(ajv@8.17.1) + scrypt-js@3.0.1: {} secp256k1@4.0.4: @@ -11172,16 +20576,81 @@ snapshots: node-addon-api: 5.1.0 node-gyp-build: 4.8.4 + section-matter@1.0.0: + dependencies: + extend-shallow: 2.0.1 + kind-of: 6.0.3 + + select-hose@2.0.0: {} + + selfsigned@5.5.0: + dependencies: + '@peculiar/x509': 1.14.3 + pkijs: 3.3.3 + + semver-diff@4.0.0: + dependencies: + semver: 7.7.3 + semver@5.7.2: {} semver@6.3.1: {} semver@7.7.3: {} + send@0.19.2: + dependencies: + debug: 2.6.9 + depd: 2.0.0 + destroy: 1.2.0 + encodeurl: 2.0.0 + escape-html: 1.0.3 + etag: 1.8.1 + fresh: 0.5.2 + http-errors: 2.0.1 + mime: 1.6.0 + ms: 2.1.3 + on-finished: 2.4.1 + range-parser: 1.2.1 + statuses: 2.0.2 + transitivePeerDependencies: + - supports-color + serialize-javascript@6.0.2: dependencies: randombytes: 2.1.0 + serve-handler@6.1.6: + dependencies: + bytes: 3.0.0 + content-disposition: 0.5.2 + mime-types: 2.1.18 + minimatch: 3.1.2 + path-is-inside: 1.0.2 + path-to-regexp: 3.3.0 + range-parser: 1.2.0 + + serve-index@1.9.1: + dependencies: + accepts: 1.3.8 + batch: 0.6.1 + debug: 2.6.9 + escape-html: 1.0.3 + http-errors: 1.6.3 + mime-types: 2.1.35 + parseurl: 1.3.3 + transitivePeerDependencies: + - supports-color + + serve-static@1.16.3: + dependencies: + encodeurl: 2.0.0 + escape-html: 1.0.3 + parseurl: 1.3.3 + send: 0.19.2 + transitivePeerDependencies: + - supports-color + set-blocking@2.0.0: {} set-function-length@1.2.2: @@ -11195,6 +20664,8 @@ snapshots: setimmediate@1.0.5: {} + setprototypeof@1.1.0: {} + setprototypeof@1.2.0: {} sha.js@2.4.12: @@ -11208,6 +20679,20 @@ snapshots: charenc: 0.0.2 crypt: 0.0.2 + shallow-clone@3.0.1: + dependencies: + kind-of: 6.0.3 + + shallowequal@1.1.0: {} + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} + + shell-quote@1.8.3: {} + shelljs@0.8.5: dependencies: glob: 7.2.3 @@ -11246,16 +20731,40 @@ snapshots: signal-exit@3.0.7: {} + sirv@2.0.4: + dependencies: + '@polka/url': 1.0.0-next.29 + mrmime: 2.0.1 + totalist: 3.0.1 + sisteransi@1.0.5: {} + sitemap@7.1.2: + dependencies: + '@types/node': 17.0.45 + '@types/sax': 1.2.7 + arg: 5.0.2 + sax: 1.4.4 + + skin-tone@2.0.0: + dependencies: + unicode-emoji-modifier-base: 1.0.0 + slash@3.0.0: {} + slash@4.0.0: {} + slice-ansi@4.0.0: dependencies: ansi-styles: 4.3.0 astral-regex: 2.0.0 is-fullwidth-code-point: 3.0.0 + snake-case@3.0.4: + dependencies: + dot-case: 3.0.4 + tslib: 2.8.1 + socket.io-client@4.8.1(bufferutil@4.0.9)(utf-8-validate@5.0.10): dependencies: '@socket.io/component-emitter': 3.1.2 @@ -11274,6 +20783,12 @@ snapshots: transitivePeerDependencies: - supports-color + sockjs@0.3.24: + dependencies: + faye-websocket: 0.11.4 + uuid: 8.3.2 + websocket-driver: 0.7.4 + solc@0.8.26(debug@4.4.3): dependencies: command-exists: 1.2.9 @@ -11288,7 +20803,7 @@ snapshots: solidity-ast@0.4.61: {} - solidity-coverage@0.8.17(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10)): + solidity-coverage@0.8.17(hardhat@2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.6.3))(typescript@5.6.3)(utf-8-validate@5.0.10)): dependencies: '@ethersproject/abi': 5.8.0 '@solidity-parser/parser': 0.20.2 @@ -11299,7 +20814,7 @@ snapshots: ghost-testrpc: 0.0.2 global-modules: 2.0.0 globby: 10.0.2 - hardhat: 2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@5.0.10) + hardhat: 2.28.0(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.6.3))(typescript@5.6.3)(utf-8-validate@5.0.10) jsonschema: 1.5.0 lodash: 4.17.21 mocha: 10.8.2 @@ -11315,6 +20830,8 @@ snapshots: dependencies: atomic-sleep: 1.0.0 + sort-css-media-queries@2.2.0: {} + source-map-js@1.2.1: {} source-map-support@0.5.21: @@ -11329,6 +20846,31 @@ snapshots: source-map@0.6.1: {} + source-map@0.7.6: {} + + space-separated-tokens@2.0.2: {} + + spdy-transport@3.0.0: + dependencies: + debug: 4.4.3(supports-color@8.1.1) + detect-node: 2.1.0 + hpack.js: 2.1.6 + obuf: 1.1.2 + readable-stream: 3.6.2 + wbuf: 1.7.3 + transitivePeerDependencies: + - supports-color + + spdy@4.0.2: + dependencies: + debug: 4.4.3(supports-color@8.1.1) + handle-thing: 2.0.1 + http-deceiver: 1.2.7 + select-hose: 2.0.0 + spdy-transport: 3.0.0 + transitivePeerDependencies: + - supports-color + split-on-first@1.1.0: {} split2@3.2.2: @@ -11339,12 +20881,16 @@ snapshots: sprintf-js@1.0.3: {} + srcset@4.0.0: {} + stackback@0.0.2: {} stacktrace-parser@0.1.11: dependencies: type-fest: 0.7.1 + statuses@1.5.0: {} + statuses@2.0.2: {} std-env@3.10.0: {} @@ -11372,6 +20918,12 @@ snapshots: is-fullwidth-code-point: 3.0.0 strip-ansi: 6.0.1 + string-width@5.1.2: + dependencies: + eastasianwidth: 0.2.0 + emoji-regex: 9.2.2 + strip-ansi: 7.1.2 + string_decoder@1.1.1: dependencies: safe-buffer: 5.1.2 @@ -11380,6 +20932,17 @@ snapshots: dependencies: safe-buffer: 5.2.1 + stringify-entities@4.0.4: + dependencies: + character-entities-html4: 2.1.0 + character-entities-legacy: 3.0.0 + + stringify-object@3.3.0: + dependencies: + get-own-enumerable-property-symbols: 3.0.2 + is-obj: 1.0.1 + is-regexp: 1.0.0 + strip-ansi@4.0.0: dependencies: ansi-regex: 3.0.1 @@ -11388,10 +20951,20 @@ snapshots: dependencies: ansi-regex: 5.0.1 + strip-ansi@7.1.2: + dependencies: + ansi-regex: 6.2.2 + + strip-bom-string@1.0.0: {} + + strip-final-newline@2.0.0: {} + strip-hex-prefix@1.0.0: dependencies: is-hex-prefixed: 1.0.0 + strip-json-comments@2.0.1: {} + strip-json-comments@3.1.1: {} strip-literal@3.1.0: @@ -11400,6 +20973,20 @@ snapshots: strnum@2.1.2: {} + style-to-js@1.1.21: + dependencies: + style-to-object: 1.0.14 + + style-to-object@1.0.14: + dependencies: + inline-style-parser: 0.2.7 + + stylehacks@6.1.1(postcss@8.5.6): + dependencies: + browserslist: 4.28.1 + postcss: 8.5.6 + postcss-selector-parser: 6.1.2 + sucrase@3.35.1: dependencies: '@jridgewell/gen-mapping': 0.3.13 @@ -11432,6 +21019,18 @@ snapshots: supports-preserve-symlinks-flag@1.0.0: {} + svg-parser@2.0.4: {} + + svgo@3.3.2: + dependencies: + '@trysound/sax': 0.2.0 + commander: 7.2.0 + css-select: 5.2.2 + css-tree: 2.3.1 + css-what: 6.2.2 + csso: 5.0.5 + picocolors: 1.1.1 + sync-request@6.1.0: dependencies: http-response-object: 3.0.2 @@ -11485,6 +21084,24 @@ snapshots: - tsx - yaml + tapable@2.3.0: {} + + terser-webpack-plugin@5.3.16(webpack@5.104.1): + dependencies: + '@jridgewell/trace-mapping': 0.3.31 + jest-worker: 27.5.1 + schema-utils: 4.3.3 + serialize-javascript: 6.0.2 + terser: 5.46.0 + webpack: 5.104.1 + + terser@5.46.0: + dependencies: + '@jridgewell/source-map': 0.3.11 + acorn: 8.15.0 + commander: 2.20.3 + source-map-support: 0.5.21 + text-encoding-utf-8@1.0.2: {} then-request@6.0.2: @@ -11509,6 +21126,10 @@ snapshots: dependencies: any-promise: 1.3.0 + thingies@2.5.0(tslib@2.8.1): + dependencies: + tslib: 2.8.1 + thread-stream@0.15.2: dependencies: real-require: 0.1.0 @@ -11517,6 +21138,12 @@ snapshots: dependencies: readable-stream: 3.6.2 + thunky@1.1.0: {} + + tiny-invariant@1.3.3: {} + + tiny-warning@1.0.3: {} + tinybench@2.9.0: {} tinyexec@0.3.2: {} @@ -11548,8 +21175,18 @@ snapshots: toidentifier@1.0.1: {} + totalist@3.0.1: {} + tr46@0.0.3: {} + tree-dump@1.1.0(tslib@2.8.1): + dependencies: + tslib: 2.8.1 + + trim-lines@3.0.1: {} + + trough@2.2.0: {} + ts-command-line-args@2.5.1: dependencies: chalk: 4.1.2 @@ -11557,13 +21194,13 @@ snapshots: command-line-usage: 6.1.3 string-format: 2.0.0 - ts-essentials@7.0.3(typescript@5.9.3): + ts-essentials@7.0.3(typescript@5.6.3): dependencies: - typescript: 5.9.3 + typescript: 5.6.3 ts-interface-checker@0.1.13: {} - ts-node@10.9.2(@types/node@22.7.5)(typescript@5.9.3): + ts-node@10.9.2(@types/node@22.7.5)(typescript@5.6.3): dependencies: '@cspotcode/source-map-support': 0.8.1 '@tsconfig/node10': 1.0.12 @@ -11577,7 +21214,7 @@ snapshots: create-require: 1.1.1 diff: 4.0.2 make-error: 1.3.6 - typescript: 5.9.3 + typescript: 5.6.3 v8-compile-cache-lib: 3.0.1 yn: 3.1.1 @@ -11589,6 +21226,10 @@ snapshots: tsort@0.0.1: {} + tsyringe@4.10.0: + dependencies: + tslib: 1.14.1 + tweetnacl@1.0.3: {} type-check@0.3.2: @@ -11603,7 +21244,16 @@ snapshots: type-fest@0.7.1: {} - typechain@8.3.2(typescript@5.9.3): + type-fest@1.4.0: {} + + type-fest@2.19.0: {} + + type-is@1.6.18: + dependencies: + media-typer: 0.3.0 + mime-types: 2.1.35 + + typechain@8.3.2(typescript@5.6.3): dependencies: '@types/prettier': 2.7.3 debug: 4.4.3(supports-color@8.1.1) @@ -11614,8 +21264,8 @@ snapshots: mkdirp: 1.0.4 prettier: 2.8.8 ts-command-line-args: 2.5.1 - ts-essentials: 7.0.3(typescript@5.9.3) - typescript: 5.9.3 + ts-essentials: 7.0.3(typescript@5.6.3) + typescript: 5.6.3 transitivePeerDependencies: - supports-color @@ -11625,9 +21275,13 @@ snapshots: es-errors: 1.3.0 is-typed-array: 1.1.15 + typedarray-to-buffer@3.1.5: + dependencies: + is-typedarray: 1.0.0 + typedarray@0.0.6: {} - typescript@5.9.3: {} + typescript@5.6.3: {} typical@4.0.0: {} @@ -11660,6 +21314,60 @@ snapshots: unfetch@4.2.0: {} + unicode-canonical-property-names-ecmascript@2.0.1: {} + + unicode-emoji-modifier-base@1.0.0: {} + + unicode-match-property-ecmascript@2.0.0: + dependencies: + unicode-canonical-property-names-ecmascript: 2.0.1 + unicode-property-aliases-ecmascript: 2.2.0 + + unicode-match-property-value-ecmascript@2.2.1: {} + + unicode-property-aliases-ecmascript@2.2.0: {} + + unified@11.0.5: + dependencies: + '@types/unist': 3.0.3 + bail: 2.0.2 + devlop: 1.1.0 + extend: 3.0.2 + is-plain-obj: 4.1.0 + trough: 2.2.0 + vfile: 6.0.3 + + unique-string@3.0.0: + dependencies: + crypto-random-string: 4.0.0 + + unist-util-is@6.0.1: + dependencies: + '@types/unist': 3.0.3 + + unist-util-position-from-estree@2.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-position@5.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-stringify-position@4.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-visit-parents@6.0.2: + dependencies: + '@types/unist': 3.0.3 + unist-util-is: 6.0.1 + + unist-util-visit@5.0.0: + dependencies: + '@types/unist': 3.0.3 + unist-util-is: 6.0.1 + unist-util-visit-parents: 6.0.2 + universalify@0.1.2: {} universalify@2.0.1: {} @@ -11685,6 +21393,36 @@ snapshots: escalade: 3.2.0 picocolors: 1.1.1 + update-notifier@6.0.2: + dependencies: + boxen: 7.1.1 + chalk: 5.6.2 + configstore: 6.0.0 + has-yarn: 3.0.0 + import-lazy: 4.0.0 + is-ci: 3.0.1 + is-installed-globally: 0.4.0 + is-npm: 6.1.0 + is-yarn-global: 0.4.1 + latest-version: 7.0.0 + pupa: 3.3.0 + semver: 7.7.3 + semver-diff: 4.0.0 + xdg-basedir: 5.1.0 + + uri-js@4.4.1: + dependencies: + punycode: 2.3.1 + + url-loader@4.1.1(file-loader@6.2.0(webpack@5.104.1))(webpack@5.104.1): + dependencies: + loader-utils: 2.0.4 + mime-types: 2.1.35 + schema-utils: 3.3.0 + webpack: 5.104.1 + optionalDependencies: + file-loader: 6.2.0(webpack@5.104.1) + use-callback-ref@1.3.3(@types/react@18.3.27)(react@18.3.1): dependencies: react: 18.3.1 @@ -11724,6 +21462,12 @@ snapshots: is-typed-array: 1.1.15 which-typed-array: 1.1.19 + utila@0.4.0: {} + + utility-types@3.11.0: {} + + utils-merge@1.0.1: {} + uuid@8.3.2: {} uuid@9.0.1: {} @@ -11739,81 +21483,100 @@ snapshots: '@types/react': 18.3.27 react: 18.3.1 - viem@2.23.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1): + value-equal@1.0.1: {} + + vary@1.1.2: {} + + vfile-location@5.0.3: + dependencies: + '@types/unist': 3.0.3 + vfile: 6.0.3 + + vfile-message@4.0.3: + dependencies: + '@types/unist': 3.0.3 + unist-util-stringify-position: 4.0.0 + + vfile@6.0.3: + dependencies: + '@types/unist': 3.0.3 + vfile-message: 4.0.3 + + viem@2.23.2(bufferutil@4.0.9)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.25.76): dependencies: '@noble/curves': 1.8.1 '@noble/hashes': 1.7.1 '@scure/bip32': 1.6.2 '@scure/bip39': 1.5.4 - abitype: 1.0.8(typescript@5.9.3)(zod@4.2.1) + abitype: 1.0.8(typescript@5.6.3)(zod@3.25.76) isows: 1.0.6(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) - ox: 0.6.7(typescript@5.9.3)(zod@4.2.1) + ox: 0.6.7(typescript@5.6.3)(zod@3.25.76) ws: 8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) optionalDependencies: - typescript: 5.9.3 + typescript: 5.6.3 transitivePeerDependencies: - bufferutil - utf-8-validate - zod - viem@2.43.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.22.4): + viem@2.43.1(bufferutil@4.0.9)(typescript@5.6.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) + abitype: 1.2.3(typescript@5.6.3)(zod@3.22.4) isows: 1.0.7(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) - ox: 0.10.5(typescript@5.9.3)(zod@3.22.4) + ox: 0.10.5(typescript@5.6.3)(zod@3.22.4) ws: 8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10) optionalDependencies: - typescript: 5.9.3 + typescript: 5.6.3 transitivePeerDependencies: - bufferutil - utf-8-validate - zod - viem@2.43.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76): + viem@2.43.1(bufferutil@4.0.9)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.25.76): dependencies: '@noble/curves': 1.9.1 '@noble/hashes': 1.8.0 '@scure/bip32': 1.7.0 '@scure/bip39': 1.6.0 - abitype: 1.2.3(typescript@5.9.3)(zod@3.25.76) + abitype: 1.2.3(typescript@5.6.3)(zod@3.25.76) isows: 1.0.7(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) - ox: 0.10.5(typescript@5.9.3)(zod@3.25.76) + ox: 0.10.5(typescript@5.6.3)(zod@3.25.76) ws: 8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10) optionalDependencies: - typescript: 5.9.3 + typescript: 5.6.3 transitivePeerDependencies: - bufferutil - utf-8-validate - zod - viem@2.43.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1): + viem@2.43.1(bufferutil@4.0.9)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@4.2.1): 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.2.1) + abitype: 1.2.3(typescript@5.6.3)(zod@4.2.1) isows: 1.0.7(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) - ox: 0.10.5(typescript@5.9.3)(zod@4.2.1) + ox: 0.10.5(typescript@5.6.3)(zod@4.2.1) ws: 8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10) optionalDependencies: - typescript: 5.9.3 + typescript: 5.6.3 transitivePeerDependencies: - bufferutil - utf-8-validate - zod - vite-node@3.2.4(@types/node@20.19.27): + vite-node@3.2.4(@types/node@20.19.27)(terser@5.46.0): dependencies: cac: 6.7.14 debug: 4.4.3(supports-color@8.1.1) es-module-lexer: 1.7.0 pathe: 2.0.3 - vite: 5.4.21(@types/node@20.19.27) + vite: 5.4.21(@types/node@20.19.27)(terser@5.46.0) transitivePeerDependencies: - '@types/node' - less @@ -11825,13 +21588,13 @@ snapshots: - supports-color - terser - vite-node@3.2.4(@types/node@22.7.5): + vite-node@3.2.4(@types/node@22.7.5)(terser@5.46.0): dependencies: cac: 6.7.14 debug: 4.4.3(supports-color@8.1.1) es-module-lexer: 1.7.0 pathe: 2.0.3 - vite: 5.4.21(@types/node@22.7.5) + vite: 5.4.21(@types/node@22.7.5)(terser@5.46.0) transitivePeerDependencies: - '@types/node' - less @@ -11843,11 +21606,11 @@ snapshots: - supports-color - terser - vite-plugin-wasm@3.5.0(vite@5.4.21(@types/node@22.7.5)): + vite-plugin-wasm@3.5.0(vite@5.4.21(@types/node@22.7.5)(terser@5.46.0)): dependencies: - vite: 5.4.21(@types/node@22.7.5) + vite: 5.4.21(@types/node@22.7.5)(terser@5.46.0) - vite@5.4.21(@types/node@20.19.27): + vite@5.4.21(@types/node@20.19.27)(terser@5.46.0): dependencies: esbuild: 0.21.5 postcss: 8.5.6 @@ -11855,8 +21618,9 @@ snapshots: optionalDependencies: '@types/node': 20.19.27 fsevents: 2.3.3 + terser: 5.46.0 - vite@5.4.21(@types/node@22.7.5): + vite@5.4.21(@types/node@22.7.5)(terser@5.46.0): dependencies: esbuild: 0.21.5 postcss: 8.5.6 @@ -11864,12 +21628,13 @@ snapshots: optionalDependencies: '@types/node': 22.7.5 fsevents: 2.3.3 + terser: 5.46.0 - vitest@3.2.4(@types/debug@4.1.12)(@types/node@20.19.27): + vitest@3.2.4(@types/debug@4.1.12)(@types/node@20.19.27)(terser@5.46.0): dependencies: '@types/chai': 5.2.3 '@vitest/expect': 3.2.4 - '@vitest/mocker': 3.2.4(vite@5.4.21(@types/node@20.19.27)) + '@vitest/mocker': 3.2.4(vite@5.4.21(@types/node@20.19.27)(terser@5.46.0)) '@vitest/pretty-format': 3.2.4 '@vitest/runner': 3.2.4 '@vitest/snapshot': 3.2.4 @@ -11887,8 +21652,8 @@ snapshots: tinyglobby: 0.2.15 tinypool: 1.1.1 tinyrainbow: 2.0.0 - vite: 5.4.21(@types/node@20.19.27) - vite-node: 3.2.4(@types/node@20.19.27) + vite: 5.4.21(@types/node@20.19.27)(terser@5.46.0) + vite-node: 3.2.4(@types/node@20.19.27)(terser@5.46.0) why-is-node-running: 2.3.0 optionalDependencies: '@types/debug': 4.1.12 @@ -11904,11 +21669,11 @@ snapshots: - supports-color - terser - vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.7.5): + vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.7.5)(terser@5.46.0): dependencies: '@types/chai': 5.2.3 '@vitest/expect': 3.2.4 - '@vitest/mocker': 3.2.4(vite@5.4.21(@types/node@20.19.27)) + '@vitest/mocker': 3.2.4(vite@5.4.21(@types/node@22.7.5)(terser@5.46.0)) '@vitest/pretty-format': 3.2.4 '@vitest/runner': 3.2.4 '@vitest/snapshot': 3.2.4 @@ -11926,8 +21691,8 @@ snapshots: tinyglobby: 0.2.15 tinypool: 1.1.1 tinyrainbow: 2.0.0 - vite: 5.4.21(@types/node@22.7.5) - vite-node: 3.2.4(@types/node@22.7.5) + vite: 5.4.21(@types/node@22.7.5)(terser@5.46.0) + vite-node: 3.2.4(@types/node@22.7.5)(terser@5.46.0) why-is-node-running: 2.3.0 optionalDependencies: '@types/debug': 4.1.12 @@ -11943,16 +21708,16 @@ snapshots: - supports-color - terser - wagmi@2.19.5(@tanstack/query-core@5.90.12)(@tanstack/react-query@5.90.12(react@18.3.1))(@types/react@18.3.27)(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(immer@10.0.2)(react@18.3.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.43.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1))(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@4.2.1): + wagmi@2.19.5(@tanstack/query-core@5.90.12)(@tanstack/react-query@5.90.12(react@18.3.1))(@types/react@18.3.27)(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(immer@10.0.2)(react@18.3.1)(typescript@5.6.3)(utf-8-validate@5.0.10)(viem@2.43.1(bufferutil@4.0.9)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.25.76))(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76): dependencies: '@tanstack/react-query': 5.90.12(react@18.3.1) - '@wagmi/connectors': 6.2.0(3e683225d0eaab4e1b5a92e5a7d66afa) - '@wagmi/core': 2.22.1(@tanstack/query-core@5.90.12)(@types/react@18.3.27)(immer@10.0.2)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@18.3.1))(viem@2.43.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1)) + '@wagmi/connectors': 6.2.0(d21a8c3adbd777f8e242ee40accde91d) + '@wagmi/core': 2.22.1(@tanstack/query-core@5.90.12)(@types/react@18.3.27)(immer@10.0.2)(react@18.3.1)(typescript@5.6.3)(use-sync-external-store@1.4.0(react@18.3.1))(viem@2.43.1(bufferutil@4.0.9)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.25.76)) react: 18.3.1 use-sync-external-store: 1.4.0(react@18.3.1) - viem: 2.43.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.2.1) + viem: 2.43.1(bufferutil@4.0.9)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.25.76) optionalDependencies: - typescript: 5.9.3 + typescript: 5.6.3 transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -11989,6 +21754,17 @@ snapshots: - ws - zod + watchpack@2.5.1: + dependencies: + glob-to-regexp: 0.4.1 + graceful-fs: 4.2.11 + + wbuf@1.7.3: + dependencies: + minimalistic-assert: 1.0.1 + + web-namespaces@2.0.1: {} + web3-utils@1.10.4: dependencies: '@ethereumjs/util': 8.1.0 @@ -12004,6 +21780,142 @@ snapshots: webidl-conversions@3.0.1: {} + webpack-bundle-analyzer@4.10.2(bufferutil@4.0.9)(utf-8-validate@5.0.10): + dependencies: + '@discoveryjs/json-ext': 0.5.7 + acorn: 8.15.0 + acorn-walk: 8.3.4 + commander: 7.2.0 + debounce: 1.2.1 + escape-string-regexp: 4.0.0 + gzip-size: 6.0.0 + html-escaper: 2.0.2 + opener: 1.5.2 + picocolors: 1.1.1 + sirv: 2.0.4 + ws: 7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10) + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + webpack-dev-middleware@7.4.5(tslib@2.8.1)(webpack@5.104.1): + dependencies: + colorette: 2.0.20 + memfs: 4.56.4(tslib@2.8.1) + mime-types: 3.0.2 + on-finished: 2.4.1 + range-parser: 1.2.1 + schema-utils: 4.3.3 + optionalDependencies: + webpack: 5.104.1 + transitivePeerDependencies: + - tslib + + webpack-dev-server@5.2.3(bufferutil@4.0.9)(tslib@2.8.1)(utf-8-validate@5.0.10)(webpack@5.104.1): + dependencies: + '@types/bonjour': 3.5.13 + '@types/connect-history-api-fallback': 1.5.4 + '@types/express': 4.17.25 + '@types/express-serve-static-core': 4.19.8 + '@types/serve-index': 1.9.4 + '@types/serve-static': 1.15.10 + '@types/sockjs': 0.3.36 + '@types/ws': 8.18.1 + ansi-html-community: 0.0.8 + bonjour-service: 1.3.0 + chokidar: 3.6.0 + colorette: 2.0.20 + compression: 1.8.1 + connect-history-api-fallback: 2.0.0 + express: 4.22.1 + graceful-fs: 4.2.11 + http-proxy-middleware: 2.0.9(@types/express@4.17.25) + ipaddr.js: 2.3.0 + launch-editor: 2.12.0 + open: 10.2.0 + p-retry: 6.2.1 + schema-utils: 4.3.3 + selfsigned: 5.5.0 + serve-index: 1.9.1 + sockjs: 0.3.24 + spdy: 4.0.2 + webpack-dev-middleware: 7.4.5(tslib@2.8.1)(webpack@5.104.1) + ws: 8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10) + optionalDependencies: + webpack: 5.104.1 + transitivePeerDependencies: + - bufferutil + - debug + - supports-color + - tslib + - utf-8-validate + + webpack-merge@5.10.0: + dependencies: + clone-deep: 4.0.1 + flat: 5.0.2 + wildcard: 2.0.1 + + webpack-merge@6.0.1: + dependencies: + clone-deep: 4.0.1 + flat: 5.0.2 + wildcard: 2.0.1 + + webpack-sources@3.3.3: {} + + webpack@5.104.1: + dependencies: + '@types/eslint-scope': 3.7.7 + '@types/estree': 1.0.8 + '@types/json-schema': 7.0.15 + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/wasm-edit': 1.14.1 + '@webassemblyjs/wasm-parser': 1.14.1 + acorn: 8.15.0 + acorn-import-phases: 1.0.4(acorn@8.15.0) + browserslist: 4.28.1 + chrome-trace-event: 1.0.4 + enhanced-resolve: 5.18.4 + es-module-lexer: 2.0.0 + eslint-scope: 5.1.1 + events: 3.3.0 + glob-to-regexp: 0.4.1 + graceful-fs: 4.2.11 + json-parse-even-better-errors: 2.3.1 + loader-runner: 4.3.1 + mime-types: 2.1.35 + neo-async: 2.6.2 + schema-utils: 4.3.3 + tapable: 2.3.0 + terser-webpack-plugin: 5.3.16(webpack@5.104.1) + watchpack: 2.5.1 + webpack-sources: 3.3.3 + transitivePeerDependencies: + - '@swc/core' + - esbuild + - uglify-js + + webpackbar@6.0.1(webpack@5.104.1): + dependencies: + ansi-escapes: 4.3.2 + chalk: 4.1.2 + consola: 3.4.2 + figures: 3.2.0 + markdown-table: 2.0.0 + pretty-time: 1.1.0 + std-env: 3.10.0 + webpack: 5.104.1 + wrap-ansi: 7.0.0 + + websocket-driver@0.7.4: + dependencies: + http-parser-js: 0.5.10 + safe-buffer: 5.2.1 + websocket-extensions: 0.1.4 + + websocket-extensions@0.1.4: {} + whatwg-url@5.0.0: dependencies: tr46: 0.0.3 @@ -12025,6 +21937,10 @@ snapshots: dependencies: isexe: 2.0.0 + which@2.0.2: + dependencies: + isexe: 2.0.0 + why-is-node-running@2.3.0: dependencies: siginfo: 2.0.0 @@ -12034,6 +21950,12 @@ snapshots: dependencies: string-width: 4.2.3 + widest-line@4.0.1: + dependencies: + string-width: 5.1.2 + + wildcard@2.0.1: {} + word-wrap@1.2.5: {} wordwrap@1.0.0: {} @@ -12057,8 +21979,21 @@ snapshots: string-width: 4.2.3 strip-ansi: 6.0.1 + wrap-ansi@8.1.0: + dependencies: + ansi-styles: 6.2.3 + string-width: 5.1.2 + strip-ansi: 7.1.2 + wrappy@1.0.2: {} + write-file-atomic@3.0.3: + dependencies: + imurmurhash: 0.1.4 + is-typedarray: 1.0.0 + signal-exit: 3.0.7 + typedarray-to-buffer: 3.1.5 + ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10): optionalDependencies: bufferutil: 4.0.9 @@ -12079,6 +22014,16 @@ snapshots: bufferutil: 4.0.9 utf-8-validate: 5.0.10 + wsl-utils@0.1.0: + dependencies: + is-wsl: 3.1.0 + + xdg-basedir@5.1.0: {} + + xml-js@1.6.11: + dependencies: + sax: 1.4.4 + xmlhttprequest-ssl@2.1.2: {} xtend@4.0.2: {} @@ -12131,6 +22076,8 @@ snapshots: yocto-queue@0.1.0: {} + yocto-queue@1.2.2: {} + zod@3.22.4: {} zod@3.25.76: {} @@ -12157,3 +22104,5 @@ snapshots: immer: 10.0.2 react: 18.3.1 use-sync-external-store: 1.4.0(react@18.3.1) + + zwitch@2.0.4: {} diff --git a/verbeth-client-plan.md b/verbeth-client-plan.md deleted file mode 100644 index b92f58f..0000000 --- a/verbeth-client-plan.md +++ /dev/null @@ -1,1236 +0,0 @@ -# VerbethClient SDK Improvements: Implementation Guide - -## Executive Summary - -This document provides concrete implementation details for the VerbethClient improvement plan. The changes centralize session management into the SDK while allowing apps to provide their own storage adapters. - ---- - -## Current Pain Points (from codebase analysis) - -| Problem | Where it occurs | -|---------|-----------------| -| Session lookup logic duplicated | `RatchetDbService.getRatchetSessionByAnyInboundTopic()`, `EventProcessorService.processMessageEvent()` | -| Two-phase commit scattered | `useMessageQueue.ts` lines 139-254 | -| Session cache managed by app | `useMessageQueue.ts` line 77-78, `EventProcessorService.ts` line 539-569 | -| Pending outbound tracking manual | `useMessageQueue.ts` lines 170-182 | -| Topic promotion duplicated | `EventProcessorService.ts` lines 543-569 | - ---- - -## Milestone 1: Session Store Interface + Encrypt/Decrypt Helpers - -### 1.1 New SDK Types - -**File: `packages/sdk/src/client/types.ts`** - -```typescript -import { RatchetSession, MessageHeader, EncryptResult } from '../ratchet/types.js'; - -/** - * Storage interface for ratchet sessions. - * Implement this to connect VerbethClient to your storage layer. - */ -export interface SessionStore { - /** - * Get session by conversation ID (primary key). - */ - get(conversationId: string): Promise; - - /** - * Find session by any active inbound topic. - * Must check: currentTopicInbound, nextTopicInbound, previousTopicInbound (if not expired). - */ - getByInboundTopic(topic: string): Promise; - - /** - * Persist session state. - * Called after encrypt (immediate commit) and after decrypt. - */ - save(session: RatchetSession): Promise; -} - -/** - * Result of prepareMessage - contains everything needed to send and commit. - */ -export interface PreparedMessage { - /** Unique ID for this prepared message */ - id: string; - /** Conversation this message belongs to */ - conversationId: string; - /** Topic to publish to (may be ratcheted) */ - topic: `0x${string}`; - /** Binary payload ready for on-chain submission */ - payload: Uint8Array; - /** Original plaintext (for UI/storage) */ - plaintext: string; - /** Session state BEFORE encryption (for rollback if needed) */ - sessionBefore: RatchetSession; - /** Session state AFTER encryption (to persist on commit) */ - sessionAfter: RatchetSession; - /** Message number in the sending chain */ - messageNumber: number; - /** Timestamp when prepared */ - createdAt: number; -} - -/** - * Result of decryptMessage. - */ -export interface DecryptedMessage { - /** Conversation ID */ - conversationId: string; - /** Decrypted plaintext */ - plaintext: string; - /** Whether this was our own message (echo) */ - isOwnMessage: boolean; - /** Updated session state (must be persisted) */ - session: RatchetSession; - /** Topic the message arrived on */ - topic: string; - /** Which topic matched: 'current', 'next', or 'previous' */ - topicMatch: 'current' | 'next' | 'previous'; -} -``` - -### 1.2 Session Manager (Internal) - -**File: `packages/sdk/src/client/SessionManager.ts`** - -```typescript -import { RatchetSession, TOPIC_TRANSITION_WINDOW_MS } from '../ratchet/types.js'; -import { SessionStore } from './types.js'; - -/** - * Internal session coordinator. - * Handles topic matching, session lookup, and topic promotion. - */ -export class SessionManager { - private cache = new Map(); - - constructor(private store: SessionStore) {} - - /** - * Get session by conversation ID, checking cache first. - */ - async getByConversationId(conversationId: string): Promise { - // Check cache first - const cached = this.cache.get(conversationId); - if (cached) return cached; - - // Load from store - const session = await this.store.get(conversationId); - if (session) { - this.cache.set(conversationId, session); - } - return session; - } - - /** - * Find session by inbound topic with automatic topic promotion. - */ - async getByInboundTopic(topic: string): Promise<{ - session: RatchetSession; - topicMatch: 'current' | 'next' | 'previous'; - } | null> { - const topicLower = topic.toLowerCase(); - - // Try store's topic lookup - const session = await this.store.getByInboundTopic(topic); - if (!session) return null; - - // Check cache for more recent state - const cached = this.cache.get(session.conversationId); - let workingSession = cached || session; - - // Determine which topic matched and handle promotion - if (workingSession.currentTopicInbound.toLowerCase() === topicLower) { - return { session: workingSession, topicMatch: 'current' }; - } - - if (workingSession.nextTopicInbound?.toLowerCase() === topicLower) { - // Promote next topics to current - workingSession = this.promoteTopics(workingSession); - this.cache.set(workingSession.conversationId, workingSession); - return { session: workingSession, topicMatch: 'next' }; - } - - if ( - workingSession.previousTopicInbound?.toLowerCase() === topicLower && - workingSession.previousTopicExpiry && - Date.now() < workingSession.previousTopicExpiry - ) { - return { session: workingSession, topicMatch: 'previous' }; - } - - return null; - } - - /** - * Update session in cache and persist to store. - */ - async save(session: RatchetSession): Promise { - this.cache.set(session.conversationId, session); - await this.store.save(session); - } - - /** - * Update cache without persisting (for batch operations). - */ - updateCache(session: RatchetSession): void { - this.cache.set(session.conversationId, session); - } - - /** - * Invalidate cache entry (e.g., on session reset). - */ - invalidate(conversationId: string): void { - this.cache.delete(conversationId); - } - - /** - * Clear entire cache. - */ - clearCache(): void { - this.cache.clear(); - } - - /** - * Promote next topics to current (internal helper). - */ - private promoteTopics(session: RatchetSession): RatchetSession { - if (!session.nextTopicInbound || !session.nextTopicOutbound) { - return session; - } - - return { - ...session, - previousTopicInbound: session.currentTopicInbound, - previousTopicExpiry: Date.now() + TOPIC_TRANSITION_WINDOW_MS, - currentTopicInbound: session.nextTopicInbound, - currentTopicOutbound: session.nextTopicOutbound, - nextTopicInbound: undefined, - nextTopicOutbound: undefined, - topicEpoch: session.topicEpoch + 1, - updatedAt: Date.now(), - }; - } -} -``` - -### 1.3 VerbethClient Extensions - -**File: `packages/sdk/src/client/VerbethClient.ts`** (additions to existing class) - -```typescript -import { hexlify } from 'ethers'; -import { ratchetEncrypt, packageRatchetPayload } from '../ratchet/index.js'; -import { ratchetDecrypt, parseRatchetPayload, isRatchetPayload } from '../ratchet/decrypt.js'; -import { verifyMessageSignature } from '../ratchet/auth.js'; -import { SessionStore, PreparedMessage, DecryptedMessage } from './types.js'; -import { SessionManager } from './SessionManager.js'; - -// Add to VerbethClient class: - -export class VerbethClient { - // ... existing properties ... - - private sessionManager?: SessionManager; - - /** - * Configure session storage. - * Must be called before using prepareMessage/decryptMessage. - */ - setSessionStore(store: SessionStore): void { - this.sessionManager = new SessionManager(store); - } - - /** - * Prepare a message for sending (encrypt without persisting). - * - * Two-phase commit pattern: - * 1. prepareMessage() - encrypts and returns PreparedMessage - * 2. Send transaction using prepared.payload and prepared.topic - * 3. commitMessage() - persists session state after tx confirmation - * - * Session state is committed immediately for forward secrecy. - * If tx fails, the ratchet slot is "burned" (receiver handles via skip keys). - */ - async prepareMessage( - conversationId: string, - plaintext: string - ): Promise { - if (!this.sessionManager) { - throw new Error('SessionStore not configured. Call setSessionStore() first.'); - } - - const session = await this.sessionManager.getByConversationId(conversationId); - if (!session) { - throw new Error(`No session found for conversation: ${conversationId}`); - } - - const plaintextBytes = new TextEncoder().encode(plaintext); - - const encryptResult = ratchetEncrypt( - session, - plaintextBytes, - this.identityKeyPairInstance.signingSecretKey - ); - - const payload = packageRatchetPayload( - encryptResult.signature, - encryptResult.header, - encryptResult.ciphertext - ); - - // Immediately persist session state (forward secrecy) - await this.sessionManager.save(encryptResult.session); - - const prepared: PreparedMessage = { - id: `prep-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`, - conversationId, - topic: encryptResult.topic, - payload, - plaintext, - sessionBefore: session, - sessionAfter: encryptResult.session, - messageNumber: session.sendingMsgNumber, - createdAt: Date.now(), - }; - - return prepared; - } - - /** - * Commit a prepared message after successful tx. - * In the current design, session is already persisted in prepareMessage(). - * This method exists for API symmetry and future extensibility. - */ - async commitMessage(prepared: PreparedMessage): Promise { - // Session already saved in prepareMessage for forward secrecy. - // This method can be used for additional bookkeeping if needed. - } - - /** - * Decrypt an incoming message. - * Handles topic routing, signature verification, and session updates. - * - * @param topic - The topic the message arrived on - * @param payload - Raw message payload (Uint8Array) - * @param senderSigningKey - Sender's Ed25519 signing public key - * @param isOwnMessage - Whether this is our own outbound message (echo) - * @returns DecryptedMessage or null if decryption fails - */ - async decryptMessage( - topic: string, - payload: Uint8Array, - senderSigningKey: Uint8Array, - isOwnMessage: boolean = false - ): Promise { - if (!this.sessionManager) { - throw new Error('SessionStore not configured. Call setSessionStore() first.'); - } - - // Skip decryption for own messages (we already have plaintext) - if (isOwnMessage) { - return null; - } - - // Find session by topic - const result = await this.sessionManager.getByInboundTopic(topic); - if (!result) { - return null; - } - - const { session, topicMatch } = result; - - // Validate payload format - if (!isRatchetPayload(payload)) { - return null; - } - - const parsed = parseRatchetPayload(payload); - if (!parsed) { - return null; - } - - // AUTH-FIRST: Verify signature before any ratchet operations - const sigValid = verifyMessageSignature( - parsed.signature, - parsed.header, - parsed.ciphertext, - senderSigningKey - ); - - if (!sigValid) { - return null; - } - - // Decrypt - const decryptResult = ratchetDecrypt(session, parsed.header, parsed.ciphertext); - if (!decryptResult) { - return null; - } - - // Persist updated session - await this.sessionManager.save(decryptResult.session); - - const plaintextStr = new TextDecoder().decode(decryptResult.plaintext); - - return { - conversationId: session.conversationId, - plaintext: plaintextStr, - isOwnMessage: false, - session: decryptResult.session, - topic, - topicMatch, - }; - } - - /** - * Invalidate session cache for a conversation. - * Call after external session changes (e.g., session reset). - */ - invalidateSessionCache(conversationId: string): void { - this.sessionManager?.invalidate(conversationId); - } - - /** - * Clear all cached sessions. - */ - clearSessionCache(): void { - this.sessionManager?.clearCache(); - } -} -``` - -### 1.4 SDK Index Exports - -**File: `packages/sdk/src/client/index.ts`** - -```typescript -export { VerbethClient } from './VerbethClient.js'; -export type { - SessionStore, - PreparedMessage, - DecryptedMessage -} from './types.js'; -``` - -**Update `packages/sdk/src/index.ts`:** - -```typescript -// ... existing exports ... -export type { SessionStore, PreparedMessage, DecryptedMessage } from './client/index.js'; -``` - ---- - -## Milestone 2: Pending Message Manager - -### 2.1 Pending Store Interface - -**File: `packages/sdk/src/client/types.ts`** (additions) - -```typescript - -export type PendingStatus = 'preparing' | 'submitted' | 'confirmed' | 'failed'; - -/** - * Pending outbound message record. - */ -export interface PendingMessage { - /** Unique ID */ - id: string; - /** Conversation ID */ - conversationId: string; - /** Topic used for sending */ - topic: string; - /** Hex-encoded payload */ - payloadHex: string; - /** Original plaintext */ - plaintext: string; - /** Session state before encryption (serialized JSON) */ - sessionStateBefore: string; - /** Session state after encryption (serialized JSON) */ - sessionStateAfter: string; - /** Creation timestamp */ - createdAt: number; - /** Transaction hash (once submitted) */ - txHash: string | null; - /** Current status */ - status: PendingStatus; -} - -/** - * Storage interface for pending outbound messages. - */ -export interface PendingStore { - /** - * Save a new pending message. - */ - save(pending: PendingMessage): Promise; - - /** - * Get pending message by ID. - */ - get(id: string): Promise; - - /** - * Get pending message by transaction hash. - */ - getByTxHash(txHash: string): Promise; - - /** - * Update pending message status. - */ - updateStatus(id: string, status: PendingStatus, txHash?: string): Promise; - - /** - * Delete pending message (after confirmation or cancellation). - */ - delete(id: string): Promise; - - /** - * Get all pending messages for a conversation. - */ - getByConversation(conversationId: string): Promise; -} - -/** - * Result of sendMessage. - */ -export interface SendResult { - /** Message ID for tracking */ - messageId: string; - /** Transaction hash */ - txHash: string; - /** Topic the message was sent on */ - topic: string; - /** Message number in sending chain */ - messageNumber: number; -} - -/** - * Result of confirmTx. - */ -export interface ConfirmResult { - /** Conversation ID */ - conversationId: string; - /** Original plaintext */ - plaintext: string; - /** Message ID */ - messageId: string; -} -``` - -### 2.2 Pending Manager (Internal) - -**File: `packages/sdk/src/client/PendingManager.ts`** - -```typescript -import { hexlify } from 'ethers'; -import { PendingStore, PendingMessage, PendingStatus } from './types.js'; - -/** - * Internal pending message coordinator. - */ -export class PendingManager { - constructor(private store: PendingStore) {} - - /** - * Create and save a pending message record. - */ - async create(params: Omit): Promise { - const pending: PendingMessage = { - ...params, - txHash: null, - status: 'preparing', - }; - await this.store.save(pending); - return pending; - } - - /** - * Mark as submitted with transaction hash. - */ - async markSubmitted(id: string, txHash: string): Promise { - await this.store.updateStatus(id, 'submitted', txHash); - } - - /** - * Get pending by transaction hash. - */ - async getByTxHash(txHash: string): Promise { - return this.store.getByTxHash(txHash); - } - - /** - * Finalize (confirm) and delete. - */ - async finalize(id: string): Promise { - const pending = await this.store.get(id); - if (!pending) return null; - - await this.store.delete(id); - return pending; - } - - /** - * Mark as failed. - */ - async markFailed(id: string): Promise { - await this.store.updateStatus(id, 'failed'); - } - - /** - * Delete a pending message. - */ - async delete(id: string): Promise { - await this.store.delete(id); - } -} -``` - -### 2.3 VerbethClient Extensions (Milestone 2) - -**Add to `packages/sdk/src/client/VerbethClient.ts`:** - -```typescript -import { PendingStore, PendingMessage, SendResult, ConfirmResult } from './types.js'; -import { PendingManager } from './PendingManager.js'; - -// Add to VerbethClient class: - -export class VerbethClient { - // ... existing properties ... - - private pendingManager?: PendingManager; - - /** - * Configure pending message storage. - * Must be called before using sendMessage/confirmTx/revertTx. - */ - setPendingStore(store: PendingStore): void { - this.pendingManager = new PendingManager(store); - } - - /** - * Send a message with full lifecycle management. - * - * This is the high-level API that handles: - * 1. Encryption - * 2. Pending record creation - * 3. Transaction submission - * 4. Status tracking - * - * After calling this, wait for on-chain confirmation and call confirmTx(). - */ - async sendMessage( - conversationId: string, - plaintext: string - ): Promise { - if (!this.sessionManager) { - throw new Error('SessionStore not configured. Call setSessionStore() first.'); - } - if (!this.pendingManager) { - throw new Error('PendingStore not configured. Call setPendingStore() first.'); - } - if (!this.executorInstance) { - throw new Error('Executor not configured.'); - } - - // 1. Prepare message (encrypts and persists session) - const prepared = await this.prepareMessage(conversationId, plaintext); - - // 2. Create pending record - const pending = await this.pendingManager.create({ - id: prepared.id, - conversationId, - topic: prepared.topic, - payloadHex: hexlify(prepared.payload), - plaintext, - sessionStateBefore: JSON.stringify(this.serializeSession(prepared.sessionBefore)), - sessionStateAfter: JSON.stringify(this.serializeSession(prepared.sessionAfter)), - createdAt: prepared.createdAt, - }); - - // 3. Submit transaction - const timestamp = Math.floor(Date.now() / 1000); - const nonce = prepared.messageNumber; - - try { - const tx = await this.executorInstance.sendMessage( - prepared.payload, - prepared.topic, - timestamp, - BigInt(nonce) - ); - - // 4. Update pending with txHash - await this.pendingManager.markSubmitted(prepared.id, tx.hash); - - return { - messageId: prepared.id, - txHash: tx.hash, - topic: prepared.topic, - messageNumber: nonce, - }; - } catch (error) { - // Mark as failed (ratchet slot is burned) - await this.pendingManager.markFailed(prepared.id); - throw error; - } - } - - /** - * Confirm a transaction after on-chain confirmation. - * Call this when you see your MessageSent event on-chain. - * - * @param txHash - Transaction hash to confirm - * @returns ConfirmResult or null if not found - */ - async confirmTx(txHash: string): Promise { - if (!this.pendingManager) { - throw new Error('PendingStore not configured.'); - } - - const pending = await this.pendingManager.getByTxHash(txHash); - if (!pending || pending.status !== 'submitted') { - return null; - } - - // Finalize (delete pending record) - const finalized = await this.pendingManager.finalize(pending.id); - if (!finalized) { - return null; - } - - return { - conversationId: finalized.conversationId, - plaintext: finalized.plaintext, - messageId: finalized.id, - }; - } - - /** - * Handle transaction failure/revert. - * The ratchet slot is already burned (session was persisted in prepareMessage). - * This just cleans up the pending record. - * - * @param txHash - Transaction hash that failed - */ - async revertTx(txHash: string): Promise { - if (!this.pendingManager) { - throw new Error('PendingStore not configured.'); - } - - const pending = await this.pendingManager.getByTxHash(txHash); - if (pending) { - await this.pendingManager.delete(pending.id); - } - } - - /** - * Serialize session for storage (helper). - * Apps should use their own serialization if needed. - */ - private serializeSession(session: RatchetSession): any { - // Basic serialization - apps can override - return { - conversationId: session.conversationId, - topicEpoch: session.topicEpoch, - sendingMsgNumber: session.sendingMsgNumber, - receivingMsgNumber: session.receivingMsgNumber, - // ... other fields as hex strings - }; - } -} -``` - -### 2.4 Updated SDK Exports - -**Update `packages/sdk/src/client/index.ts`:** - -```typescript -export { VerbethClient } from './VerbethClient.js'; -export type { - SessionStore, - PreparedMessage, - DecryptedMessage, - PendingStore, - PendingMessage, - PendingStatus, - SendResult, - ConfirmResult, -} from './types.js'; -``` - ---- - -## App-Side Adapter Implementation - -these adapters could also be in the same file. - -### SessionStore Adapter - -**File: `apps/demo/src/adapters/SessionStoreAdapter.ts`** - -```typescript -import type { SessionStore } from '@verbeth/sdk'; -import { dbService } from '../services/DbService.js'; - -/** - * Adapter connecting VerbethClient SessionStore to app's DbService. - */ -export function createSessionStore(): SessionStore { - return { - async get(conversationId: string) { - return dbService.getRatchetSessionByConversation(conversationId); - }, - - async getByInboundTopic(topic: string) { - return dbService.getRatchetSessionByAnyInboundTopic(topic); - }, - - async save(session) { - await dbService.saveRatchetSession(session); - }, - }; -} -``` - -### PendingStore Adapter - -**File: `apps/demo/src/adapters/PendingStoreAdapter.ts`** - -```typescript -import type { PendingStore, PendingMessage, PendingStatus } from '@verbeth/sdk'; -import { dbService } from '../services/DbService.js'; - -/** - * Adapter connecting VerbethClient PendingStore to app's DbService. - */ -export function createPendingStore(): PendingStore { - return { - async save(pending: PendingMessage) { - await dbService.savePendingOutbound(pending); - }, - - async get(id: string) { - return dbService.getPendingOutbound(id); - }, - - async getByTxHash(txHash: string) { - return dbService.getPendingOutboundByTxHash(txHash); - }, - - async updateStatus(id: string, status: PendingStatus, txHash?: string) { - await dbService.updatePendingOutboundStatus(id, status, txHash); - }, - - async delete(id: string) { - await dbService.deletePendingOutbound(id); - }, - - async getByConversation(conversationId: string) { - return dbService.getPendingOutboundByConversation(conversationId); - }, - }; -} -``` - -### Updated App.tsx Initialization - -**In `apps/demo/src/App.tsx`:** - -```typescript -import { createSessionStore } from './adapters/SessionStoreAdapter.js'; -import { createPendingStore } from './adapters/PendingStoreAdapter.js'; - -// In the useEffect where VerbethClient is created: -useEffect(() => { - if (executor && identityKeyPair && identityProof && identitySigner && currentAddress) { - const client = new VerbethClient({ - userAddress: currentAddress, - identityKeyPair, - identityProof, - executor, - signer: identitySigner, - }); - - // Configure storage adapters - client.setSessionStore(createSessionStore()); - client.setPendingStore(createPendingStore()); - - setVerbethClient(client); - } -}, [executor, identityKeyPair, identityProof, identitySigner, address]); -``` - ---- - -## Simplified useMessageQueue (After Milestones 1 & 2) - -**File: `apps/demo/src/hooks/useMessageQueue.ts`** (refactored) - -```typescript -import { useCallback, useRef, useEffect } from "react"; -import { VerbethClient } from "@verbeth/sdk"; -import { Contact, Message, generateTempMessageId } from "../types.js"; - -interface UseMessageQueueProps { - verbethClient: VerbethClient | null; - addLog: (message: string) => void; - addMessage: (message: Message) => Promise; - updateMessageStatus: (id: string, status: Message["status"], error?: string) => Promise; - removeMessage: (id: string) => Promise; - updateContact: (contact: Contact) => Promise; -} - -export interface QueuedMessage { - id: string; - conversationId: string; - contact: Contact; - plaintext: string; - status: 'queued' | 'sending' | 'pending' | 'confirmed' | 'failed'; - error?: string; - txHash?: string; - createdAt: number; -} - -interface ConversationQueue { - messages: QueuedMessage[]; - isProcessing: boolean; -} - -export const useMessageQueue = ({ - verbethClient, - addLog, - addMessage, - updateMessageStatus, - removeMessage, - updateContact, -}: UseMessageQueueProps) => { - const queuesRef = useRef>(new Map()); - const failedMessagesRef = useRef>(new Map()); - const mountedRef = useRef(true); - - useEffect(() => { - mountedRef.current = true; - return () => { mountedRef.current = false; }; - }, []); - - const processQueue = useCallback(async (conversationId: string) => { - if (!verbethClient || !mountedRef.current) return; - - const queue = queuesRef.current.get(conversationId); - if (!queue || queue.isProcessing || queue.messages.length === 0) return; - - queue.isProcessing = true; - - while (queue.messages.length > 0 && mountedRef.current) { - const message = queue.messages[0]; - - if (message.status === 'confirmed' || message.status === 'pending') { - queue.messages.shift(); - continue; - } - - if (message.status === 'failed') { - queue.messages.shift(); - continue; - } - - try { - message.status = 'sending'; - - // ===================================================================== - // SDK handles everything: encryption, session persistence, pending tracking - // ===================================================================== - const result = await verbethClient.sendMessage( - conversationId, - message.plaintext - ); - - message.id = result.messageId; - message.txHash = result.txHash; - message.status = 'pending'; - - addLog(`๐Ÿ“ค Message sent: "${message.plaintext.slice(0, 30)}..." (tx: ${result.txHash.slice(0, 10)}..., n=${result.messageNumber})`); - - // Update contact with current topic - const updatedContact: Contact = { - ...message.contact, - lastMessage: message.plaintext, - lastTimestamp: Date.now(), - }; - await updateContact(updatedContact); - - queue.messages.shift(); - - } catch (error) { - const errorMessage = error instanceof Error ? error.message : 'Unknown error'; - - message.status = 'failed'; - message.error = errorMessage; - - await updateMessageStatus(message.id, 'failed', errorMessage); - addLog(`โœ— Failed to send: "${message.plaintext.slice(0, 20)}..." - ${errorMessage}`); - - failedMessagesRef.current.set(message.id, { ...message }); - queue.messages.shift(); - } - } - - queue.isProcessing = false; - }, [verbethClient, addLog, updateContact, updateMessageStatus]); - - const queueMessage = useCallback(async ( - contact: Contact, - messageText: string - ): Promise => { - if (!verbethClient || !contact.conversationId) { - addLog('โœ— Cannot queue message: missing client or conversation'); - return null; - } - - const messageId = generateTempMessageId(); - const conversationId = contact.conversationId; - - const queuedMessage: QueuedMessage = { - id: messageId, - conversationId, - contact, - plaintext: messageText, - status: 'queued', - createdAt: Date.now(), - }; - - let queue = queuesRef.current.get(conversationId); - if (!queue) { - queue = { messages: [], isProcessing: false }; - queuesRef.current.set(conversationId, queue); - } - queue.messages.push(queuedMessage); - - // Optimistic UI - const optimisticMessage: Message = { - id: messageId, - topic: contact.topicOutbound || '', - sender: verbethClient.userAddress, - recipient: contact.address, - ciphertext: '', - timestamp: Date.now(), - blockTimestamp: Date.now(), - blockNumber: 0, - direction: 'outgoing', - decrypted: messageText, - read: true, - nonce: 0, - dedupKey: `pending-${messageId}`, - type: 'text', - ownerAddress: verbethClient.userAddress, - status: 'pending', - }; - - await addMessage(optimisticMessage); - addLog(`๐Ÿ“ Message queued: "${messageText.slice(0, 30)}..."`); - - setTimeout(() => processQueue(conversationId), 0); - return messageId; - }, [verbethClient, addLog, addMessage, processQueue]); - - // ... retryMessage, cancelMessage, getQueueStatus remain largely the same ... - - return { - queueMessage, - retryMessage: useCallback(async (id: string) => { /* ... */ }, []), - cancelMessage: useCallback(async (id: string) => { /* ... */ }, []), - getQueueStatus: useCallback((convId: string) => { /* ... */ }, []), - invalidateSessionCache: useCallback((convId: string) => { - verbethClient?.invalidateSessionCache(convId); - }, [verbethClient]), - clearAllQueues: useCallback(() => { - queuesRef.current.clear(); - failedMessagesRef.current.clear(); - verbethClient?.clearSessionCache(); - }, [verbethClient]), - }; -}; -``` - ---- - -## Simplified EventProcessorService (After Milestone 1) - -**In `apps/demo/src/services/EventProcessorService.ts`:** - -The `processMessageEvent` function becomes simpler: - -```typescript -export async function processMessageEvent( - event: ProcessedEvent, - address: string, - emitterAddress: string | undefined, - verbethClient: VerbethClient, // Now we pass the client - onLog: (msg: string) => void -): Promise { - try { - const log = event.rawLog; - const abiCoder = new AbiCoder(); - const [ciphertextBytes, timestamp, topic, nonce] = abiCoder.decode( - ['bytes', 'uint256', 'bytes32', 'uint256'], - log.data - ); - - const sender = '0x' + log.topics[1].slice(-40); - const ciphertextRaw = hexToUint8Array(ciphertextBytes); - - const isOurMessage = - sender.toLowerCase() === address.toLowerCase() || - (emitterAddress && sender.toLowerCase() === emitterAddress.toLowerCase()); - - // ========================================================================= - // OUTGOING CONFIRMATION - Use SDK's confirmTx - // ========================================================================= - if (isOurMessage) { - const confirmed = await verbethClient.confirmTx(log.transactionHash); - if (confirmed) { - onLog(`โœ… Message confirmed: "${confirmed.plaintext.slice(0, 30)}..."`); - return { - messageUpdate: [confirmed.messageId, { status: 'confirmed' }], - }; - } - return null; - } - - // ========================================================================= - // INCOMING MESSAGE - Use SDK's decryptMessage - // ========================================================================= - - // Get contact for signing key - const contact = await dbService.getContactByTopic(topic, address); - if (!contact?.signingPubKey) { - onLog(`โ“ No contact found for topic ${topic.slice(0, 10)}...`); - return null; - } - - const decrypted = await verbethClient.decryptMessage( - topic, - ciphertextRaw, - contact.signingPubKey, - isOurMessage - ); - - if (!decrypted) { - onLog(`โœ— Failed to decrypt message from ${sender.slice(0, 8)}...`); - return null; - } - - const message: Message = { - id: generateMessageId(log.transactionHash, log), - topic, - sender: contact.address, - recipient: address, - ciphertext: hexlify(ciphertextRaw), - timestamp: Number(timestamp) * 1000, - blockTimestamp: Date.now(), - blockNumber: log.blockNumber, - direction: 'incoming', - decrypted: decrypted.plaintext, - read: false, - nonce: Number(nonce), - dedupKey: `msg-${log.transactionHash}-${log.logIndex}`, - type: 'text', - ownerAddress: address, - status: 'confirmed', - }; - - // Update contact topics if they changed - const updatedContact: Contact = { - ...contact, - topicInbound: decrypted.session.currentTopicInbound, - topicOutbound: decrypted.session.currentTopicOutbound, - lastMessage: decrypted.plaintext, - lastTimestamp: Date.now(), - }; - - await dbService.saveMessage(message); - await dbService.saveContact(updatedContact); - - onLog(`๐Ÿ“ฉ Message from ${contact.address.slice(0, 8)}...: "${decrypted.plaintext}"`); - - return { newMessage: message, contactUpdate: updatedContact }; - } catch (error) { - onLog(`โœ— Failed to process message: ${error}`); - return null; - } -} -``` - ---- - -## Migration Guide - -All changes are additive. Existing code continues to work. However, we must now prune old code no longer needed (like duplexTopics). - -### Recommended Migration Path - -1. **Add adapters** to your app (SessionStoreAdapter, PendingStoreAdapter) -2. **Configure VerbethClient** with `setSessionStore()` and `setPendingStore()` after creation -3. **Gradually replace** direct session/pending operations with SDK methods: - - Replace manual `ratchetEncrypt` + session save โ†’ `client.prepareMessage()` - - Replace pending record creation โ†’ already handled by `client.sendMessage()` - - Replace manual decryption flow โ†’ `client.decryptMessage()` - - Replace confirmation matching โ†’ `client.confirmTx()` - -4. **Remove** duplicated logic: - - Session cache in hooks (SDK manages internally) - - Topic promotion logic (SDK handles in `getByInboundTopic`) - - ---- - -## Milestone 3: Event Processor Helpers - -### Goal -Simplify event processing loops. - -```ts -interface ProcessedIncomingMessage { - conversationId: string; - plaintext: string; - sender: string; - topic: string; - isOwnMessage: boolean; -} -``` - -```ts -class VerbethClient { - async processMessageEvent(event: { - topic: string; - payload: Uint8Array; - txHash: string; - sender?: string; - }): Promise; - - async processMessageEvents(events: Array): Promise; -} -``` - ---- - -## App-Side Example - -```ts -const sessionStore: SessionStore = { - get: (id) => dbService.getRatchetSessionByConversation(id), - getByInboundTopic: (topic) => - dbService.getRatchetSessionByAnyInboundTopic(topic), - save: (session) => dbService.saveRatchetSession(session), -}; - -verbethClient.setSessionStore(sessionStore); -``` From 3de27547bf7bc223d88d18ae109b21210b8dc56d Mon Sep 17 00:00:00 2001 From: Marco Esposito Date: Sat, 24 Jan 2026 20:15:14 +0100 Subject: [PATCH 18/51] add verbeth client methods --- apps/demo/src/App.tsx | 21 +- apps/demo/src/hooks/useChatActions.ts | 14 +- apps/demo/src/hooks/useMessageListener.ts | 42 ++-- apps/demo/src/hooks/useMessageQueue.ts | 44 ++-- .../src/services/EventProcessorService.ts | 16 +- apps/demo/src/services/StorageAdapters.ts | 31 +-- packages/sdk/src/client/HsrTagIndex.ts | 199 ++++++++++++++++++ packages/sdk/src/client/VerbethClient.ts | 46 +++- .../sdk/src/client/VerbethClientBuilder.ts | 195 +++++++++++++++++ packages/sdk/src/client/index.ts | 27 ++- packages/sdk/src/client/types.ts | 59 ++++++ packages/sdk/src/index.ts | 26 ++- 12 files changed, 612 insertions(+), 108 deletions(-) create mode 100644 packages/sdk/src/client/HsrTagIndex.ts create mode 100644 packages/sdk/src/client/VerbethClientBuilder.ts diff --git a/apps/demo/src/App.tsx b/apps/demo/src/App.tsx index 27c1569..7637ec9 100644 --- a/apps/demo/src/App.tsx +++ b/apps/demo/src/App.tsx @@ -5,6 +5,7 @@ import { useAccount, useWalletClient } from 'wagmi'; import { useRpcClients } from './rpc.js'; import { VerbethClient, + createVerbethClient, } from '@verbeth/sdk'; import { useMessageListener } from './hooks/useMessageListener.js'; import { useMessageProcessor } from './hooks/useMessageProcessor.js'; @@ -24,7 +25,7 @@ import { useSessionSetup } from './hooks/useSessionSetup.js'; import { useInitIdentity } from './hooks/useInitIdentity.js'; import { usePendingSessionReset } from './hooks/usePendingSessionReset.js'; import { PinnedResetRequest } from './components/PinnedResetRequest.js'; -import { configureClientStorage } from './services/StorageAdapters.js'; +import { sessionStore, pendingStore } from './services/StorageAdapters.js'; export default function App() { const { ethers: readProvider, viem: viemClient } = useRpcClients(); @@ -126,22 +127,22 @@ export default function App() { }); // =========================================================================== - // UPDATED: Create and configure VerbethClient with storage adapters + // Create VerbethClient with storage adapters using factory function // =========================================================================== useEffect(() => { const currentAddress = address; if (executor && identityKeyPair && identityProof && identitySigner && currentAddress) { - const client = new VerbethClient({ - executor, + const client = createVerbethClient({ + address: currentAddress, + signer: identitySigner, identityKeyPair, identityProof, - signer: identitySigner, - address: currentAddress, + executor, + sessionStore, + pendingStore, }); - - configureClientStorage(client); - + setVerbethClient(client); addLog(`VerbethClient initialized for ${currentAddress.slice(0, 8)}...`); } else { @@ -166,7 +167,7 @@ export default function App() { address: address ?? undefined, emitterAddress: emitterAddress ?? undefined, identityKeyPair, - verbethClient, // NEW: Pass the configured client + verbethClient, onLog: addLog }); const { hasPendingReset, pendingHandshake: pendingResetHandshake, limboAfterTimestamp } = diff --git a/apps/demo/src/hooks/useChatActions.ts b/apps/demo/src/hooks/useChatActions.ts index 393ef3b..f73771a 100644 --- a/apps/demo/src/hooks/useChatActions.ts +++ b/apps/demo/src/hooks/useChatActions.ts @@ -13,7 +13,7 @@ * Uses VerbethClient for session creation. */ -import { useCallback } from "react"; +import { useCallback, useRef } from "react"; import { hexlify } from "ethers"; import type { VerbethClient } from "@verbeth/sdk"; import { dbService } from "../services/DbService.js"; @@ -69,6 +69,9 @@ export const useChatActions = ({ updateContact, }); + // Guard against duplicate acceptHandshake calls (e.g., rapid double-click) + const acceptingHandshakesRef = useRef>(new Set()); + // =========================================================================== // Handshake Operations // =========================================================================== @@ -163,7 +166,14 @@ export const useChatActions = ({ */ const acceptHandshake = useCallback( async (handshake: any, responseMessage: string) => { + // Prevent duplicate calls for same handshake + if (acceptingHandshakesRef.current.has(handshake.id)) { + return; + } + acceptingHandshakesRef.current.add(handshake.id); + if (!verbethClient) { + acceptingHandshakesRef.current.delete(handshake.id); addLog("โœ— Client not initialized"); return; } @@ -251,6 +261,8 @@ export const useChatActions = ({ addLog( `โœ— Failed to accept handshake: ${error instanceof Error ? error.message : "Unknown error"}` ); + } finally { + acceptingHandshakesRef.current.delete(handshake.id); } }, [ diff --git a/apps/demo/src/hooks/useMessageListener.ts b/apps/demo/src/hooks/useMessageListener.ts index ed8937a..0ae2e77 100644 --- a/apps/demo/src/hooks/useMessageListener.ts +++ b/apps/demo/src/hooks/useMessageListener.ts @@ -2,7 +2,7 @@ import { useState, useEffect, useRef, useCallback } from "react"; import { keccak256, toUtf8Bytes, getBytes } from "ethers"; -import { computeTagFromInitiator } from "@verbeth/sdk"; +import { HsrTagIndex, type PendingContactEntry } from "@verbeth/sdk"; import { dbService } from "../services/DbService.js"; import { LOGCHAIN_SINGLETON_ADDR, @@ -47,6 +47,7 @@ export const useMessageListener = ({ const processedLogs = useRef(new Set()); const scanChunks = useRef([]); + const hsrTagIndex = useRef(new HsrTagIndex()); const calculateRecipientHash = (recipientAddr: string) => { return keccak256(toUtf8Bytes(`contact:${recipientAddr.toLowerCase()}`)); @@ -188,37 +189,36 @@ export const useMessageListener = ({ }; /** - * Match HSR event to a pending contact using cryptographic tag verification. - * This works regardless of whether responder uses EOA or Safe. + * Match HSR event to a pending contact using HsrTagIndex for O(1) lookup. + * Uses cached tag computation for efficiency with many pending contacts. */ const matchHsrToContact = ( log: any, pendingContacts: Contact[] ): Contact | null => { - const inResponseTo = log.topics[1] as string; - + const inResponseTo = log.topics[1] as `0x${string}`; + // Extract responderEphemeralR (first bytes32 in log.data) - // ABI encoding: bytes32 is first 32 bytes = 64 hex chars + 0x prefix const responderEphemeralR = log.data.slice(0, 66); const R = getBytes(responderEphemeralR); - for (const contact of pendingContacts) { - if (!contact.handshakeEphemeralSecret) continue; + // Build index entries from pending contacts with ephemeral secrets + const indexEntries: PendingContactEntry[] = pendingContacts + .filter((c): c is Contact & { handshakeEphemeralSecret: string } => + !!c.handshakeEphemeralSecret + ) + .map(c => ({ + address: c.address, + handshakeEphemeralSecret: getBytes(c.handshakeEphemeralSecret), + })); - try { - const expectedTag = computeTagFromInitiator( - getBytes(contact.handshakeEphemeralSecret), - R - ); - if (expectedTag.toLowerCase() === inResponseTo.toLowerCase()) { - return contact; - } - } catch { - // Skip contacts where tag computation fails - } - } + hsrTagIndex.current.rebuild(indexEntries); + + // O(1) lookup after first computation for this R + const matchedAddress = hsrTagIndex.current.matchByTag(inResponseTo, R); + if (!matchedAddress) return null; - return null; + return pendingContacts.find(c => c.address === matchedAddress) || null; }; // scan specific block range - load contacts from db when needed diff --git a/apps/demo/src/hooks/useMessageQueue.ts b/apps/demo/src/hooks/useMessageQueue.ts index 40b9092..02099c2 100644 --- a/apps/demo/src/hooks/useMessageQueue.ts +++ b/apps/demo/src/hooks/useMessageQueue.ts @@ -2,12 +2,12 @@ /** * Message Queue Hook for Sequential Processing with Optimistic UI. - * + * * Uses VerbethClient's two-phase commit pattern: * 1. prepareMessage() - get ID and encrypted payload * 2. Submit tx manually * 3. confirmTx() on chain confirmation - * + * * The key insight: we use prepareMessage()'s ID for BOTH the optimistic * message AND the pending record, so confirmTx() can find the right message. */ @@ -51,9 +51,6 @@ interface UseMessageQueueProps { updateContact: (contact: Contact) => Promise; } -// ============================================================================= -// Hook Implementation -// ============================================================================= export const useMessageQueue = ({ verbethClient, @@ -101,9 +98,12 @@ export const useMessageQueue = ({ continue; } + // Track prepared ID for error handling (survives into catch block) + let preparedId: string | null = null; + try { queuedMsg.status = "sending"; - + // ===================================================================== // Step 1: Prepare message - this gives us the ID and encrypted payload // Session is committed immediately for forward secrecy @@ -113,12 +113,16 @@ export const useMessageQueue = ({ queuedMsg.plaintext ); + // Update queuedMsg.id IMMEDIATELY so catch block has correct ID + preparedId = prepared.id; + queuedMsg.id = prepared.id; + // ===================================================================== // Step 2: Create optimistic message with the SAME ID as prepared // This is the key fix - both share prepared.id // ===================================================================== const optimisticMessage: Message = { - id: prepared.id, // USE THE PREPARED ID! + id: prepared.id, topic: prepared.topic, sender: verbethClient.userAddress, recipient: queuedMsg.contact.address, @@ -170,8 +174,6 @@ export const useMessageQueue = ({ // ===================================================================== await dbService.updatePendingOutboundStatus(prepared.id, 'submitted', tx.hash); - // Update our tracking - queuedMsg.id = prepared.id; queuedMsg.txHash = tx.hash; queuedMsg.status = "pending"; @@ -192,24 +194,24 @@ export const useMessageQueue = ({ await updateContact(updatedContact); } - // Remove from queue (confirmation will be handled by event processor) queue.messages.shift(); } catch (error) { const errorMessage = error instanceof Error ? error.message : "Unknown error"; - - // Mark as failed queuedMsg.status = "failed"; queuedMsg.error = errorMessage; - // Note: Ratchet slot may already be burned (session was committed in prepareMessage) + // Use preparedId if message was already created in DB, otherwise use original queue id + const messageId = preparedId ?? queuedMsg.id; - await updateMessageStatus(queuedMsg.id, "failed", errorMessage); + // Note: Ratchet slot may already be burned (session was committed in prepareMessage) + await updateMessageStatus(messageId, "failed", errorMessage); addLog(`โœ— Failed to send: "${queuedMsg.plaintext.slice(0, 20)}..." - ${errorMessage}`); - // Store failed message for retry/cancel - failedMessagesRef.current.set(queuedMsg.id, { ...queuedMsg }); + // Store failed message for retry/cancel (use correct ID) + queuedMsg.id = messageId; + failedMessagesRef.current.set(messageId, { ...queuedMsg }); // Remove from active queue queue.messages.shift(); @@ -219,14 +221,9 @@ export const useMessageQueue = ({ queue.isProcessing = false; }, [verbethClient, addLog, addMessage, updateContact, updateMessageStatus]); - // =========================================================================== - // Public API - // =========================================================================== /** * Queue a message for sending. - * Note: The actual optimistic message is created in processQueue after prepareMessage - * so we can use the correct ID. */ const queueMessage = useCallback(async ( contact: Contact, @@ -264,7 +261,6 @@ export const useMessageQueue = ({ queuesRef.current.set(conversationId, queue); } - // Add to queue queue.messages.push(queuedMessage); addLog(`๐Ÿ“ Message queued: "${messageText.slice(0, 30)}..."`); @@ -275,9 +271,6 @@ export const useMessageQueue = ({ return tempId; }, [verbethClient, addLog, processQueue]); - /** - * Retry a failed message. - */ const retryMessage = useCallback(async (messageId: string): Promise => { const failedMessage = failedMessagesRef.current.get(messageId); @@ -328,7 +321,6 @@ export const useMessageQueue = ({ if (failedMessage) { failedMessagesRef.current.delete(messageId); - // Remove from DB and UI await removeMessage(messageId); addLog(`๐Ÿ—‘๏ธ Deleted message: "${failedMessage.plaintext.slice(0, 30)}..."`); diff --git a/apps/demo/src/services/EventProcessorService.ts b/apps/demo/src/services/EventProcessorService.ts index ff599c5..73b11fa 100644 --- a/apps/demo/src/services/EventProcessorService.ts +++ b/apps/demo/src/services/EventProcessorService.ts @@ -273,15 +273,17 @@ export async function processHandshakeResponseEvent( } // ========================================================================= - // Create session using VerbethClient (handles topic derivation and KEM internally) + // Create session using VerbethClient convenience method // ========================================================================= - const ratchetSession = verbethClient.createInitiatorSession({ + const ratchetSession = verbethClient.createInitiatorSessionFromHsr({ contactAddress: contact.address, - initiatorEphemeralSecret, - responderEphemeralPubKey: result.keys.ephemeralPubKey, - inResponseToTag: inResponseTo as `0x${string}`, - kemCiphertext: result.keys.kemCiphertext, - initiatorKemSecret, + myEphemeralSecret: initiatorEphemeralSecret, + myKemSecret: initiatorKemSecret, + hsrEvent: { + inResponseToTag: inResponseTo as `0x${string}`, + responderEphemeralPubKey: result.keys.ephemeralPubKey, + kemCiphertext: result.keys.kemCiphertext, + }, }); // Save session to DB (SDK will pick it up via SessionStore) diff --git a/apps/demo/src/services/StorageAdapters.ts b/apps/demo/src/services/StorageAdapters.ts index e4f6f5f..6a00482 100644 --- a/apps/demo/src/services/StorageAdapters.ts +++ b/apps/demo/src/services/StorageAdapters.ts @@ -143,33 +143,8 @@ class PendingStoreAdapter implements PendingStore { } // ============================================================================= -// Singleton Instances +// Singleton Instances (exported for createVerbethClient factory) // ============================================================================= -const sessionStoreInstance = new SessionStoreAdapter(); -const pendingStoreInstance = new PendingStoreAdapter(); - -// ============================================================================= -// Client Configuration Helper -// ============================================================================= - -/** - * Configure a VerbethClient with storage adapters. - * Uses the singleton dbService internally. - * - * @param client - VerbethClient instance to configure - * - * @example - * ```typescript - * const client = new VerbethClient(config); - * configureClientStorage(client); - * - * // Now client is ready to use sendMessage/decryptMessage - * ``` - */ -export function configureClientStorage( - client: { setSessionStore: (s: SessionStore) => void; setPendingStore: (p: PendingStore) => void } -): void { - client.setSessionStore(sessionStoreInstance); - client.setPendingStore(pendingStoreInstance); -} \ No newline at end of file +export const sessionStore = new SessionStoreAdapter(); +export const pendingStore = new PendingStoreAdapter(); \ No newline at end of file diff --git a/packages/sdk/src/client/HsrTagIndex.ts b/packages/sdk/src/client/HsrTagIndex.ts new file mode 100644 index 0000000..a25f18e --- /dev/null +++ b/packages/sdk/src/client/HsrTagIndex.ts @@ -0,0 +1,199 @@ +// packages/sdk/src/client/HsrTagIndex.ts + +/** + * Index for O(1) HSR (Handshake Response) matching. + * + * Caches computed tags for pending contacts to avoid O(n) loops + * when matching incoming handshake responses. + */ + +import { computeTagFromInitiator } from '../crypto.js'; + +/** + * Pending contact entry for HSR matching. + */ +export interface PendingContactEntry { + address: string; + handshakeEphemeralSecret: Uint8Array; +} + +/** + * Cache entry storing computed tags per R value. + */ +interface CacheEntry { + address: string; + secret: Uint8Array; + tagsByR: Map; +} + +/** + * Index for efficient HSR tag matching. + * + * When an HSR arrives, we need to find which pending contact it belongs to. + * This requires computing tag = computeTagFromInitiator(secret, R) for each + * pending contact until we find a match. + * + * This class caches the computed tags per (contact, R) pair, making + * subsequent lookups O(1) after the first computation. + * + * @example + * ```typescript + * const hsrIndex = new HsrTagIndex(); + * + * // When pending contacts change + * hsrIndex.rebuild(pendingContacts.map(c => ({ + * address: c.address, + * handshakeEphemeralSecret: c.handshakeEphemeralSecret + * }))); + * + * // Matching O(1) after first computation for each R + * const matchedAddress = hsrIndex.matchByTag(inResponseToTag, R); + * ``` + */ +export class HsrTagIndex { + private entries: Map = new Map(); + private tagToAddress: Map = new Map(); + + /** + * Rebuild the index with a new set of pending contacts. + * + * Preserves cached tag computations for contacts that remain. + * Clears entries for contacts no longer in the list. + * + * @param contacts - Current pending contacts + */ + rebuild(contacts: PendingContactEntry[]): void { + const newEntries = new Map(); + + for (const contact of contacts) { + const existing = this.entries.get(contact.address); + + if (existing && this.secretsEqual(existing.secret, contact.handshakeEphemeralSecret)) { + newEntries.set(contact.address, existing); + } else { + newEntries.set(contact.address, { + address: contact.address, + secret: contact.handshakeEphemeralSecret, + tagsByR: new Map(), + }); + } + } + + // Rebuild tagToAddress map + this.tagToAddress.clear(); + for (const [address, entry] of newEntries) { + for (const [, tag] of entry.tagsByR) { + this.tagToAddress.set(tag, address); + } + } + + this.entries = newEntries; + } + + /** + * Add a single pending contact without full rebuild. + * + * @param contact - Contact to add + */ + addContact(contact: PendingContactEntry): void { + const existing = this.entries.get(contact.address); + + if (!existing || !this.secretsEqual(existing.secret, contact.handshakeEphemeralSecret)) { + this.entries.set(contact.address, { + address: contact.address, + secret: contact.handshakeEphemeralSecret, + tagsByR: new Map(), + }); + } + } + + /** + * Remove a contact from the index. + * + * @param address - Address of contact to remove + */ + removeContact(address: string): void { + const entry = this.entries.get(address); + if (entry) { + // Remove all cached tags for this contact + for (const [, tag] of entry.tagsByR) { + this.tagToAddress.delete(tag); + } + this.entries.delete(address); + } + } + + + clear(): void { + this.entries.clear(); + this.tagToAddress.clear(); + } + + /** + * Match an HSR by its tag and responder ephemeral public key. + * + * First checks the global tag cache for O(1) lookup. + * If not found, computes tags for all pending contacts for this R + * and caches them. + * + * @param inResponseToTag - The tag from the HSR event + * @param R - Responder's ephemeral public key (from HSR event) + * @returns Address of matching contact, or null if no match + */ + matchByTag(inResponseToTag: `0x${string}`, R: Uint8Array): string | null { + // Fast path: check global tag cache + const cachedAddress = this.tagToAddress.get(inResponseToTag); + if (cachedAddress) { + return cachedAddress; + } + + // Slow path: compute tags for all contacts for this R + const rKey = this.bytesToHex(R); + + for (const [address, entry] of this.entries) { + // Check if we already computed for this R + let tag = entry.tagsByR.get(rKey); + + if (!tag) { + // Compute and cache + tag = computeTagFromInitiator(entry.secret, R); + entry.tagsByR.set(rKey, tag); + this.tagToAddress.set(tag, address); + } + + if (tag === inResponseToTag) { + return address; + } + } + + return null; + } + + /** + * Get the number of indexed contacts. + */ + get size(): number { + return this.entries.size; + } + + /** + * Check if a contact is in the index. + */ + hasContact(address: string): boolean { + return this.entries.has(address); + } + + private secretsEqual(a: Uint8Array, b: Uint8Array): boolean { + if (a.length !== b.length) return false; + for (let i = 0; i < a.length; i++) { + if (a[i] !== b[i]) return false; + } + return true; + } + + private bytesToHex(bytes: Uint8Array): string { + return Array.from(bytes) + .map(b => b.toString(16).padStart(2, '0')) + .join(''); + } +} diff --git a/packages/sdk/src/client/VerbethClient.ts b/packages/sdk/src/client/VerbethClient.ts index 7ac19d3..fd68cee 100644 --- a/packages/sdk/src/client/VerbethClient.ts +++ b/packages/sdk/src/client/VerbethClient.ts @@ -1,5 +1,4 @@ // packages/sdk/src/client/VerbethClient.ts -// CLEANED VERSION - duplexTopics removed, topics derived from ephemeral DH /** * High-level client for Verbeth E2EE messaging. @@ -47,6 +46,8 @@ import type { SendResult, ConfirmResult, SerializedSessionInfo, + VerbethClientCallbacks, + CreateInitiatorSessionFromHsrParams, } from './types.js'; export interface CreateInitiatorSessionParams { @@ -73,6 +74,7 @@ export class VerbethClient { private readonly identityProof: IdentityProof; private readonly signer: Signer; private readonly address: string; + private readonly callbacks?: VerbethClientCallbacks; // configured via setters private sessionManager?: SessionManager; @@ -84,6 +86,7 @@ export class VerbethClient { this.identityProof = config.identityProof; this.signer = config.signer; this.address = config.address; + this.callbacks = config.callbacks; } /** @@ -293,9 +296,23 @@ export class VerbethClient { }); } + /** + * Accepting a structured HSR event object instead of individual parameters scattered across variables. + */ + createInitiatorSessionFromHsr(params: CreateInitiatorSessionFromHsrParams): RatchetSession { + return this.createInitiatorSession({ + contactAddress: params.contactAddress, + initiatorEphemeralSecret: params.myEphemeralSecret, + responderEphemeralPubKey: params.hsrEvent.responderEphemeralPubKey, + inResponseToTag: params.hsrEvent.inResponseToTag, + kemCiphertext: params.hsrEvent.kemCiphertext, + initiatorKemSecret: params.myKemSecret, + }); + } + /** * Derive topics from DH shared secret. - * + * * @param mySecret - My ephemeral secret key * @param theirPublic - Their ephemeral public key * @param salt - Salt for topic derivation (typically the tag bytes) @@ -440,7 +457,6 @@ export class VerbethClient { return null; } - // verify signature before any ratchet operations const sigValid = verifyMessageSignature( parsed.signature, parsed.header, @@ -457,8 +473,32 @@ export class VerbethClient { return null; } + // Check for topic ratchet before saving + const topicRatcheted = decryptResult.session.topicEpoch > session.topicEpoch; + const previousTopicInbound = topicRatcheted ? session.currentTopicInbound : null; + await this.sessionManager.save(decryptResult.session); + // Invoke callbacks if configured + if (this.callbacks) { + if (topicRatcheted && this.callbacks.onTopicRatchet) { + this.callbacks.onTopicRatchet({ + conversationId: session.conversationId, + previousTopicInbound, + currentTopicInbound: decryptResult.session.currentTopicInbound, + topicEpoch: decryptResult.session.topicEpoch, + }); + } + + if (this.callbacks.onMessageDecrypted) { + this.callbacks.onMessageDecrypted({ + conversationId: session.conversationId, + topicMatch, + topicEpoch: decryptResult.session.topicEpoch, + }); + } + } + const plaintextStr = new TextDecoder().decode(decryptResult.plaintext); return { diff --git a/packages/sdk/src/client/VerbethClientBuilder.ts b/packages/sdk/src/client/VerbethClientBuilder.ts new file mode 100644 index 0000000..3d81572 --- /dev/null +++ b/packages/sdk/src/client/VerbethClientBuilder.ts @@ -0,0 +1,195 @@ +// packages/sdk/src/client/VerbethClientBuilder.ts + +/** + * Builder pattern and factory function for VerbethClient. + * + * Provides a fluent API for client setup, reducing boilerplate + * and making the initialization order explicit. + */ + +import type { Signer } from 'ethers'; +import type { IExecutor } from '../executor.js'; +import type { IdentityKeyPair, IdentityProof } from '../types.js'; +import type { SessionStore, PendingStore, VerbethClientCallbacks } from './types.js'; +import { VerbethClient } from './VerbethClient.js'; + +/** + * Options for createVerbethClient factory function. + */ +export interface CreateVerbethClientOptions { + address: string; + signer: Signer; + identityKeyPair: IdentityKeyPair; + identityProof: IdentityProof; + executor: IExecutor; + sessionStore?: SessionStore; + pendingStore?: PendingStore; + callbacks?: VerbethClientCallbacks; +} + +/** + * Factory function for one-liner client creation. + * + * @example + * ```typescript + * const client = createVerbethClient({ + * address, + * signer, + * identityKeyPair, + * identityProof, + * executor, + * sessionStore, + * pendingStore, + * }); + * ``` + */ +export function createVerbethClient(options: CreateVerbethClientOptions): VerbethClient { + const client = new VerbethClient({ + address: options.address, + signer: options.signer, + identityKeyPair: options.identityKeyPair, + identityProof: options.identityProof, + executor: options.executor, + callbacks: options.callbacks, + }); + + if (options.sessionStore) { + client.setSessionStore(options.sessionStore); + } + + if (options.pendingStore) { + client.setPendingStore(options.pendingStore); + } + + return client; +} + +/** + * Builder for fluent VerbethClient construction. + * + * @example + * ```typescript + * const client = new VerbethClientBuilder() + * .withAddress(address) + * .withSigner(signer) + * .withIdentity(keyPair, proof) + * .withExecutor(executor) + * .withStorage(sessionStore, pendingStore) + * .build(); + * ``` + */ +export class VerbethClientBuilder { + private address?: string; + private signer?: Signer; + private identityKeyPair?: IdentityKeyPair; + private identityProof?: IdentityProof; + private executor?: IExecutor; + private sessionStore?: SessionStore; + private pendingStore?: PendingStore; + private callbacks?: VerbethClientCallbacks; + + /** + * Set the user's blockchain address. + */ + withAddress(address: string): this { + this.address = address; + return this; + } + + /** + * Set the ethers Signer for transaction signing. + */ + withSigner(signer: Signer): this { + this.signer = signer; + return this; + } + + /** + * Set the identity keypair and proof. + */ + withIdentity(keyPair: IdentityKeyPair, proof: IdentityProof): this { + this.identityKeyPair = keyPair; + this.identityProof = proof; + return this; + } + + /** + * Set the contract executor. + */ + withExecutor(executor: IExecutor): this { + this.executor = executor; + return this; + } + + /** + * Set storage adapters for sessions and pending messages. + * Both are optional - only set what you need. + */ + withStorage(sessionStore?: SessionStore, pendingStore?: PendingStore): this { + if (sessionStore) { + this.sessionStore = sessionStore; + } + if (pendingStore) { + this.pendingStore = pendingStore; + } + return this; + } + + /** + * Set the session store adapter. + */ + withSessionStore(store: SessionStore): this { + this.sessionStore = store; + return this; + } + + /** + * Set the pending message store adapter. + */ + withPendingStore(store: PendingStore): this { + this.pendingStore = store; + return this; + } + + /** + * Set optional callbacks for events. + */ + withCallbacks(callbacks: VerbethClientCallbacks): this { + this.callbacks = callbacks; + return this; + } + + /** + * Build the VerbethClient instance. + * + * @throws Error if required fields are missing + */ + build(): VerbethClient { + if (!this.address) { + throw new Error('VerbethClientBuilder: address is required. Call withAddress().'); + } + if (!this.signer) { + throw new Error('VerbethClientBuilder: signer is required. Call withSigner().'); + } + if (!this.identityKeyPair) { + throw new Error('VerbethClientBuilder: identityKeyPair is required. Call withIdentity().'); + } + if (!this.identityProof) { + throw new Error('VerbethClientBuilder: identityProof is required. Call withIdentity().'); + } + if (!this.executor) { + throw new Error('VerbethClientBuilder: executor is required. Call withExecutor().'); + } + + return createVerbethClient({ + address: this.address, + signer: this.signer, + identityKeyPair: this.identityKeyPair, + identityProof: this.identityProof, + executor: this.executor, + sessionStore: this.sessionStore, + pendingStore: this.pendingStore, + callbacks: this.callbacks, + }); + } +} diff --git a/packages/sdk/src/client/index.ts b/packages/sdk/src/client/index.ts index 97c6fa2..b61feb9 100644 --- a/packages/sdk/src/client/index.ts +++ b/packages/sdk/src/client/index.ts @@ -3,25 +3,40 @@ export { VerbethClient } from './VerbethClient.js'; export { SessionManager } from './SessionManager.js'; export { PendingManager } from './PendingManager.js'; +export { VerbethClientBuilder, createVerbethClient } from './VerbethClientBuilder.js'; +export { HsrTagIndex } from './HsrTagIndex.js'; -export type { +export type { + CreateVerbethClientOptions, +} from './VerbethClientBuilder.js'; + +export type { + PendingContactEntry, +} from './HsrTagIndex.js'; + +export type { VerbethClientConfig, - + VerbethClientCallbacks, + TopicRatchetEvent, + MessageDecryptedEvent, + HandshakeResult, HandshakeResponseResult, - + SessionStore, PendingStore, - + PreparedMessage, DecryptedMessage, PendingMessage, PendingStatus, - + SendResult, ConfirmResult, - + SerializedSessionInfo, + HsrEventData, + CreateInitiatorSessionFromHsrParams, } from './types.js'; export type { diff --git a/packages/sdk/src/client/types.ts b/packages/sdk/src/client/types.ts index 316cf31..bca60b7 100644 --- a/packages/sdk/src/client/types.ts +++ b/packages/sdk/src/client/types.ts @@ -14,6 +14,45 @@ import type { RatchetSession } from '../ratchet/types.js'; import type nacl from 'tweetnacl'; import type { KemKeyPair } from '../send.js'; +/** + * Event emitted when topic ratcheting occurs. + */ +export interface TopicRatchetEvent { + conversationId: string; + previousTopicInbound: string | null; + currentTopicInbound: string; + topicEpoch: number; +} + +/** + * Event emitted after message decryption with topic match info. + */ +export interface MessageDecryptedEvent { + conversationId: string; + topicMatch: 'current' | 'next' | 'previous'; + topicEpoch: number; +} + +/** + * Optional callbacks for VerbethClient events. + * + * These callbacks allow apps to react to internal state changes + * without polling or manual session inspection. + */ +export interface VerbethClientCallbacks { + /** + * Called when a topic ratchet occurs (epoch advances). + * Useful for updating UI or triggering contact sync. + */ + onTopicRatchet?: (event: TopicRatchetEvent) => void; + + /** + * Called after successful message decryption. + * Provides topic match info for debugging/analytics. + */ + onMessageDecrypted?: (event: MessageDecryptedEvent) => void; +} + /** * Configuration for creating a VerbethClient instance. */ @@ -23,6 +62,7 @@ export interface VerbethClientConfig { identityProof: IdentityProof; signer: Signer; address: string; + callbacks?: VerbethClientCallbacks; } export interface HandshakeResult { @@ -146,4 +186,23 @@ export interface SerializedSessionInfo { receivingMsgNumber: number; currentTopicOutbound: string; currentTopicInbound: string; +} + +/** + * HSR event data for createInitiatorSessionFromHsr convenience method. + */ +export interface HsrEventData { + inResponseToTag: `0x${string}`; + responderEphemeralPubKey: Uint8Array; + kemCiphertext?: Uint8Array; +} + +/** + * Parameters for createInitiatorSessionFromHsr convenience method. + */ +export interface CreateInitiatorSessionFromHsrParams { + contactAddress: string; + myEphemeralSecret: Uint8Array; + myKemSecret?: Uint8Array; + hsrEvent: HsrEventData; } \ No newline at end of file diff --git a/packages/sdk/src/index.ts b/packages/sdk/src/index.ts index 96f3c71..d312772 100644 --- a/packages/sdk/src/index.ts +++ b/packages/sdk/src/index.ts @@ -48,25 +48,39 @@ export { getNextNonce } from './utils/nonce.js'; export { SafeSessionSigner } from "./utils/safeSessionSigner.js"; export type { SafeSessionSignerOptions } from "./utils/safeSessionSigner.js"; -export { VerbethClient, SessionManager, PendingManager } from './client/index.js'; +export { + VerbethClient, + SessionManager, + PendingManager, + VerbethClientBuilder, + createVerbethClient, + HsrTagIndex, +} from './client/index.js'; -export type { +export type { VerbethClientConfig, + VerbethClientCallbacks, + TopicRatchetEvent, + MessageDecryptedEvent, HandshakeResult, HandshakeResponseResult, - + SessionStore, PendingStore, - + PreparedMessage, DecryptedMessage, PendingMessage, PendingStatus, - + SendResult, ConfirmResult, - + SerializedSessionInfo, + HsrEventData, + CreateInitiatorSessionFromHsrParams, + CreateVerbethClientOptions, + PendingContactEntry, } from './client/index.js'; export * from './ratchet/index.js'; From 26d8209cf2d5736d913785b9d867fcc5e21c95e5 Mon Sep 17 00:00:00 2001 From: Marco Esposito Date: Sat, 24 Jan 2026 20:29:25 +0100 Subject: [PATCH 19/51] fix: use verbeth client methods --- apps/demo/src/hooks/useMessageProcessor.ts | 6 ++++++ apps/demo/src/services/EventProcessorService.ts | 16 ++++++---------- packages/sdk/src/client/index.ts | 2 -- packages/sdk/src/crypto.ts | 7 +++---- packages/sdk/src/index.ts | 3 --- packages/sdk/src/payload.ts | 11 ----------- packages/sdk/src/utils/nonce.ts | 7 ------- packages/sdk/test/crypto.test.ts | 9 ++++++++- packages/sdk/test/utils.test.ts | 12 ------------ packages/sdk/test/verify.test.ts | 9 ++++++++- 10 files changed, 31 insertions(+), 51 deletions(-) delete mode 100644 packages/sdk/src/utils/nonce.ts diff --git a/apps/demo/src/hooks/useMessageProcessor.ts b/apps/demo/src/hooks/useMessageProcessor.ts index 269c5c1..ce1d46b 100644 --- a/apps/demo/src/hooks/useMessageProcessor.ts +++ b/apps/demo/src/hooks/useMessageProcessor.ts @@ -95,11 +95,17 @@ export const useMessageProcessor = ({ // HANDSHAKE // ----------------------------------------------------------------- case "handshake": { + if (!verbethClient) { + onLog(`โŒ Cannot process handshake: VerbethClient not configured`); + break; + } + const result = await processHandshakeEvent( event, address, readProvider, identityContext, + verbethClient, onLog ); diff --git a/apps/demo/src/services/EventProcessorService.ts b/apps/demo/src/services/EventProcessorService.ts index 73b11fa..7006144 100644 --- a/apps/demo/src/services/EventProcessorService.ts +++ b/apps/demo/src/services/EventProcessorService.ts @@ -12,11 +12,6 @@ import { AbiCoder, getBytes } from "ethers"; import { type IdentityContext, type VerbethClient, - parseHandshakePayload, - parseBindingMessage, - verifyHandshakeIdentity, - decodeUnifiedPubKeys, - verifyAndExtractHandshakeResponseKeys, } from "@verbeth/sdk"; import { dbService } from "./DbService.js"; @@ -71,6 +66,7 @@ export async function processHandshakeEvent( address: string, readProvider: any, identityContext: IdentityContext, + verbethClient: VerbethClient, onLog: (msg: string) => void ): Promise { try { @@ -80,7 +76,7 @@ export async function processHandshakeEvent( const [identityPubKeyBytes, ephemeralPubKeyBytes, plaintextPayloadBytes] = decoded; const unifiedPubKeys = getBytes(identityPubKeyBytes); - const decodedKeys = decodeUnifiedPubKeys(unifiedPubKeys); + const decodedKeys = verbethClient.payload.decodeUnifiedPubKeys(unifiedPubKeys); if (!decodedKeys) { onLog("โœ— Failed to decode unified public keys"); @@ -105,7 +101,7 @@ export async function processHandshakeEvent( let hasValidIdentityProof = false; try { - handshakeContent = parseHandshakePayload(plaintextPayload); + handshakeContent = verbethClient.payload.parseHandshakePayload(plaintextPayload); hasValidIdentityProof = true; } catch (error) { handshakeContent = { @@ -126,7 +122,7 @@ export async function processHandshakeEvent( plaintextPayload: plaintextPayload, }; - isVerified = await verifyHandshakeIdentity( + isVerified = await verbethClient.verify.verifyHandshakeIdentity( handshakeEvent, readProvider, identityContext @@ -139,7 +135,7 @@ export async function processHandshakeEvent( let identityAddress = cleanSenderAddress; if (hasValidIdentityProof && handshakeContent.identityProof?.message) { try { - const parsed = parseBindingMessage(handshakeContent.identityProof.message); + const parsed = verbethClient.utils.parseBindingMessage(handshakeContent.identityProof.message); if (parsed.address) { identityAddress = parsed.address; } @@ -260,7 +256,7 @@ export async function processHandshakeResponseEvent( ? getBytes(contact.handshakeKemSecret) : undefined; - const result = await verifyAndExtractHandshakeResponseKeys( + const result = await verbethClient.verify.verifyAndExtractHandshakeResponseKeys( responseEvent, initiatorEphemeralSecret, readProvider, diff --git a/packages/sdk/src/client/index.ts b/packages/sdk/src/client/index.ts index b61feb9..c1bfa51 100644 --- a/packages/sdk/src/client/index.ts +++ b/packages/sdk/src/client/index.ts @@ -1,8 +1,6 @@ // packages/sdk/src/client/index.ts export { VerbethClient } from './VerbethClient.js'; -export { SessionManager } from './SessionManager.js'; -export { PendingManager } from './PendingManager.js'; export { VerbethClientBuilder, createVerbethClient } from './VerbethClientBuilder.js'; export { HsrTagIndex } from './HsrTagIndex.js'; diff --git a/packages/sdk/src/crypto.ts b/packages/sdk/src/crypto.ts index 49031b6..c13cb4c 100644 --- a/packages/sdk/src/crypto.ts +++ b/packages/sdk/src/crypto.ts @@ -19,12 +19,11 @@ import nacl from 'tweetnacl'; import { keccak256, toUtf8Bytes } from 'ethers'; import { sha256 } from '@noble/hashes/sha2'; import { hkdf } from '@noble/hashes/hkdf'; -import { - encodePayload, - decodePayload, +import { + encodePayload, + decodePayload, encodeStructuredContent, decodeStructuredContent, - MessagePayload, HandshakeResponseContent, extractKeysFromHandshakeResponse } from './payload.js'; diff --git a/packages/sdk/src/index.ts b/packages/sdk/src/index.ts index d312772..1999ee1 100644 --- a/packages/sdk/src/index.ts +++ b/packages/sdk/src/index.ts @@ -44,14 +44,11 @@ export { } from './executor.js'; -export { getNextNonce } from './utils/nonce.js'; export { SafeSessionSigner } from "./utils/safeSessionSigner.js"; export type { SafeSessionSignerOptions } from "./utils/safeSessionSigner.js"; export { VerbethClient, - SessionManager, - PendingManager, VerbethClientBuilder, createVerbethClient, HsrTagIndex, diff --git a/packages/sdk/src/payload.ts b/packages/sdk/src/payload.ts index cc4021f..fdadd15 100644 --- a/packages/sdk/src/payload.ts +++ b/packages/sdk/src/payload.ts @@ -13,17 +13,6 @@ export interface EncryptedPayload { sig?: string; // base64 of detached signature over (epk || n || ct) } -// Unified message payload -export interface MessagePayload { - content: string; - timestamp?: number; - messageType?: 'text' | 'file' | 'media'; - metadata?: Record; -} - -export interface HandshakeResponsePayload extends EncryptedPayload { -} - export interface HandshakeContent { plaintextPayload: string; identityProof: IdentityProof; diff --git a/packages/sdk/src/utils/nonce.ts b/packages/sdk/src/utils/nonce.ts deleted file mode 100644 index ea4cbd9..0000000 --- a/packages/sdk/src/utils/nonce.ts +++ /dev/null @@ -1,7 +0,0 @@ -const nonceRegistry: Record = {}; - -export function getNextNonce(sender: string, topic: string): bigint { - const key = `${sender}-${topic}`; - nonceRegistry[key] = (nonceRegistry[key] ?? 0n) + 1n; - return nonceRegistry[key]; -} diff --git a/packages/sdk/test/crypto.test.ts b/packages/sdk/test/crypto.test.ts index a463c14..4083f52 100644 --- a/packages/sdk/test/crypto.test.ts +++ b/packages/sdk/test/crypto.test.ts @@ -12,13 +12,20 @@ import { decodeHandshakePayload, encodeHandshakeResponseContent, decodeHandshakeResponseContent, - MessagePayload, HandshakeResponseContent, encodeUnifiedPubKeys, extractKeysFromHandshakePayload, extractKeysFromHandshakeResponse, parseHandshakeKeys, } from "../src/payload.js"; + +// Local type for test payloads +interface MessagePayload { + content: string; + timestamp?: number; + messageType?: 'text' | 'file' | 'media'; + metadata?: Record; +} import { IdentityProof } from "../src/types.js"; describe("Encryption/Decryption", () => { diff --git a/packages/sdk/test/utils.test.ts b/packages/sdk/test/utils.test.ts index 1625299..46e030f 100644 --- a/packages/sdk/test/utils.test.ts +++ b/packages/sdk/test/utils.test.ts @@ -2,7 +2,6 @@ import { describe, it, expect, vi } from "vitest"; import nacl from "tweetnacl"; import { JsonRpcProvider } from "ethers"; -import { getNextNonce } from "../src/utils/nonce.js"; import { convertPublicKeyToX25519 } from "../src/utils/x25519.js"; import { isSmartContract1271, parseBindingMessage } from "../src/utils.js"; import { ExecutorFactory } from "../src/index.js"; @@ -20,17 +19,6 @@ const fakeProvider = { }, } as unknown as JsonRpcProvider; - -describe("getNextNonce", () => { - it("increments per (sender, topic) and returns bigint", () => { - const n1 = getNextNonce("0xAlice", "topic"); - const n2 = getNextNonce("0xAlice", "topic"); - const nOther = getNextNonce("0xBob", "topic"); - expect(n2).toBe(n1 + 1n); - expect(nOther).toBe(1n); - }); -}); - describe("Utils Functions", () => { it("isSmartContract1271 returns true for contract bytecode", async () => { expect(await isSmartContract1271("0xCcโ€ฆCc", fakeProvider)).toBe(true); diff --git a/packages/sdk/test/verify.test.ts b/packages/sdk/test/verify.test.ts index a463c14..4083f52 100644 --- a/packages/sdk/test/verify.test.ts +++ b/packages/sdk/test/verify.test.ts @@ -12,13 +12,20 @@ import { decodeHandshakePayload, encodeHandshakeResponseContent, decodeHandshakeResponseContent, - MessagePayload, HandshakeResponseContent, encodeUnifiedPubKeys, extractKeysFromHandshakePayload, extractKeysFromHandshakeResponse, parseHandshakeKeys, } from "../src/payload.js"; + +// Local type for test payloads +interface MessagePayload { + content: string; + timestamp?: number; + messageType?: 'text' | 'file' | 'media'; + metadata?: Record; +} import { IdentityProof } from "../src/types.js"; describe("Encryption/Decryption", () => { From 7cd29e7d03845e75b9ff04fca11f144dae1700ef Mon Sep 17 00:00:00 2001 From: Marco Esposito Date: Sun, 25 Jan 2026 18:38:02 +0100 Subject: [PATCH 20/51] pq-secure topic unlinkability --- packages/sdk/src/client/VerbethClient.ts | 30 ++- packages/sdk/src/index.ts | 2 +- packages/sdk/src/ratchet/decrypt.ts | 16 +- packages/sdk/src/ratchet/index.ts | 2 +- packages/sdk/src/ratchet/kdf.ts | 25 +-- packages/sdk/src/ratchet/session.ts | 12 +- packages/sdk/test/ratchet.test.ts | 46 ++--- previous-plan.md | 232 +++++++++++++++++++++++ 8 files changed, 308 insertions(+), 57 deletions(-) create mode 100644 previous-plan.md diff --git a/packages/sdk/src/client/VerbethClient.ts b/packages/sdk/src/client/VerbethClient.ts index fd68cee..bace0d4 100644 --- a/packages/sdk/src/client/VerbethClient.ts +++ b/packages/sdk/src/client/VerbethClient.ts @@ -11,7 +11,9 @@ * - Transaction confirmation handling */ -import { hexlify, getBytes } from 'ethers'; +import { hexlify, getBytes, keccak256 } from 'ethers'; +import { hkdf } from '@noble/hashes/hkdf'; +import { sha256 } from '@noble/hashes/sha2'; import { initiateHandshake, respondToHandshake } from '../send.js'; import { kem } from '../pq/kem.js'; import type { IExecutor } from '../executor.js'; @@ -29,7 +31,7 @@ import { ratchetEncrypt } from '../ratchet/encrypt.js'; import { ratchetDecrypt } from '../ratchet/decrypt.js'; import { packageRatchetPayload, parseRatchetPayload, isRatchetPayload } from '../ratchet/codec.js'; import { verifyMessageSignature } from '../ratchet/auth.js'; -import { dh, deriveTopicFromDH } from '../ratchet/kdf.js'; +import { dh } from '../ratchet/kdf.js'; import { initSessionAsInitiator, initSessionAsResponder } from '../ratchet/session.js'; import type { RatchetSession } from '../ratchet/types.js'; @@ -311,7 +313,11 @@ export class VerbethClient { } /** - * Derive topics from DH shared secret. + * Derive epoch 0 topics from DH shared secret (handshake topics). + * + * NOTE: This uses the v2 scheme (DH + salt) for backward compatibility + * with epoch 0 topics. Post-handshake topics (epoch 1+) use the v3 scheme + * (DH + rootKey) via deriveTopic() for quantum-resistant unlinkability. * * @param mySecret - My ephemeral secret key * @param theirPublic - Their ephemeral public key @@ -326,19 +332,27 @@ export class VerbethClient { isInitiator: boolean ): { topicOutbound: `0x${string}`; topicInbound: `0x${string}` } { const ephemeralShared = dh(mySecret, theirPublic); - + + // Inline epoch 0 topic derivation (v2 scheme: DH + salt) + // This keeps epoch 0 topics compatible while epoch 1+ use PQ-secure derivation + const deriveEpoch0Topic = (direction: 'outbound' | 'inbound'): `0x${string}` => { + const info = `verbeth:topic-${direction}:v2`; + const okm = hkdf(sha256, ephemeralShared, salt, info, 32); + return keccak256(okm) as `0x${string}`; + }; + // Labels are from initiator's perspective // Initiator: outbound='outbound', inbound='inbound' // Responder: outbound='inbound', inbound='outbound' (swapped) if (isInitiator) { return { - topicOutbound: deriveTopicFromDH(ephemeralShared, 'outbound', salt), - topicInbound: deriveTopicFromDH(ephemeralShared, 'inbound', salt), + topicOutbound: deriveEpoch0Topic('outbound'), + topicInbound: deriveEpoch0Topic('inbound'), }; } else { return { - topicOutbound: deriveTopicFromDH(ephemeralShared, 'inbound', salt), - topicInbound: deriveTopicFromDH(ephemeralShared, 'outbound', salt), + topicOutbound: deriveEpoch0Topic('inbound'), + topicInbound: deriveEpoch0Topic('outbound'), }; } } diff --git a/packages/sdk/src/index.ts b/packages/sdk/src/index.ts index 1999ee1..ed3392b 100644 --- a/packages/sdk/src/index.ts +++ b/packages/sdk/src/index.ts @@ -81,6 +81,6 @@ export type { } from './client/index.js'; export * from './ratchet/index.js'; -export { dh, deriveTopicFromDH, hybridInitialSecret } from './ratchet/kdf.js'; +export { dh, deriveTopic, hybridInitialSecret } from './ratchet/kdf.js'; export { kem } from './pq/kem.js'; \ No newline at end of file diff --git a/packages/sdk/src/ratchet/decrypt.ts b/packages/sdk/src/ratchet/decrypt.ts index 8420b0b..7d10763 100644 --- a/packages/sdk/src/ratchet/decrypt.ts +++ b/packages/sdk/src/ratchet/decrypt.ts @@ -11,7 +11,7 @@ */ import nacl from 'tweetnacl'; -import { hexlify, getBytes } from 'ethers'; +import { hexlify } from 'ethers'; import { RatchetSession, MessageHeader, @@ -21,7 +21,7 @@ import { MAX_STORED_SKIPPED_KEYS, TOPIC_TRANSITION_WINDOW_MS, } from './types.js'; -import { kdfRootKey, kdfChainKey, dh, generateDHKeyPair, deriveTopicFromDH } from './kdf.js'; +import { kdfRootKey, kdfChainKey, dh, generateDHKeyPair, deriveTopic } from './kdf.js'; /** * Decrypt a message using the ratchet. @@ -135,15 +135,15 @@ function dhRatchetStep(session: RatchetSession, theirNewDHPub: Uint8Array): Ratc const dhSend = dh(newDHKeyPair.secretKey, theirNewDHPub); const { rootKey: rootKey2, chainKey: sendingChainKey } = kdfRootKey(rootKey1, dhSend); - const saltBytes = getBytes(session.conversationId); - // Current topics (post ratchet) - swapped since we're the receiver - const newTopicOut = deriveTopicFromDH(dhReceive, 'inbound', saltBytes); - const newTopicIn = deriveTopicFromDH(dhReceive, 'outbound', saltBytes); + // Use rootKey1 (derived from dhReceive) for PQ-secure topic derivation + const newTopicOut = deriveTopic(rootKey1, dhReceive, 'inbound'); + const newTopicIn = deriveTopic(rootKey1, dhReceive, 'outbound'); // Next topics (for our next DH pubkey) - normal labels because we will be the sender - const nextTopicOut = deriveTopicFromDH(dhSend, 'outbound', saltBytes); - const nextTopicIn = deriveTopicFromDH(dhSend, 'inbound', saltBytes); + // Use rootKey2 (derived from dhSend) for PQ-secure topic derivation + const nextTopicOut = deriveTopic(rootKey2, dhSend, 'outbound'); + const nextTopicIn = deriveTopic(rootKey2, dhSend, 'inbound'); return { ...session, diff --git a/packages/sdk/src/ratchet/index.ts b/packages/sdk/src/ratchet/index.ts index 9be2629..ecfa701 100644 --- a/packages/sdk/src/ratchet/index.ts +++ b/packages/sdk/src/ratchet/index.ts @@ -25,7 +25,7 @@ export { kdfChainKey, dh, generateDHKeyPair, - deriveTopicFromDH, + deriveTopic, hybridInitialSecret, } from './kdf.js'; diff --git a/packages/sdk/src/ratchet/kdf.ts b/packages/sdk/src/ratchet/kdf.ts index 9d99c22..9c207f9 100644 --- a/packages/sdk/src/ratchet/kdf.ts +++ b/packages/sdk/src/ratchet/kdf.ts @@ -76,21 +76,24 @@ export function generateDHKeyPair(): { secretKey: Uint8Array; publicKey: Uint8Ar } /** - * Derive topic from DH shared secret. - * Called after each DH ratchet step to rotate topics. - * - * @param dhSharedSecret - DH output from ratchet step (32 bytes) + * Derive topic from DH output using rootKey as PQ-secure salt. + * + * The rootKey (PQ-secure from hybrid handshake) acts as HKDF salt, + * providing quantum-resistant topic unlinkability even if dhOutput + * is later computed by a quantum adversary. + * + * @param rootKey - Current root key (32 bytes, PQ-secure) + * @param dhOutput - DH shared secret from ratchet step (32 bytes) * @param direction - 'outbound' or 'inbound' for topic direction - * @param salt - Conversation ID bytes for domain separation * @returns bytes32 topic as hex string */ -export function deriveTopicFromDH( - dhSharedSecret: Uint8Array, - direction: 'outbound' | 'inbound', - salt: Uint8Array +export function deriveTopic( + rootKey: Uint8Array, + dhOutput: Uint8Array, + direction: 'outbound' | 'inbound' ): `0x${string}` { - const info = `verbeth:topic-${direction}:v2`; - const okm = hkdf(sha256, dhSharedSecret, salt, info, 32); + const info = `verbeth:topic-${direction}:v3`; + const okm = hkdf(sha256, dhOutput, rootKey, info, 32); return keccak256(okm) as `0x${string}`; } diff --git a/packages/sdk/src/ratchet/session.ts b/packages/sdk/src/ratchet/session.ts index 669efb6..3917804 100644 --- a/packages/sdk/src/ratchet/session.ts +++ b/packages/sdk/src/ratchet/session.ts @@ -9,13 +9,13 @@ * Initial shared secret is derived from ephemeral-to-ephemeral DH only. */ -import { keccak256, toUtf8Bytes, getBytes } from 'ethers'; +import { keccak256, toUtf8Bytes } from 'ethers'; import { RatchetSession, InitResponderParams, InitInitiatorParams, } from './types.js'; -import { kdfRootKey, dh, generateDHKeyPair, deriveTopicFromDH, hybridInitialSecret } from './kdf.js'; +import { kdfRootKey, dh, generateDHKeyPair, deriveTopic, hybridInitialSecret } from './kdf.js'; /** * Compute deterministic conversation ID from topics. @@ -156,11 +156,11 @@ export function initSessionAsInitiator(params: InitInitiatorParams): RatchetSess ); const conversationId = computeConversationId(topicOutbound, topicInbound); - const saltBytes = getBytes(conversationId); - + // Pre-compute epoch 1 topics (for when our first message is sent) - const epoch1TopicOut = deriveTopicFromDH(dhSend, 'outbound', saltBytes); - const epoch1TopicIn = deriveTopicFromDH(dhSend, 'inbound', saltBytes); + // Use finalRootKey as PQ-secure salt for quantum-resistant topic unlinkability + const epoch1TopicOut = deriveTopic(finalRootKey, dhSend, 'outbound'); + const epoch1TopicIn = deriveTopic(finalRootKey, dhSend, 'inbound'); const now = Date.now(); diff --git a/packages/sdk/test/ratchet.test.ts b/packages/sdk/test/ratchet.test.ts index 082a041..3b15037 100644 --- a/packages/sdk/test/ratchet.test.ts +++ b/packages/sdk/test/ratchet.test.ts @@ -4,7 +4,7 @@ import { describe, it, expect, beforeEach } from 'vitest'; import nacl from 'tweetnacl'; import { - deriveTopicFromDH, + deriveTopic, initSessionAsResponder, initSessionAsInitiator, ratchetEncrypt, @@ -14,48 +14,50 @@ import { type RatchetSession, } from '../src/ratchet/index.js'; -describe('deriveTopicFromDH', () => { - it('derives deterministic topic from DH output', () => { +describe('deriveTopic (PQ-secure)', () => { + it('derives deterministic topic from rootKey + dhOutput', () => { + const rootKey = nacl.randomBytes(32); const dhOutput = nacl.randomBytes(32); - const salt = nacl.randomBytes(32); - const topic1 = deriveTopicFromDH(dhOutput, 'outbound', salt); - const topic2 = deriveTopicFromDH(dhOutput, 'outbound', salt); + const topic1 = deriveTopic(rootKey, dhOutput, 'outbound'); + const topic2 = deriveTopic(rootKey, dhOutput, 'outbound'); expect(topic1).toBe(topic2); expect(topic1).toMatch(/^0x[a-f0-9]{64}$/); }); - it('derives different topics for outbound vs inbound', () => { - const dhOutput = nacl.randomBytes(32); - const salt = nacl.randomBytes(32); + it('derives different topics for different rootKeys (PQ-unlinkability)', () => { + const rootKey1 = nacl.randomBytes(32); + const rootKey2 = nacl.randomBytes(32); + const dhOutput = nacl.randomBytes(32); // SAME dhOutput - const topicOut = deriveTopicFromDH(dhOutput, 'outbound', salt); - const topicIn = deriveTopicFromDH(dhOutput, 'inbound', salt); + const topic1 = deriveTopic(rootKey1, dhOutput, 'outbound'); + const topic2 = deriveTopic(rootKey2, dhOutput, 'outbound'); - expect(topicOut).not.toBe(topicIn); + // Key property: quantum adversary who knows dhOutput + // but not rootKey cannot derive the topic + expect(topic1).not.toBe(topic2); }); - it('derives different topics for different DH outputs', () => { + it('derives different topics for different dhOutputs', () => { + const rootKey = nacl.randomBytes(32); const dhOutput1 = nacl.randomBytes(32); const dhOutput2 = nacl.randomBytes(32); - const salt = nacl.randomBytes(32); - const topic1 = deriveTopicFromDH(dhOutput1, 'outbound', salt); - const topic2 = deriveTopicFromDH(dhOutput2, 'outbound', salt); + const topic1 = deriveTopic(rootKey, dhOutput1, 'outbound'); + const topic2 = deriveTopic(rootKey, dhOutput2, 'outbound'); expect(topic1).not.toBe(topic2); }); - it('derives different topics for different salts', () => { + it('derives different topics for outbound vs inbound', () => { + const rootKey = nacl.randomBytes(32); const dhOutput = nacl.randomBytes(32); - const salt1 = nacl.randomBytes(32); - const salt2 = nacl.randomBytes(32); - const topic1 = deriveTopicFromDH(dhOutput, 'outbound', salt1); - const topic2 = deriveTopicFromDH(dhOutput, 'outbound', salt2); + const topicOut = deriveTopic(rootKey, dhOutput, 'outbound'); + const topicIn = deriveTopic(rootKey, dhOutput, 'inbound'); - expect(topic1).not.toBe(topic2); + expect(topicOut).not.toBe(topicIn); }); }); diff --git a/previous-plan.md b/previous-plan.md new file mode 100644 index 0000000..8f17a19 --- /dev/null +++ b/previous-plan.md @@ -0,0 +1,232 @@ +# Plan: Quantum-Resistant Topic Unlinkability + +## Obiettivo +Derivare i topic da `rootKey` (PQ-secure) invece che solo da `dhOutput` (classico X25519), ottenendo **quantum-resistant topic unlinkability** senza il costo di un PQ-ratchet completo. + +## Analisi del Problema + +**Stato attuale** (`kdf.ts:87-94`): +```typescript +export function deriveTopicFromDH( + dhSharedSecret: Uint8Array, + direction: 'outbound' | 'inbound', + salt: Uint8Array // conversationId +): `0x${string}` { + const okm = hkdf(sha256, dhSharedSecret, salt, info, 32); + return keccak256(okm); +} +``` + +**Problema**: IKM = `dhSharedSecret` (X25519 solo). Un avversario quantum passivo puรฒ: +1. Calcolare tutti i `dhSecret` futuri con Shor +2. Derivare tutti i topic e linkare i messaggi alla sessione originale + +**Soluzione**: Usare `rootKey` (PQ-secure dall'handshake ibrido) come **salt** in HKDF: +```typescript +// Proposta +const okm = hkdf(sha256, dhOutput, rootKey, info, 32); +// ^IKM ^salt (PQ-secure) +``` + +Questo sfrutta la proprietร  di HKDF: anche conoscendo l'IKM, senza il salt l'output รจ indistinguibile da random. + +## Proprietร  di Sicurezza Preservate + +| Proprietร  | Prima | Dopo | Note | +|-----------|-------|------|------| +| **Bilateral Forward Secrecy** | โœ“ | โœ“ | DH ratchet continua a funzionare | +| **Post-Compromise Security (classical)** | โœ“ | โœ“ | Fresh DH โ†’ fresh chainKey | +| **PCS (quantum active)** | โœ— | โœ— | Richiede PQ-ratchet completo | +| **Topic-HS Unlinkability (classical)** | โœ“ | โœ“ | Invariato | +| **Topic-HS Unlinkability (quantum passive)** | โœ— | **โœ“** | **Nuovo** | +| **HNDL Resistance** | โœ“ | โœ“ | rootKey giร  PQ-secure | + +## Refactor + +### 1. Modificare `deriveTopicFromDH` โ†’ `deriveTopic` + +**File**: `packages/sdk/src/ratchet/kdf.ts` + +```typescript +/** + * Derive topic from DH output using rootKey as PQ-secure salt. + * + * The rootKey (PQ-secure from hybrid handshake) acts as HKDF salt, + * providing quantum-resistant topic unlinkability even if dhOutput + * is later computed by a quantum adversary. + */ +export function deriveTopic( + rootKey: Uint8Array, + dhOutput: Uint8Array, + direction: 'outbound' | 'inbound' +): `0x${string}` { + const info = `verbeth:topic-${direction}:v3`; + const okm = hkdf(sha256, dhOutput, rootKey, info, 32); + return keccak256(okm) as `0x${string}`; +} + +// REMOVE deriveTopicFromDH entirely (no migration needed) +``` + +**Note**: +- Rimosso `salt` (conversationId) - non necessario, rootKey fornisce domain separation +- `info` bumped a `:v3` per chiarezza +- rootKey come salt รจ crittograficamente corretto per HKDF +- **Nessuna deprecation**: rimuovere direttamente `deriveTopicFromDH` + +### 2. Aggiornare `initSessionAsInitiator` + +**File**: `packages/sdk/src/ratchet/session.ts` (linee 161-163) + +```typescript +// Prima: +const epoch1TopicOut = deriveTopicFromDH(dhSend, 'outbound', saltBytes); +const epoch1TopicIn = deriveTopicFromDH(dhSend, 'inbound', saltBytes); + +// Dopo: +const epoch1TopicOut = deriveTopic(finalRootKey, dhSend, 'outbound'); +const epoch1TopicIn = deriveTopic(finalRootKey, dhSend, 'inbound'); +``` + +`finalRootKey` รจ giร  disponibile nello scope (linea 153). + +### 3. Aggiornare `dhRatchetStep` + +**File**: `packages/sdk/src/ratchet/decrypt.ts` (linee 141-146) + +```typescript +// Prima: +const newTopicOut = deriveTopicFromDH(dhReceive, 'inbound', saltBytes); +const newTopicIn = deriveTopicFromDH(dhReceive, 'outbound', saltBytes); +const nextTopicOut = deriveTopicFromDH(dhSend, 'outbound', saltBytes); +const nextTopicIn = deriveTopicFromDH(dhSend, 'inbound', saltBytes); + +// Dopo: +const newTopicOut = deriveTopic(rootKey1, dhReceive, 'inbound'); +const newTopicIn = deriveTopic(rootKey1, dhReceive, 'outbound'); +const nextTopicOut = deriveTopic(rootKey2, dhSend, 'outbound'); +const nextTopicIn = deriveTopic(rootKey2, dhSend, 'inbound'); +``` + +`rootKey1` e `rootKey2` sono giร  derivati alle linee 126 e 136. + +### 4. (Opzionale) Topic iniziali handshake + +I topic dell'epoch 0 (handshake) sono derivati in `crypto.ts` durante l'handshake stesso. Questi usano ancora il DH dell'handshake ma con l'initial rootKey come salt. + +**File**: `packages/sdk/src/crypto.ts` (se applicabile) + +Se i topic handshake sono derivati con una funzione separata, aggiornare per usare il rootKey iniziale. + +## File da Modificare + +| File | Modifica | +|------|----------| +| `packages/sdk/src/ratchet/kdf.ts` | Nuova `deriveTopic()`, deprecare `deriveTopicFromDH` | +| `packages/sdk/src/ratchet/session.ts` | Aggiornare chiamate in `initSessionAsInitiator` | +| `packages/sdk/src/ratchet/decrypt.ts` | Aggiornare chiamate in `dhRatchetStep` | +| `packages/sdk/src/ratchet/index.ts` | Export nuova funzione | + +## Epoch 0 (Handshake Topics) - Considerazioni Speciali + +I topic dell'epoch 0 sono derivati in `VerbethClient.deriveTopicsFromDH()` **prima** che la sessione sia creata, quindi prima che il rootKey sia disponibile. + +**Strategia**: Lasciare i topic epoch 0 con il vecchio schema (DH-only con conversationSalt). + +**Razionale**: +1. L'handshake DH รจ giร  protetto dall'hybrid KEM โ†’ rootKey รจ PQ-secure +2. Dopo il primo DH ratchet (epoch 1+), i topic diventano PQ-unlinkable +3. Il "leak" รจ minimo: un avversario quantum puรฒ linkare l'epoch 0 all'handshake, ma non puรฒ: + - Decifrare i messaggi (rootKey PQ-secure) + - Linkare i topic epoch 1+ (derivati con rootKey come salt) +4. Propagare rootKey a VerbethClient richiederebbe refactor invasivo + +**Alternativa (futura)**: Derivare topic epoch 0 da una forma intermedia del rootKey. Richiede refactor piรน profondo di `initSession*` e `deriveTopicsFromDH`. + +## Non Modificare + +- `VerbethClient.deriveTopicsFromDH()`: topic epoch 0 restano con vecchio schema +- `initSessionAsResponder`: non pre-computa next topics (Alice lo fa al primo ratchet) +- Handshake payload/protocol: nessun cambiamento wire format +- Storage format: i topic sono giร  stringhe, nessun cambiamento schema + +## Backward Compatibility + +**Non necessaria**: Verbeth non รจ ancora in produzione. + +- Rimuovere `deriveTopicFromDH` direttamente +- Nessun migration path +- Aggiornare tutti i call site in un colpo solo + +## Test da Aggiornare + +**File**: `packages/sdk/test/ratchet.test.ts` + +### Nuovi test per `deriveTopic` + +```typescript +describe('deriveTopic (PQ-secure)', () => { + it('derives deterministic topic from rootKey + dhOutput', () => { + const rootKey = nacl.randomBytes(32); + const dhOutput = nacl.randomBytes(32); + + const topic1 = deriveTopic(rootKey, dhOutput, 'outbound'); + const topic2 = deriveTopic(rootKey, dhOutput, 'outbound'); + + expect(topic1).toBe(topic2); + }); + + it('derives different topics for different rootKeys (PQ-unlinkability)', () => { + const rootKey1 = nacl.randomBytes(32); + const rootKey2 = nacl.randomBytes(32); + const dhOutput = nacl.randomBytes(32); // STESSO dhOutput + + const topic1 = deriveTopic(rootKey1, dhOutput, 'outbound'); + const topic2 = deriveTopic(rootKey2, dhOutput, 'outbound'); + + // Proprietร  chiave: quantum adversary che conosce dhOutput + // ma non rootKey non puรฒ derivare il topic + expect(topic1).not.toBe(topic2); + }); + + it('derives different topics for different dhOutputs', () => { + const rootKey = nacl.randomBytes(32); + const dhOutput1 = nacl.randomBytes(32); + const dhOutput2 = nacl.randomBytes(32); + + const topic1 = deriveTopic(rootKey, dhOutput1, 'outbound'); + const topic2 = deriveTopic(rootKey, dhOutput2, 'outbound'); + + expect(topic1).not.toBe(topic2); + }); + + it('derives different topics for outbound vs inbound', () => { + const rootKey = nacl.randomBytes(32); + const dhOutput = nacl.randomBytes(32); + + const topicOut = deriveTopic(rootKey, dhOutput, 'outbound'); + const topicIn = deriveTopic(rootKey, dhOutput, 'inbound'); + + expect(topicOut).not.toBe(topicIn); + }); +}); +``` + +### Test da rimuovere + +- `describe('deriveTopicFromDH', ...)` - sostituito dai nuovi test `deriveTopic` + +### Test integrazione esistenti + +I test `DH ratchet step - topic rotation` e `topic continuity` restano validi - verificano solo che i topic ruotino correttamente, non come sono derivati. + +## Verifica End-to-End + +1. **Unit test**: `npm test` nella SDK +2. **Integration test**: + - Creare sessione con hybrid handshake + - Inviare messaggi, verificare topic rotation + - Controllare che `session.rootKey` sia usato nella derivazione +3. **Security test manuale**: + - Log `deriveTopic` inputs/outputs + - Verificare che stesso dhOutput + rootKey diversi โ†’ topic diversi From 35d7e37f51c15c0a134dd3e6bfa7bfd74927b87e Mon Sep 17 00:00:00 2001 From: Marco Esposito Date: Sun, 25 Jan 2026 21:03:35 +0100 Subject: [PATCH 21/51] refactor for hs to hsr quantum unlinkability --- apps/demo/src/hooks/useChatActions.ts | 1 - apps/demo/src/hooks/useMessageListener.ts | 33 +- .../src/services/EventProcessorService.ts | 6 + packages/sdk/src/client/HsrTagIndex.ts | 83 ++-- packages/sdk/src/client/VerbethClient.ts | 52 ++- packages/sdk/src/crypto.ts | 27 ++ packages/sdk/src/send.ts | 29 +- packages/sdk/src/verify.ts | 34 +- packages/sdk/test/crypto.test.ts | 69 ++++ packages/sdk/test/executor.test.ts | 17 +- packages/sdk/test/ratchet.test.ts | 1 - plan-pq-metadata-v2.md | 366 ++++++++++++++++++ previous-plan.md | 232 ----------- 13 files changed, 598 insertions(+), 352 deletions(-) create mode 100644 plan-pq-metadata-v2.md delete mode 100644 previous-plan.md diff --git a/apps/demo/src/hooks/useChatActions.ts b/apps/demo/src/hooks/useChatActions.ts index f73771a..b7a7c34 100644 --- a/apps/demo/src/hooks/useChatActions.ts +++ b/apps/demo/src/hooks/useChatActions.ts @@ -189,7 +189,6 @@ export const useChatActions = ({ kemSharedSecret, } = await verbethClient.acceptHandshake( ephemeralKey, - handshake.identityPubKey, responseMessage ); diff --git a/apps/demo/src/hooks/useMessageListener.ts b/apps/demo/src/hooks/useMessageListener.ts index 0ae2e77..38a20a3 100644 --- a/apps/demo/src/hooks/useMessageListener.ts +++ b/apps/demo/src/hooks/useMessageListener.ts @@ -1,7 +1,7 @@ // apps/demo/src/hooks/useMessageListener.ts import { useState, useEffect, useRef, useCallback } from "react"; -import { keccak256, toUtf8Bytes, getBytes } from "ethers"; +import { keccak256, toUtf8Bytes, getBytes, AbiCoder } from "ethers"; import { HsrTagIndex, type PendingContactEntry } from "@verbeth/sdk"; import { dbService } from "../services/DbService.js"; import { @@ -198,26 +198,37 @@ export const useMessageListener = ({ ): Contact | null => { const inResponseTo = log.topics[1] as `0x${string}`; - // Extract responderEphemeralR (first bytes32 in log.data) - const responderEphemeralR = log.data.slice(0, 66); - const R = getBytes(responderEphemeralR); + // Extract R and encrypted payload using AbiCoder + const abiCoder = new AbiCoder(); + const [responderEphemeralRBytes, ciphertextBytes] = abiCoder.decode( + ["bytes32", "bytes"], + log.data + ); + const R = getBytes(responderEphemeralRBytes); + const encryptedPayload = new TextDecoder().decode(getBytes(ciphertextBytes)); - // Build index entries from pending contacts with ephemeral secrets + // Build index entries with kemSecretKey const indexEntries: PendingContactEntry[] = pendingContacts - .filter((c): c is Contact & { handshakeEphemeralSecret: string } => - !!c.handshakeEphemeralSecret - ) + .filter((c): c is Contact & { + handshakeEphemeralSecret: string; + handshakeKemSecret: string; + } => !!c.handshakeEphemeralSecret && !!c.handshakeKemSecret) .map(c => ({ address: c.address, handshakeEphemeralSecret: getBytes(c.handshakeEphemeralSecret), + kemSecretKey: getBytes(c.handshakeKemSecret), })); hsrTagIndex.current.rebuild(indexEntries); - // O(1) lookup after first computation for this R - const matchedAddress = hsrTagIndex.current.matchByTag(inResponseTo, R); - if (!matchedAddress) return null; + // matchByTag now does decrypt+match internally + const matchedAddress = hsrTagIndex.current.matchByTag( + inResponseTo, + R, + encryptedPayload + ); + if (!matchedAddress) return null; return pendingContacts.find(c => c.address === matchedAddress) || null; }; diff --git a/apps/demo/src/services/EventProcessorService.ts b/apps/demo/src/services/EventProcessorService.ts index 7006144..a9c7c65 100644 --- a/apps/demo/src/services/EventProcessorService.ts +++ b/apps/demo/src/services/EventProcessorService.ts @@ -256,9 +256,15 @@ export async function processHandshakeResponseEvent( ? getBytes(contact.handshakeKemSecret) : undefined; + if (!initiatorKemSecret) { + onLog(`โœ— Missing KEM secret for contact ${contact.address.slice(0, 8)}...`); + return null; + } + const result = await verbethClient.verify.verifyAndExtractHandshakeResponseKeys( responseEvent, initiatorEphemeralSecret, + initiatorKemSecret, readProvider, identityContext ); diff --git a/packages/sdk/src/client/HsrTagIndex.ts b/packages/sdk/src/client/HsrTagIndex.ts index a25f18e..65db2a0 100644 --- a/packages/sdk/src/client/HsrTagIndex.ts +++ b/packages/sdk/src/client/HsrTagIndex.ts @@ -7,23 +7,19 @@ * when matching incoming handshake responses. */ -import { computeTagFromInitiator } from '../crypto.js'; +import { computeHybridTagFromInitiator, decryptHandshakeResponse } from '../crypto.js'; +import { kem } from '../pq/kem.js'; -/** - * Pending contact entry for HSR matching. - */ export interface PendingContactEntry { address: string; handshakeEphemeralSecret: Uint8Array; + kemSecretKey: Uint8Array; } -/** - * Cache entry storing computed tags per R value. - */ interface CacheEntry { address: string; secret: Uint8Array; - tagsByR: Map; + kemSecretKey: Uint8Array; } /** @@ -68,25 +64,20 @@ export class HsrTagIndex { for (const contact of contacts) { const existing = this.entries.get(contact.address); - if (existing && this.secretsEqual(existing.secret, contact.handshakeEphemeralSecret)) { + if (existing && + this.secretsEqual(existing.secret, contact.handshakeEphemeralSecret) && + this.secretsEqual(existing.kemSecretKey, contact.kemSecretKey)) { newEntries.set(contact.address, existing); } else { newEntries.set(contact.address, { address: contact.address, secret: contact.handshakeEphemeralSecret, - tagsByR: new Map(), + kemSecretKey: contact.kemSecretKey, }); } } - // Rebuild tagToAddress map - this.tagToAddress.clear(); - for (const [address, entry] of newEntries) { - for (const [, tag] of entry.tagsByR) { - this.tagToAddress.set(tag, address); - } - } - + // Keep tagToAddress cache - it's still valid for already computed tags this.entries = newEntries; } @@ -98,11 +89,13 @@ export class HsrTagIndex { addContact(contact: PendingContactEntry): void { const existing = this.entries.get(contact.address); - if (!existing || !this.secretsEqual(existing.secret, contact.handshakeEphemeralSecret)) { + if (!existing || + !this.secretsEqual(existing.secret, contact.handshakeEphemeralSecret) || + !this.secretsEqual(existing.kemSecretKey, contact.kemSecretKey)) { this.entries.set(contact.address, { address: contact.address, secret: contact.handshakeEphemeralSecret, - tagsByR: new Map(), + kemSecretKey: contact.kemSecretKey, }); } } @@ -115,9 +108,11 @@ export class HsrTagIndex { removeContact(address: string): void { const entry = this.entries.get(address); if (entry) { - // Remove all cached tags for this contact - for (const [, tag] of entry.tagsByR) { - this.tagToAddress.delete(tag); + // Remove any cached tags for this address + for (const [tag, addr] of this.tagToAddress) { + if (addr === address) { + this.tagToAddress.delete(tag); + } } this.entries.delete(address); } @@ -130,36 +125,36 @@ export class HsrTagIndex { } /** - * Match an HSR by its tag and responder ephemeral public key. + * Match an HSR by its tag using hybrid (PQ-secure) computation. * - * First checks the global tag cache for O(1) lookup. - * If not found, computes tags for all pending contacts for this R - * and caches them. + * Decrypts the payload internally to extract kemCiphertext, then + * decapsulates and computes the hybrid tag for matching. * * @param inResponseToTag - The tag from the HSR event * @param R - Responder's ephemeral public key (from HSR event) + * @param encryptedPayload - JSON string of the encrypted HSR payload * @returns Address of matching contact, or null if no match */ - matchByTag(inResponseToTag: `0x${string}`, R: Uint8Array): string | null { - // Fast path: check global tag cache + matchByTag( + inResponseToTag: `0x${string}`, + R: Uint8Array, + encryptedPayload: string + ): string | null { + // Cache check const cachedAddress = this.tagToAddress.get(inResponseToTag); if (cachedAddress) { return cachedAddress; } - // Slow path: compute tags for all contacts for this R - const rKey = this.bytesToHex(R); - + // For each contact: decrypt โ†’ extract kemCiphertext โ†’ decapsulate โ†’ compute hybrid tag for (const [address, entry] of this.entries) { - // Check if we already computed for this R - let tag = entry.tagsByR.get(rKey); - - if (!tag) { - // Compute and cache - tag = computeTagFromInitiator(entry.secret, R); - entry.tagsByR.set(rKey, tag); - this.tagToAddress.set(tag, address); - } + const decrypted = decryptHandshakeResponse(encryptedPayload, entry.secret); + if (!decrypted || !decrypted.kemCiphertext) continue; + + const kemSecret = kem.decapsulate(decrypted.kemCiphertext, entry.kemSecretKey); + const tag = computeHybridTagFromInitiator(entry.secret, R, kemSecret); + + this.tagToAddress.set(tag, address); if (tag === inResponseToTag) { return address; @@ -190,10 +185,4 @@ export class HsrTagIndex { } return true; } - - private bytesToHex(bytes: Uint8Array): string { - return Array.from(bytes) - .map(b => b.toString(16).padStart(2, '0')) - .join(''); - } } diff --git a/packages/sdk/src/client/VerbethClient.ts b/packages/sdk/src/client/VerbethClient.ts index bace0d4..fad9ea0 100644 --- a/packages/sdk/src/client/VerbethClient.ts +++ b/packages/sdk/src/client/VerbethClient.ts @@ -31,7 +31,7 @@ import { ratchetEncrypt } from '../ratchet/encrypt.js'; import { ratchetDecrypt } from '../ratchet/decrypt.js'; import { packageRatchetPayload, parseRatchetPayload, isRatchetPayload } from '../ratchet/codec.js'; import { verifyMessageSignature } from '../ratchet/auth.js'; -import { dh } from '../ratchet/kdf.js'; +import { dh, hybridInitialSecret } from '../ratchet/kdf.js'; import { initSessionAsInitiator, initSessionAsResponder } from '../ratchet/session.js'; import type { RatchetSession } from '../ratchet/types.js'; @@ -152,13 +152,11 @@ export class VerbethClient { * performs KEM encapsulation and returns kemSharedSecret. * * @param initiatorEphemeralPubKey - Initiator's ephemeral key (32 bytes X25519 or 1216 bytes with KEM) - * @param initiatorIdentityPubKey - Initiator's long-term X25519 identity key (kept for future use) * @param note - Response message to send back * @returns Transaction, derived topics, ephemeral keys for ratchet, and KEM shared secret */ async acceptHandshake( initiatorEphemeralPubKey: Uint8Array, - initiatorIdentityPubKey: Uint8Array, // Kept for potential future use note: string ): Promise { const { @@ -182,11 +180,16 @@ export class VerbethClient { ? initiatorEphemeralPubKey.slice(0, 32) : initiatorEphemeralPubKey; + if (!kemSharedSecret) { + throw new Error("KEM is required for PQ-secure handshake"); + } + const { topicOutbound, topicInbound } = this.deriveTopicsFromDH( responderEphemeralSecret, x25519Pub, salt, - false // responder swaps labels + false, + kemSharedSecret ); return { @@ -227,18 +230,18 @@ export class VerbethClient { initiatorKemSecret, } = params; - // Decapsulate KEM if present - let kemSecret: Uint8Array | undefined; - if (kemCiphertext && initiatorKemSecret) { - kemSecret = kem.decapsulate(kemCiphertext, initiatorKemSecret); + if (!kemCiphertext || !initiatorKemSecret) { + throw new Error("KEM is required for PQ-secure handshake"); } + const kemSecret = kem.decapsulate(kemCiphertext, initiatorKemSecret); const salt = getBytes(inResponseToTag); const { topicOutbound, topicInbound } = this.deriveTopicsFromDH( initiatorEphemeralSecret, responderEphemeralPubKey, salt, - true // initiator: no swap + true, + kemSecret ); return initSessionAsInitiator({ @@ -274,6 +277,10 @@ export class VerbethClient { kemSharedSecret, } = params; + if (!kemSharedSecret) { + throw new Error("KEM is required for PQ-secure handshake"); + } + // Extract X25519 part for topic derivation (first 32 bytes if extended) const x25519Pub = initiatorEphemeralPubKey.length > 32 ? initiatorEphemeralPubKey.slice(0, 32) @@ -283,7 +290,8 @@ export class VerbethClient { responderEphemeralSecret, x25519Pub, salt, - false // responder swaps labels + false, + kemSharedSecret ); return initSessionAsResponder({ @@ -312,38 +320,22 @@ export class VerbethClient { }); } - /** - * Derive epoch 0 topics from DH shared secret (handshake topics). - * - * NOTE: This uses the v2 scheme (DH + salt) for backward compatibility - * with epoch 0 topics. Post-handshake topics (epoch 1+) use the v3 scheme - * (DH + rootKey) via deriveTopic() for quantum-resistant unlinkability. - * - * @param mySecret - My ephemeral secret key - * @param theirPublic - Their ephemeral public key - * @param salt - Salt for topic derivation (typically the tag bytes) - * @param isInitiator - Whether this party is the initiator (affects label swap) - * @returns Derived outbound and inbound topics - */ private deriveTopicsFromDH( mySecret: Uint8Array, theirPublic: Uint8Array, salt: Uint8Array, - isInitiator: boolean + isInitiator: boolean, + kemSecret: Uint8Array ): { topicOutbound: `0x${string}`; topicInbound: `0x${string}` } { const ephemeralShared = dh(mySecret, theirPublic); + const hybridSecret = hybridInitialSecret(ephemeralShared, kemSecret); - // Inline epoch 0 topic derivation (v2 scheme: DH + salt) - // This keeps epoch 0 topics compatible while epoch 1+ use PQ-secure derivation const deriveEpoch0Topic = (direction: 'outbound' | 'inbound'): `0x${string}` => { const info = `verbeth:topic-${direction}:v2`; - const okm = hkdf(sha256, ephemeralShared, salt, info, 32); + const okm = hkdf(sha256, hybridSecret, salt, info, 32); return keccak256(okm) as `0x${string}`; }; - // Labels are from initiator's perspective - // Initiator: outbound='outbound', inbound='inbound' - // Responder: outbound='inbound', inbound='outbound' (swapped) if (isInitiator) { return { topicOutbound: deriveEpoch0Topic('outbound'), diff --git a/packages/sdk/src/crypto.ts b/packages/sdk/src/crypto.ts index c13cb4c..2e8557b 100644 --- a/packages/sdk/src/crypto.ts +++ b/packages/sdk/src/crypto.ts @@ -178,6 +178,33 @@ export function computeTagFromInitiator( return finalizeHsrTag(shared); } +// ============================================================================= +// Hybrid Tag Computation (PQ-Secure) +// ============================================================================= + +function finalizeHybridHsrTag(kemSecret: Uint8Array, ecdhShared: Uint8Array): `0x${string}` { + const okm = hkdf(sha256, kemSecret, ecdhShared, toUtf8Bytes("verbeth:hsr-hybrid:v1"), 32); + return keccak256(okm) as `0x${string}`; +} + +export function computeHybridTagFromResponder( + rSecretKey: Uint8Array, + viewPubA: Uint8Array, + kemSecret: Uint8Array +): `0x${string}` { + const ecdhShared = nacl.scalarMult(rSecretKey, viewPubA); + return finalizeHybridHsrTag(kemSecret, ecdhShared); +} + +export function computeHybridTagFromInitiator( + viewPrivA: Uint8Array, + R: Uint8Array, + kemSecret: Uint8Array +): `0x${string}` { + const ecdhShared = nacl.scalarMult(viewPrivA, R); + return finalizeHybridHsrTag(kemSecret, ecdhShared); +} + // ============================================================================= // REMOVED FUNCTIONS: // ============================================================================= diff --git a/packages/sdk/src/send.ts b/packages/sdk/src/send.ts index 5cb24f1..136dba5 100644 --- a/packages/sdk/src/send.ts +++ b/packages/sdk/src/send.ts @@ -17,7 +17,7 @@ import { } from './payload.js'; import { IdentityKeyPair, IdentityProof } from './types.js'; import { IExecutor } from './executor.js'; -import { computeTagFromResponder } from './crypto.js'; +import { computeHybridTagFromResponder } from './crypto.js'; import { kem } from './pq/kem.js'; /** ML-KEM keypair for PQ-hybrid handshake */ @@ -40,14 +40,13 @@ export async function initiateHandshake({ identityKeyPair, plaintextPayload, identityProof, - signer }: { executor: IExecutor; recipientAddress: string; identityKeyPair: IdentityKeyPair; plaintextPayload: string; identityProof: IdentityProof; - signer: Signer; + signer?: Signer; }): Promise<{ tx: any; ephemeralKeyPair: nacl.BoxKeyPair; @@ -114,7 +113,6 @@ export async function respondToHandshake({ responderIdentityKeyPair, note, identityProof, - signer, }: { executor: IExecutor; /** Initiator's ephemeral key (32 bytes X25519) OR extended key (1216 bytes: X25519 + ML-KEM) */ @@ -122,7 +120,7 @@ export async function respondToHandshake({ responderIdentityKeyPair: IdentityKeyPair; note?: string; identityProof: IdentityProof; - signer: Signer; + signer?: Signer; }): Promise<{ tx: any; salt: Uint8Array; @@ -169,14 +167,7 @@ export async function respondToHandshake({ ? initiatorEphemeralPubKey.slice(0, 32) : initiatorEphemeralPubKey; - // Tag is derived from tagKeyPair, not ratchetKeyPair - const inResponseTo = computeTagFromResponder( - tagKeyPair.secretKey, - initiatorX25519Pub - ); - const salt: Uint8Array = getBytes(inResponseTo); - - // Handle ML-KEM encapsulation if initiator supports it + // KEM encapsulation FIRST (needed for hybrid tag) let kemCiphertext: Uint8Array | undefined; let kemSharedSecret: Uint8Array | undefined; @@ -187,6 +178,18 @@ export async function respondToHandshake({ kemSharedSecret = sharedSecret; } + if (!kemSharedSecret) { + throw new Error("KEM is required for PQ-secure handshake"); + } + + // Hybrid tag: combines ECDH(r, viewPubA) + kemSecret + const inResponseTo = computeHybridTagFromResponder( + tagKeyPair.secretKey, + initiatorX25519Pub, + kemSharedSecret + ); + const salt: Uint8Array = getBytes(inResponseTo); + // Response content includes ratchetKeyPair.publicKey (hidden inside encrypted payload) // and includes kemCiphertext for PQ-hybrid handshake const responseContent = createHandshakeResponseContent( diff --git a/packages/sdk/src/verify.ts b/packages/sdk/src/verify.ts index e628dc7..b1961dc 100644 --- a/packages/sdk/src/verify.ts +++ b/packages/sdk/src/verify.ts @@ -2,7 +2,8 @@ // CLEANED VERSION - duplexTopics verification removed import { JsonRpcProvider, getBytes, hexlify, getAddress } from "ethers"; -import { decryptAndExtractHandshakeKeys, computeTagFromInitiator } from "./crypto.js"; +import { decryptAndExtractHandshakeKeys, computeHybridTagFromInitiator } from "./crypto.js"; +import { kem } from "./pq/kem.js"; // REMOVED: verifyDuplexTopicsChecksum, deriveDuplexTopics imports import { HandshakeLog, HandshakeResponseLog, IdentityProof, IdentityContext } from "./types.js"; // REMOVED: TopicInfoWire, DuplexTopics from imports @@ -247,6 +248,7 @@ export async function verifyAndExtractHandshakeKeys( export async function verifyAndExtractHandshakeResponseKeys( responseEvent: HandshakeResponseLog, initiatorEphemeralSecretKey: Uint8Array, + initiatorKemSecretKey: Uint8Array, provider: JsonRpcProvider, ctx?: IdentityContext ): Promise<{ @@ -255,20 +257,11 @@ export async function verifyAndExtractHandshakeResponseKeys( identityPubKey: Uint8Array; signingPubKey: Uint8Array; ephemeralPubKey: Uint8Array; - kemCiphertext?: Uint8Array; // from PQ-hybrid handshake + kemCiphertext?: Uint8Array; note?: string; }; }> { - - const Rbytes = getBytes(responseEvent.responderEphemeralR); // hex -> Uint8Array - const expectedTag = computeTagFromInitiator( - initiatorEphemeralSecretKey, - Rbytes - ); - if (expectedTag !== responseEvent.inResponseTo) { - return { isValid: false }; - } - + // Decrypt first to get kemCiphertext const extractedResponse = decryptAndExtractHandshakeKeys( responseEvent.ciphertext, initiatorEphemeralSecretKey @@ -278,6 +271,23 @@ export async function verifyAndExtractHandshakeResponseKeys( return { isValid: false }; } + if (!extractedResponse.kemCiphertext) { + return { isValid: false }; + } + + // Decapsulate and verify hybrid tag + const Rbytes = getBytes(responseEvent.responderEphemeralR); + const kemSecret = kem.decapsulate(extractedResponse.kemCiphertext, initiatorKemSecretKey); + const expectedTag = computeHybridTagFromInitiator( + initiatorEphemeralSecretKey, + Rbytes, + kemSecret + ); + + if (expectedTag !== responseEvent.inResponseTo) { + return { isValid: false }; + } + const isValid = await verifyHandshakeResponseIdentity( responseEvent, extractedResponse.identityPubKey, diff --git a/packages/sdk/test/crypto.test.ts b/packages/sdk/test/crypto.test.ts index 4083f52..d841d34 100644 --- a/packages/sdk/test/crypto.test.ts +++ b/packages/sdk/test/crypto.test.ts @@ -5,6 +5,8 @@ import { decryptStructuredPayload, decryptHandshakeResponse, decryptAndExtractHandshakeKeys, + computeHybridTagFromResponder, + computeHybridTagFromInitiator, } from "../src/crypto.js"; import { HandshakePayload, @@ -583,4 +585,71 @@ describe("Encryption/Decryption", () => { expect(decoded.identityProof).toEqual(identityProof); }); }); + + describe("Hybrid HSR Tag (PQ-Secure)", () => { + it("responder and initiator compute matching hybrid tags", () => { + const viewKeyPair = nacl.box.keyPair(); // Alice's ephemeral + const tagKeyPair = nacl.box.keyPair(); // Bob's tag keypair (r, R) + const kemSecret = nacl.randomBytes(32); + + const tagFromResponder = computeHybridTagFromResponder( + tagKeyPair.secretKey, // r + viewKeyPair.publicKey, // viewPubA + kemSecret + ); + + const tagFromInitiator = computeHybridTagFromInitiator( + viewKeyPair.secretKey, // viewPrivA + tagKeyPair.publicKey, // R + kemSecret + ); + + expect(tagFromResponder).toBe(tagFromInitiator); + expect(tagFromResponder).toMatch(/^0x[a-f0-9]{64}$/); + }); + + it("different kemSecret produces different tag (PQ unlinkability)", () => { + const viewKeyPair = nacl.box.keyPair(); + const tagKeyPair = nacl.box.keyPair(); + const kemSecret1 = nacl.randomBytes(32); + const kemSecret2 = nacl.randomBytes(32); + + const tag1 = computeHybridTagFromResponder( + tagKeyPair.secretKey, + viewKeyPair.publicKey, + kemSecret1 + ); + + const tag2 = computeHybridTagFromResponder( + tagKeyPair.secretKey, + viewKeyPair.publicKey, + kemSecret2 + ); + + // Same ECDH, different KEM -> different tags + expect(tag1).not.toBe(tag2); + }); + + it("different R produces different tag (R binding)", () => { + const viewKeyPair = nacl.box.keyPair(); + const tagKeyPair1 = nacl.box.keyPair(); + const tagKeyPair2 = nacl.box.keyPair(); + const kemSecret = nacl.randomBytes(32); + + const tag1 = computeHybridTagFromResponder( + tagKeyPair1.secretKey, + viewKeyPair.publicKey, + kemSecret + ); + + const tag2 = computeHybridTagFromResponder( + tagKeyPair2.secretKey, + viewKeyPair.publicKey, + kemSecret + ); + + // Same kemSecret, different ECDH -> different tags + expect(tag1).not.toBe(tag2); + }); + }); }); \ No newline at end of file diff --git a/packages/sdk/test/executor.test.ts b/packages/sdk/test/executor.test.ts index ab3b958..420f98e 100644 --- a/packages/sdk/test/executor.test.ts +++ b/packages/sdk/test/executor.test.ts @@ -11,6 +11,7 @@ import { } from "../src/index.js"; import type { LogChainV1 } from "@verbeth/contracts/typechain-types"; import { IdentityKeyPair, IdentityProof } from "../src/types.js"; +import { kem } from "../src/pq/kem.js"; const TEST_SMART_ACCOUNT_ADDRESS = "0x" + "12".repeat(20); const TEST_ENTRYPOINT_ADDRESS = "0x" + "45".repeat(20); @@ -52,7 +53,13 @@ const mockSigner = { } as unknown as Signer; // Test data -const testRecipientKey = nacl.box.keyPair(); +const testRecipientX25519Key = nacl.box.keyPair(); +const testKemKeyPair = kem.generateKeyPair(); +// Extended ephemeral key: X25519 (32) + ML-KEM (1184) = 1216 bytes +const testInitiatorEphemeralExtended = new Uint8Array(32 + kem.publicKeyBytes); +testInitiatorEphemeralExtended.set(testRecipientX25519Key.publicKey, 0); +testInitiatorEphemeralExtended.set(testKemKeyPair.publicKey, 32); + const testIdentityKeyPair: IdentityKeyPair = { publicKey: new Uint8Array(32).fill(1), secretKey: new Uint8Array(32).fill(2), @@ -177,7 +184,7 @@ describe("respondToHandshake with Executors", () => { await respondToHandshake({ executor, - initiatorEphemeralPubKey: testRecipientKey.publicKey, + initiatorEphemeralPubKey: testInitiatorEphemeralExtended, responderIdentityKeyPair: testIdentityKeyPair, note: "Response from EOA", identityProof: testIdentityProof, @@ -208,7 +215,7 @@ describe("respondToHandshake with Executors", () => { await respondToHandshake({ executor, - initiatorEphemeralPubKey: testRecipientKey.publicKey, + initiatorEphemeralPubKey: testInitiatorEphemeralExtended, responderIdentityKeyPair: testIdentityKeyPair, note: "Response from UserOp", identityProof: testIdentityProof, @@ -231,7 +238,7 @@ describe("respondToHandshake with Executors", () => { await respondToHandshake({ executor, - initiatorEphemeralPubKey: testRecipientKey.publicKey, + initiatorEphemeralPubKey: testInitiatorEphemeralExtended, responderIdentityKeyPair: testIdentityKeyPair, note: "Response from DirectEntryPoint", identityProof: testIdentityProof, @@ -248,7 +255,7 @@ describe("respondToHandshake with Executors", () => { await respondToHandshake({ executor, - initiatorEphemeralPubKey: testRecipientKey.publicKey, + initiatorEphemeralPubKey: testInitiatorEphemeralExtended, responderIdentityKeyPair: testIdentityKeyPair, // No responderEphemeralKeyPair provided note: "Auto-generated ephemeral key", diff --git a/packages/sdk/test/ratchet.test.ts b/packages/sdk/test/ratchet.test.ts index 3b15037..b87f07d 100644 --- a/packages/sdk/test/ratchet.test.ts +++ b/packages/sdk/test/ratchet.test.ts @@ -10,7 +10,6 @@ import { ratchetEncrypt, ratchetDecrypt, matchesSessionTopic, - TOPIC_TRANSITION_WINDOW_MS, type RatchetSession, } from '../src/ratchet/index.js'; diff --git a/plan-pq-metadata-v2.md b/plan-pq-metadata-v2.md new file mode 100644 index 0000000..a6628f8 --- /dev/null +++ b/plan-pq-metadata-v2.md @@ -0,0 +1,366 @@ +# Plan v2: PQ-Secure Metadata Unlinkability (Meno Invasivo) + +## Obiettivo +Stesso del piano v1: eliminare metadata leak per avversari quantum passivi. Non ci interessa migrazione. + +**Vincolo aggiuntivo**: NON modificare il contratto LogChainV1.sol. R (responderEphemeralR) deve rimanere utile. +Non essere ridondante con i commenti nel nuovo codice. + +## Le Due Vulnerabilita + +### 1. Topic Epoch 0 (VerbethClient.ts:338-342) +```typescript +// Attuale: solo X25519 DH + salt +const ephemeralShared = dh(mySecret, theirPublic); +const okm = hkdf(sha256, ephemeralShared, salt, info, 32); +``` +**Problema**: Un quantum attacker puo derivare `ephemeralShared` dalle chiavi pubbliche on-chain. + +### 2. inResponseTo (crypto.ts:162-168) +```typescript +// Attuale: solo ECDH +const shared = nacl.scalarMult(rSecretKey, viewPubA); +return finalizeHsrTag(shared); +``` +**Problema**: Con R e viewPubA entrambi on-chain, un quantum attacker puo calcolare `shared` e linkare HSโ†’HSR. + +--- + +## Soluzione: Tag Ibrido (Mantiene R Utile) + +### Idea Chiave +Invece di rimuovere R dal calcolo del tag, combiniamo **sia kemSecret che ECDH**: + +``` +tag = H(KDF(kemSecret, ECDH(r, viewPubA), "verbeth:hsr-hybrid")) +``` + +**Proprieta**: +- R e ancora necessario (per calcolare ECDH) +- kemSecret e necessario (PQ-secure component) +- Un quantum attacker puo rompere ECDH ma NON puo forgiare kemSecret +- Il contratto NON cambia + +--- + +## Refactor 1: Topic Epoch 0 PQ-Secure + +**File**: `packages/sdk/src/client/VerbethClient.ts` + +### Cambiamento +Aggiungere `kemSecret` come parametro e usarlo nel derivation: + +```typescript +private deriveTopicsFromDH( + mySecret: Uint8Array, + theirPublic: Uint8Array, + salt: Uint8Array, + isInitiator: boolean, + kemSecret?: Uint8Array // NUOVO parametro opzionale +): { topicOutbound: `0x${string}`; topicInbound: `0x${string}` } { + const ephemeralShared = dh(mySecret, theirPublic); + + // Se kemSecret presente, usa derivazione ibrida + const inputKeyMaterial = kemSecret + ? hybridInitialSecret(ephemeralShared, kemSecret) + : ephemeralShared; + + const deriveEpoch0Topic = (direction: 'outbound' | 'inbound'): `0x${string}` => { + const info = `verbeth:topic-${direction}:v2`; + const okm = hkdf(sha256, inputKeyMaterial, salt, info, 32); + return keccak256(okm) as `0x${string}`; + }; + // ... rest unchanged +} +``` + +### Call Sites da Aggiornare + +1. **acceptHandshake()** (linea ~185): passare `kemSharedSecret` +2. **createInitiatorSession()** (linea ~237): passare `kemSecret` (da decapsulation) + +### Impatto +- Minimo: solo aggiunta parametro opzionale +- Backward compat: senza kemSecret comportamento invariato + +--- + +## Refactor 2: Tag HSR Ibrido (R Rimane Utile) + +**File**: `packages/sdk/src/crypto.ts` + +### Nuove Funzioni + +```typescript +/** + * Hybrid HSR tag: combines KEM secret (PQ) and ECDH (classical). + * Both are required - quantum attacker cannot compute without kemSecret. + * + * R is still necessary to compute ecdhShared. + */ +export function computeHybridHsrTag( + kemSecret: Uint8Array, + ecdhShared: Uint8Array +): `0x${string}` { + // kemSecret as IKM, ecdhShared as salt -> both required + const okm = hkdf(sha256, kemSecret, ecdhShared, toUtf8Bytes("verbeth:hsr-hybrid:v1"), 32); + return keccak256(okm) as `0x${string}`; +} + +/** + * Responder computes hybrid tag. + * Uses R's secret key for ECDH + kemSecret from encapsulation. + */ +export function computeHybridTagFromResponder( + rSecretKey: Uint8Array, + viewPubA: Uint8Array, + kemSecret: Uint8Array +): `0x${string}` { + const ecdhShared = nacl.scalarMult(rSecretKey, viewPubA); + return computeHybridHsrTag(kemSecret, ecdhShared); +} + +/** + * Initiator computes hybrid tag for verification. + * Uses viewPrivA for ECDH + kemSecret from decapsulation. + */ +export function computeHybridTagFromInitiator( + viewPrivA: Uint8Array, + R: Uint8Array, + kemSecret: Uint8Array +): `0x${string}` { + const ecdhShared = nacl.scalarMult(viewPrivA, R); + return computeHybridHsrTag(kemSecret, ecdhShared); +} +``` + +### Perche R Rimane Utile +- `computeHybridTagFromInitiator(viewPrivA, R, kemSecret)` richiede R +- Senza R, l'initiator non puo calcolare `ecdhShared` +- Il tag dipende da entrambi: KEM (PQ) + ECDH (classical binding a R) + +--- + +## Refactor 3: send.ts (respondToHandshake) + +**File**: `packages/sdk/src/send.ts` + +### Cambiamento (linee 173-176) + +```typescript +// PRIMA: +const inResponseTo = computeTagFromResponder(tagKeyPair.secretKey, initiatorX25519Pub); + +// DOPO: +const inResponseTo = computeHybridTagFromResponder( + tagKeyPair.secretKey, + initiatorX25519Pub, + kemSharedSecret // gia disponibile da encapsulation (linea 187) +); +``` + +**Nota**: Bisogna riordinare il codice per fare KEM encapsulation PRIMA del tag computation. + +### Riordino Necessario + +```typescript +// 1. Handle KEM FIRST (spostare prima del tag) +let kemSharedSecret: Uint8Array | undefined; +let kemCiphertext: Uint8Array | undefined; +if (initiatorEphemeralPubKey.length === 32 + 1184) { + const initiatorKemPub = initiatorEphemeralPubKey.slice(32); + const result = kem.encapsulate(initiatorKemPub); + kemCiphertext = result.ciphertext; + kemSharedSecret = result.sharedSecret; +} + +// 2. Compute tag (now has kemSharedSecret) +const inResponseTo = kemSharedSecret + ? computeHybridTagFromResponder(tagKeyPair.secretKey, initiatorX25519Pub, kemSharedSecret) + : computeTagFromResponder(tagKeyPair.secretKey, initiatorX25519Pub); // fallback classico +``` + +--- + +## Refactor 4: HsrTagIndex (Matching Ibrido) + +**File**: `packages/sdk/src/client/HsrTagIndex.ts` + +### Cambiamento Dati + +```typescript +interface PendingContactEntry { + address: string; + handshakeEphemeralSecret: Uint8Array; // viewPrivA - MANTIENI + kemSecretKey?: Uint8Array; // NUOVO: per decapsulation +} +``` + +### Matching Logic Ibrida + +```typescript +/** + * Match HSR to pending contact. + * + * @param inResponseToTag - Tag from HSR event + * @param R - responderEphemeralR from event (still needed!) + * @param kemCiphertext - KEM ciphertext from decrypted payload (optional) + */ +matchByTag( + inResponseToTag: `0x${string}`, + R: Uint8Array, + kemCiphertext?: Uint8Array +): string | null { + // Fast path: cache lookup + const cached = this.tagToAddress.get(inResponseToTag); + if (cached) return cached; + + // Slow path: try each contact + for (const [address, entry] of this.entries) { + let expectedTag: `0x${string}`; + + if (kemCiphertext && entry.kemSecretKey) { + // Hybrid matching (PQ-secure) + const kemSecret = kem.decapsulate(kemCiphertext, entry.kemSecretKey); + expectedTag = computeHybridTagFromInitiator( + entry.handshakeEphemeralSecret, + R, // R e ancora usato! + kemSecret + ); + } else { + // Classic matching (backward compat) + expectedTag = computeTagFromInitiator(entry.handshakeEphemeralSecret, R); + } + + // Cache for future lookups + this.tagToAddress.set(expectedTag, address); + + if (expectedTag === inResponseToTag) { + return address; + } + } + return null; +} +``` + +### R e Ancora Usato! +Nel nuovo matching, R serve per: +1. Calcolare `ecdhShared = ECDH(viewPrivA, R)` +2. Combinare con kemSecret per il tag ibrido + +--- + +## Refactor 5: verify.ts (Verifica HSR) + +**File**: `packages/sdk/src/verify.ts` (linee 263-270) + +### Cambiamento + +```typescript +// PRIMA: +const expectedTag = computeTagFromInitiator(initiatorEphemeralSecretKey, Rbytes); + +// DOPO: +const expectedTag = kemSecret + ? computeHybridTagFromInitiator(initiatorEphemeralSecretKey, Rbytes, kemSecret) + : computeTagFromInitiator(initiatorEphemeralSecretKey, Rbytes); +``` + +--- + +## Riepilogo Modifiche + +| File | Modifica | Invasivita | +|------|----------|------------| +| `crypto.ts` | Aggiungi funzioni ibride (mantieni le vecchie) | Bassa | +| `send.ts` | Riordina KEM prima del tag, usa hybrid | Media | +| `VerbethClient.ts` | Aggiungi param `kemSecret` a deriveTopicsFromDH | Bassa | +| `HsrTagIndex.ts` | Aggiungi `kemSecretKey`, matching ibrido | Media | +| `verify.ts` | Supporto verifica ibrida | Bassa | +| **LogChainV1.sol** | **NESSUNA MODIFICA** | - | + +--- + +## Cosa NON Cambia + +1. **Contratto**: LogChainV1.sol rimane identico +2. **Evento HSR**: `responderEphemeralR` rimane nel contratto e viene usato +3. **Funzioni esistenti**: `computeTagFromResponder/Initiator` restano (backward compat) +4. **R on-chain**: Necessario per ECDH nel tag ibrido + +--- + +## Proprieta di Sicurezza + +| Proprieta | Prima | Dopo | +|-----------|-------|------| +| Topic Epoch 0 (quantum) | X (solo ECDH) | V (ibrido) | +| HSโ†’HSR Unlinkability (quantum) | X (R linkabile) | V (kemSecret required) | +| R utilita | V (tag ECDH) | V (tag ibrido) | +| Backward compat | - | V (fallback classico) | + +--- + +## Test + +```typescript +describe('PQ-secure hybrid tag', () => { + it('requires both kemSecret and R to compute tag', () => { + const viewPrivA = randomBytes(32); + const viewPubA = getPublicKey(viewPrivA); + const { secretKey: r, publicKey: R } = nacl.box.keyPair(); + const kemSecret = randomBytes(32); + + // Responder computes + const tagResp = computeHybridTagFromResponder(r, viewPubA, kemSecret); + + // Initiator verifies (needs R!) + const tagInit = computeHybridTagFromInitiator(viewPrivA, R, kemSecret); + + expect(tagResp).toBe(tagInit); + }); + + it('different kemSecret = different tag (PQ unlinkability)', () => { + const viewPrivA = randomBytes(32); + const viewPubA = getPublicKey(viewPrivA); + const { secretKey: r } = nacl.box.keyPair(); + + const tag1 = computeHybridTagFromResponder(r, viewPubA, randomBytes(32)); + const tag2 = computeHybridTagFromResponder(r, viewPubA, randomBytes(32)); + + // Same ECDH, different KEM -> different tags + expect(tag1).not.toBe(tag2); + }); + + it('quantum attacker cannot compute tag without kemSecret', () => { + // Attacker has: viewPubA (from HS), R (from HSR), can compute ECDH + // Attacker missing: kemSecret (encrypted in HSR payload) + // Result: cannot compute hybrid tag -> no linkability + }); +}); +``` + +--- + +## Demo App (apps/demo) + +Le modifiche alla demo app saranno minime perche il core logic e nell'SDK. + +**useMessageListener.ts**: +- Estrarre `kemCiphertext` dal payload HSR decryptato +- Passarlo a `matchByTag(tag, R, kemCiphertext)` + +**useChatActions.ts**: +- Salvare `kemSecretKey` quando si manda un HS (gia fatto per `handshakeKemSecret`) + +--- + +## Ordine di Implementazione + +1. `crypto.ts` - Aggiungere funzioni ibride +2. `send.ts` - Usare tag ibrido +3. `VerbethClient.ts` - Propagare kemSecret a deriveTopicsFromDH +4. `HsrTagIndex.ts` - Matching ibrido +5. `verify.ts` - Verifica ibrida +6. Test +7. Demo app adjustments diff --git a/previous-plan.md b/previous-plan.md deleted file mode 100644 index 8f17a19..0000000 --- a/previous-plan.md +++ /dev/null @@ -1,232 +0,0 @@ -# Plan: Quantum-Resistant Topic Unlinkability - -## Obiettivo -Derivare i topic da `rootKey` (PQ-secure) invece che solo da `dhOutput` (classico X25519), ottenendo **quantum-resistant topic unlinkability** senza il costo di un PQ-ratchet completo. - -## Analisi del Problema - -**Stato attuale** (`kdf.ts:87-94`): -```typescript -export function deriveTopicFromDH( - dhSharedSecret: Uint8Array, - direction: 'outbound' | 'inbound', - salt: Uint8Array // conversationId -): `0x${string}` { - const okm = hkdf(sha256, dhSharedSecret, salt, info, 32); - return keccak256(okm); -} -``` - -**Problema**: IKM = `dhSharedSecret` (X25519 solo). Un avversario quantum passivo puรฒ: -1. Calcolare tutti i `dhSecret` futuri con Shor -2. Derivare tutti i topic e linkare i messaggi alla sessione originale - -**Soluzione**: Usare `rootKey` (PQ-secure dall'handshake ibrido) come **salt** in HKDF: -```typescript -// Proposta -const okm = hkdf(sha256, dhOutput, rootKey, info, 32); -// ^IKM ^salt (PQ-secure) -``` - -Questo sfrutta la proprietร  di HKDF: anche conoscendo l'IKM, senza il salt l'output รจ indistinguibile da random. - -## Proprietร  di Sicurezza Preservate - -| Proprietร  | Prima | Dopo | Note | -|-----------|-------|------|------| -| **Bilateral Forward Secrecy** | โœ“ | โœ“ | DH ratchet continua a funzionare | -| **Post-Compromise Security (classical)** | โœ“ | โœ“ | Fresh DH โ†’ fresh chainKey | -| **PCS (quantum active)** | โœ— | โœ— | Richiede PQ-ratchet completo | -| **Topic-HS Unlinkability (classical)** | โœ“ | โœ“ | Invariato | -| **Topic-HS Unlinkability (quantum passive)** | โœ— | **โœ“** | **Nuovo** | -| **HNDL Resistance** | โœ“ | โœ“ | rootKey giร  PQ-secure | - -## Refactor - -### 1. Modificare `deriveTopicFromDH` โ†’ `deriveTopic` - -**File**: `packages/sdk/src/ratchet/kdf.ts` - -```typescript -/** - * Derive topic from DH output using rootKey as PQ-secure salt. - * - * The rootKey (PQ-secure from hybrid handshake) acts as HKDF salt, - * providing quantum-resistant topic unlinkability even if dhOutput - * is later computed by a quantum adversary. - */ -export function deriveTopic( - rootKey: Uint8Array, - dhOutput: Uint8Array, - direction: 'outbound' | 'inbound' -): `0x${string}` { - const info = `verbeth:topic-${direction}:v3`; - const okm = hkdf(sha256, dhOutput, rootKey, info, 32); - return keccak256(okm) as `0x${string}`; -} - -// REMOVE deriveTopicFromDH entirely (no migration needed) -``` - -**Note**: -- Rimosso `salt` (conversationId) - non necessario, rootKey fornisce domain separation -- `info` bumped a `:v3` per chiarezza -- rootKey come salt รจ crittograficamente corretto per HKDF -- **Nessuna deprecation**: rimuovere direttamente `deriveTopicFromDH` - -### 2. Aggiornare `initSessionAsInitiator` - -**File**: `packages/sdk/src/ratchet/session.ts` (linee 161-163) - -```typescript -// Prima: -const epoch1TopicOut = deriveTopicFromDH(dhSend, 'outbound', saltBytes); -const epoch1TopicIn = deriveTopicFromDH(dhSend, 'inbound', saltBytes); - -// Dopo: -const epoch1TopicOut = deriveTopic(finalRootKey, dhSend, 'outbound'); -const epoch1TopicIn = deriveTopic(finalRootKey, dhSend, 'inbound'); -``` - -`finalRootKey` รจ giร  disponibile nello scope (linea 153). - -### 3. Aggiornare `dhRatchetStep` - -**File**: `packages/sdk/src/ratchet/decrypt.ts` (linee 141-146) - -```typescript -// Prima: -const newTopicOut = deriveTopicFromDH(dhReceive, 'inbound', saltBytes); -const newTopicIn = deriveTopicFromDH(dhReceive, 'outbound', saltBytes); -const nextTopicOut = deriveTopicFromDH(dhSend, 'outbound', saltBytes); -const nextTopicIn = deriveTopicFromDH(dhSend, 'inbound', saltBytes); - -// Dopo: -const newTopicOut = deriveTopic(rootKey1, dhReceive, 'inbound'); -const newTopicIn = deriveTopic(rootKey1, dhReceive, 'outbound'); -const nextTopicOut = deriveTopic(rootKey2, dhSend, 'outbound'); -const nextTopicIn = deriveTopic(rootKey2, dhSend, 'inbound'); -``` - -`rootKey1` e `rootKey2` sono giร  derivati alle linee 126 e 136. - -### 4. (Opzionale) Topic iniziali handshake - -I topic dell'epoch 0 (handshake) sono derivati in `crypto.ts` durante l'handshake stesso. Questi usano ancora il DH dell'handshake ma con l'initial rootKey come salt. - -**File**: `packages/sdk/src/crypto.ts` (se applicabile) - -Se i topic handshake sono derivati con una funzione separata, aggiornare per usare il rootKey iniziale. - -## File da Modificare - -| File | Modifica | -|------|----------| -| `packages/sdk/src/ratchet/kdf.ts` | Nuova `deriveTopic()`, deprecare `deriveTopicFromDH` | -| `packages/sdk/src/ratchet/session.ts` | Aggiornare chiamate in `initSessionAsInitiator` | -| `packages/sdk/src/ratchet/decrypt.ts` | Aggiornare chiamate in `dhRatchetStep` | -| `packages/sdk/src/ratchet/index.ts` | Export nuova funzione | - -## Epoch 0 (Handshake Topics) - Considerazioni Speciali - -I topic dell'epoch 0 sono derivati in `VerbethClient.deriveTopicsFromDH()` **prima** che la sessione sia creata, quindi prima che il rootKey sia disponibile. - -**Strategia**: Lasciare i topic epoch 0 con il vecchio schema (DH-only con conversationSalt). - -**Razionale**: -1. L'handshake DH รจ giร  protetto dall'hybrid KEM โ†’ rootKey รจ PQ-secure -2. Dopo il primo DH ratchet (epoch 1+), i topic diventano PQ-unlinkable -3. Il "leak" รจ minimo: un avversario quantum puรฒ linkare l'epoch 0 all'handshake, ma non puรฒ: - - Decifrare i messaggi (rootKey PQ-secure) - - Linkare i topic epoch 1+ (derivati con rootKey come salt) -4. Propagare rootKey a VerbethClient richiederebbe refactor invasivo - -**Alternativa (futura)**: Derivare topic epoch 0 da una forma intermedia del rootKey. Richiede refactor piรน profondo di `initSession*` e `deriveTopicsFromDH`. - -## Non Modificare - -- `VerbethClient.deriveTopicsFromDH()`: topic epoch 0 restano con vecchio schema -- `initSessionAsResponder`: non pre-computa next topics (Alice lo fa al primo ratchet) -- Handshake payload/protocol: nessun cambiamento wire format -- Storage format: i topic sono giร  stringhe, nessun cambiamento schema - -## Backward Compatibility - -**Non necessaria**: Verbeth non รจ ancora in produzione. - -- Rimuovere `deriveTopicFromDH` direttamente -- Nessun migration path -- Aggiornare tutti i call site in un colpo solo - -## Test da Aggiornare - -**File**: `packages/sdk/test/ratchet.test.ts` - -### Nuovi test per `deriveTopic` - -```typescript -describe('deriveTopic (PQ-secure)', () => { - it('derives deterministic topic from rootKey + dhOutput', () => { - const rootKey = nacl.randomBytes(32); - const dhOutput = nacl.randomBytes(32); - - const topic1 = deriveTopic(rootKey, dhOutput, 'outbound'); - const topic2 = deriveTopic(rootKey, dhOutput, 'outbound'); - - expect(topic1).toBe(topic2); - }); - - it('derives different topics for different rootKeys (PQ-unlinkability)', () => { - const rootKey1 = nacl.randomBytes(32); - const rootKey2 = nacl.randomBytes(32); - const dhOutput = nacl.randomBytes(32); // STESSO dhOutput - - const topic1 = deriveTopic(rootKey1, dhOutput, 'outbound'); - const topic2 = deriveTopic(rootKey2, dhOutput, 'outbound'); - - // Proprietร  chiave: quantum adversary che conosce dhOutput - // ma non rootKey non puรฒ derivare il topic - expect(topic1).not.toBe(topic2); - }); - - it('derives different topics for different dhOutputs', () => { - const rootKey = nacl.randomBytes(32); - const dhOutput1 = nacl.randomBytes(32); - const dhOutput2 = nacl.randomBytes(32); - - const topic1 = deriveTopic(rootKey, dhOutput1, 'outbound'); - const topic2 = deriveTopic(rootKey, dhOutput2, 'outbound'); - - expect(topic1).not.toBe(topic2); - }); - - it('derives different topics for outbound vs inbound', () => { - const rootKey = nacl.randomBytes(32); - const dhOutput = nacl.randomBytes(32); - - const topicOut = deriveTopic(rootKey, dhOutput, 'outbound'); - const topicIn = deriveTopic(rootKey, dhOutput, 'inbound'); - - expect(topicOut).not.toBe(topicIn); - }); -}); -``` - -### Test da rimuovere - -- `describe('deriveTopicFromDH', ...)` - sostituito dai nuovi test `deriveTopic` - -### Test integrazione esistenti - -I test `DH ratchet step - topic rotation` e `topic continuity` restano validi - verificano solo che i topic ruotino correttamente, non come sono derivati. - -## Verifica End-to-End - -1. **Unit test**: `npm test` nella SDK -2. **Integration test**: - - Creare sessione con hybrid handshake - - Inviare messaggi, verificare topic rotation - - Controllare che `session.rootKey` sia usato nella derivazione -3. **Security test manuale**: - - Log `deriveTopic` inputs/outputs - - Verificare che stesso dhOutput + rootKey diversi โ†’ topic diversi From 9ef99a67961a3523364663f4cf5b53700be4f6c7 Mon Sep 17 00:00:00 2001 From: Marco Esposito Date: Thu, 29 Jan 2026 13:00:47 +0100 Subject: [PATCH 22/51] fix: remove uselss caching hsr match --- .gitignore | 3 +- apps/demo/src/hooks/useMessageListener.ts | 24 +-- packages/sdk/src/client/HsrTagIndex.ts | 188 ---------------------- packages/sdk/src/client/hsrMatcher.ts | 45 ++++++ packages/sdk/src/client/index.ts | 4 +- packages/sdk/src/index.ts | 2 +- 6 files changed, 58 insertions(+), 208 deletions(-) delete mode 100644 packages/sdk/src/client/HsrTagIndex.ts create mode 100644 packages/sdk/src/client/hsrMatcher.ts diff --git a/.gitignore b/.gitignore index c5536d7..3c2c2ec 100644 --- a/.gitignore +++ b/.gitignore @@ -24,4 +24,5 @@ ignition/deployments/chain-84532 .python-version *apps/notes/ -.claudeignore \ No newline at end of file +.claudeignore +CLAUDE.md \ No newline at end of file diff --git a/apps/demo/src/hooks/useMessageListener.ts b/apps/demo/src/hooks/useMessageListener.ts index 38a20a3..301a2a2 100644 --- a/apps/demo/src/hooks/useMessageListener.ts +++ b/apps/demo/src/hooks/useMessageListener.ts @@ -2,7 +2,7 @@ import { useState, useEffect, useRef, useCallback } from "react"; import { keccak256, toUtf8Bytes, getBytes, AbiCoder } from "ethers"; -import { HsrTagIndex, type PendingContactEntry } from "@verbeth/sdk"; +import { matchHsrToContact, type PendingContactEntry } from "@verbeth/sdk"; import { dbService } from "../services/DbService.js"; import { LOGCHAIN_SINGLETON_ADDR, @@ -47,7 +47,6 @@ export const useMessageListener = ({ const processedLogs = useRef(new Set()); const scanChunks = useRef([]); - const hsrTagIndex = useRef(new HsrTagIndex()); const calculateRecipientHash = (recipientAddr: string) => { return keccak256(toUtf8Bytes(`contact:${recipientAddr.toLowerCase()}`)); @@ -189,10 +188,10 @@ export const useMessageListener = ({ }; /** - * Match HSR event to a pending contact using HsrTagIndex for O(1) lookup. - * Uses cached tag computation for efficiency with many pending contacts. + * Match HSR event to a pending contact by computing hybrid tags. + * Complexity: O(N) where N = number of pending contacts. */ - const matchHsrToContact = ( + const findMatchingContact = ( log: any, pendingContacts: Contact[] ): Contact | null => { @@ -207,8 +206,8 @@ export const useMessageListener = ({ const R = getBytes(responderEphemeralRBytes); const encryptedPayload = new TextDecoder().decode(getBytes(ciphertextBytes)); - // Build index entries with kemSecretKey - const indexEntries: PendingContactEntry[] = pendingContacts + // Build entries for matching + const entries: PendingContactEntry[] = pendingContacts .filter((c): c is Contact & { handshakeEphemeralSecret: string; handshakeKemSecret: string; @@ -219,14 +218,7 @@ export const useMessageListener = ({ kemSecretKey: getBytes(c.handshakeKemSecret), })); - hsrTagIndex.current.rebuild(indexEntries); - - // matchByTag now does decrypt+match internally - const matchedAddress = hsrTagIndex.current.matchByTag( - inResponseTo, - R, - encryptedPayload - ); + const matchedAddress = matchHsrToContact(entries, inResponseTo, R, encryptedPayload); if (!matchedAddress) return null; return pendingContacts.find(c => c.address === matchedAddress) || null; @@ -291,7 +283,7 @@ export const useMessageListener = ({ // Match by cryptographic tag (not address) for (const log of responseLogs) { - const matchingContact = matchHsrToContact(log, pendingContacts); + const matchingContact = findMatchingContact(log, pendingContacts); if (matchingContact) { const logKey = `${log.transactionHash}-${log.logIndex}`; diff --git a/packages/sdk/src/client/HsrTagIndex.ts b/packages/sdk/src/client/HsrTagIndex.ts deleted file mode 100644 index 65db2a0..0000000 --- a/packages/sdk/src/client/HsrTagIndex.ts +++ /dev/null @@ -1,188 +0,0 @@ -// packages/sdk/src/client/HsrTagIndex.ts - -/** - * Index for O(1) HSR (Handshake Response) matching. - * - * Caches computed tags for pending contacts to avoid O(n) loops - * when matching incoming handshake responses. - */ - -import { computeHybridTagFromInitiator, decryptHandshakeResponse } from '../crypto.js'; -import { kem } from '../pq/kem.js'; - -export interface PendingContactEntry { - address: string; - handshakeEphemeralSecret: Uint8Array; - kemSecretKey: Uint8Array; -} - -interface CacheEntry { - address: string; - secret: Uint8Array; - kemSecretKey: Uint8Array; -} - -/** - * Index for efficient HSR tag matching. - * - * When an HSR arrives, we need to find which pending contact it belongs to. - * This requires computing tag = computeTagFromInitiator(secret, R) for each - * pending contact until we find a match. - * - * This class caches the computed tags per (contact, R) pair, making - * subsequent lookups O(1) after the first computation. - * - * @example - * ```typescript - * const hsrIndex = new HsrTagIndex(); - * - * // When pending contacts change - * hsrIndex.rebuild(pendingContacts.map(c => ({ - * address: c.address, - * handshakeEphemeralSecret: c.handshakeEphemeralSecret - * }))); - * - * // Matching O(1) after first computation for each R - * const matchedAddress = hsrIndex.matchByTag(inResponseToTag, R); - * ``` - */ -export class HsrTagIndex { - private entries: Map = new Map(); - private tagToAddress: Map = new Map(); - - /** - * Rebuild the index with a new set of pending contacts. - * - * Preserves cached tag computations for contacts that remain. - * Clears entries for contacts no longer in the list. - * - * @param contacts - Current pending contacts - */ - rebuild(contacts: PendingContactEntry[]): void { - const newEntries = new Map(); - - for (const contact of contacts) { - const existing = this.entries.get(contact.address); - - if (existing && - this.secretsEqual(existing.secret, contact.handshakeEphemeralSecret) && - this.secretsEqual(existing.kemSecretKey, contact.kemSecretKey)) { - newEntries.set(contact.address, existing); - } else { - newEntries.set(contact.address, { - address: contact.address, - secret: contact.handshakeEphemeralSecret, - kemSecretKey: contact.kemSecretKey, - }); - } - } - - // Keep tagToAddress cache - it's still valid for already computed tags - this.entries = newEntries; - } - - /** - * Add a single pending contact without full rebuild. - * - * @param contact - Contact to add - */ - addContact(contact: PendingContactEntry): void { - const existing = this.entries.get(contact.address); - - if (!existing || - !this.secretsEqual(existing.secret, contact.handshakeEphemeralSecret) || - !this.secretsEqual(existing.kemSecretKey, contact.kemSecretKey)) { - this.entries.set(contact.address, { - address: contact.address, - secret: contact.handshakeEphemeralSecret, - kemSecretKey: contact.kemSecretKey, - }); - } - } - - /** - * Remove a contact from the index. - * - * @param address - Address of contact to remove - */ - removeContact(address: string): void { - const entry = this.entries.get(address); - if (entry) { - // Remove any cached tags for this address - for (const [tag, addr] of this.tagToAddress) { - if (addr === address) { - this.tagToAddress.delete(tag); - } - } - this.entries.delete(address); - } - } - - - clear(): void { - this.entries.clear(); - this.tagToAddress.clear(); - } - - /** - * Match an HSR by its tag using hybrid (PQ-secure) computation. - * - * Decrypts the payload internally to extract kemCiphertext, then - * decapsulates and computes the hybrid tag for matching. - * - * @param inResponseToTag - The tag from the HSR event - * @param R - Responder's ephemeral public key (from HSR event) - * @param encryptedPayload - JSON string of the encrypted HSR payload - * @returns Address of matching contact, or null if no match - */ - matchByTag( - inResponseToTag: `0x${string}`, - R: Uint8Array, - encryptedPayload: string - ): string | null { - // Cache check - const cachedAddress = this.tagToAddress.get(inResponseToTag); - if (cachedAddress) { - return cachedAddress; - } - - // For each contact: decrypt โ†’ extract kemCiphertext โ†’ decapsulate โ†’ compute hybrid tag - for (const [address, entry] of this.entries) { - const decrypted = decryptHandshakeResponse(encryptedPayload, entry.secret); - if (!decrypted || !decrypted.kemCiphertext) continue; - - const kemSecret = kem.decapsulate(decrypted.kemCiphertext, entry.kemSecretKey); - const tag = computeHybridTagFromInitiator(entry.secret, R, kemSecret); - - this.tagToAddress.set(tag, address); - - if (tag === inResponseToTag) { - return address; - } - } - - return null; - } - - /** - * Get the number of indexed contacts. - */ - get size(): number { - return this.entries.size; - } - - /** - * Check if a contact is in the index. - */ - hasContact(address: string): boolean { - return this.entries.has(address); - } - - private secretsEqual(a: Uint8Array, b: Uint8Array): boolean { - if (a.length !== b.length) return false; - for (let i = 0; i < a.length; i++) { - if (a[i] !== b[i]) return false; - } - return true; - } -} diff --git a/packages/sdk/src/client/hsrMatcher.ts b/packages/sdk/src/client/hsrMatcher.ts new file mode 100644 index 0000000..89e2da2 --- /dev/null +++ b/packages/sdk/src/client/hsrMatcher.ts @@ -0,0 +1,45 @@ +// packages/sdk/src/client/hsrMatcher.ts + +import { computeHybridTagFromInitiator, decryptHandshakeResponse } from '../crypto.js'; +import { kem } from '../pq/kem.js'; + +export interface PendingContactEntry { + address: string; + handshakeEphemeralSecret: Uint8Array; + kemSecretKey: Uint8Array; +} + +/** + * Match an HSR event to a pending contact by computing hybrid tags. + * + * For each pending contact, attempts to decrypt the HSR payload and compute + * the expected tag. Returns the address of the first matching contact. + * + * Complexity: O(N) where N = number of pending contacts. + * Per contact: NaCl decrypt + ML-KEM decapsulate + HKDF tag computation. + * + * @param pendingContacts - Contacts with pending handshakes + * @param inResponseToTag - The tag from the HSR event (topics[1]) + * @param R - Responder's ephemeral public key (from HSR event data) + * @param encryptedPayload - JSON string of the encrypted HSR payload + * @returns Address of matching contact, or null if no match + */ +export function matchHsrToContact( + pendingContacts: PendingContactEntry[], + inResponseToTag: `0x${string}`, + R: Uint8Array, + encryptedPayload: string +): string | null { + for (const contact of pendingContacts) { + const decrypted = decryptHandshakeResponse(encryptedPayload, contact.handshakeEphemeralSecret); + if (!decrypted?.kemCiphertext) continue; + + const kemSecret = kem.decapsulate(decrypted.kemCiphertext, contact.kemSecretKey); + const tag = computeHybridTagFromInitiator(contact.handshakeEphemeralSecret, R, kemSecret); + + if (tag === inResponseToTag) { + return contact.address; + } + } + return null; +} diff --git a/packages/sdk/src/client/index.ts b/packages/sdk/src/client/index.ts index c1bfa51..a4a2140 100644 --- a/packages/sdk/src/client/index.ts +++ b/packages/sdk/src/client/index.ts @@ -2,7 +2,7 @@ export { VerbethClient } from './VerbethClient.js'; export { VerbethClientBuilder, createVerbethClient } from './VerbethClientBuilder.js'; -export { HsrTagIndex } from './HsrTagIndex.js'; +export { matchHsrToContact } from './hsrMatcher.js'; export type { CreateVerbethClientOptions, @@ -10,7 +10,7 @@ export type { export type { PendingContactEntry, -} from './HsrTagIndex.js'; +} from './hsrMatcher.js'; export type { VerbethClientConfig, diff --git a/packages/sdk/src/index.ts b/packages/sdk/src/index.ts index ed3392b..afebb45 100644 --- a/packages/sdk/src/index.ts +++ b/packages/sdk/src/index.ts @@ -51,7 +51,7 @@ export { VerbethClient, VerbethClientBuilder, createVerbethClient, - HsrTagIndex, + matchHsrToContact, } from './client/index.js'; export type { From 6d683840faa350f13dedfed57912603036e26f6d Mon Sep 17 00:00:00 2001 From: Marco Esposito Date: Thu, 29 Jan 2026 14:36:40 +0100 Subject: [PATCH 23/51] clean --- packages/sdk/src/client/PendingManager.ts | 8 +-- packages/sdk/src/client/SessionManager.ts | 15 +----- packages/sdk/src/client/types.ts | 27 +++-------- packages/sdk/src/crypto.ts | 36 +++----------- packages/sdk/src/executor.ts | 32 +++--------- packages/sdk/src/identity.ts | 13 ++--- packages/sdk/src/payload.ts | 12 ++--- packages/sdk/src/send.ts | 59 +++++++++-------------- packages/sdk/src/types.ts | 8 ++- packages/sdk/src/utils.ts | 15 +----- packages/sdk/src/verify.ts | 5 +- 11 files changed, 63 insertions(+), 167 deletions(-) diff --git a/packages/sdk/src/client/PendingManager.ts b/packages/sdk/src/client/PendingManager.ts index 93991d5..3c3ad3c 100644 --- a/packages/sdk/src/client/PendingManager.ts +++ b/packages/sdk/src/client/PendingManager.ts @@ -12,9 +12,6 @@ import { PendingStore, PendingMessage, PendingStatus } from './types.js'; -/** - * Parameters for creating a new pending message. - */ export interface CreatePendingParams { id: string; conversationId: string; @@ -26,9 +23,6 @@ export interface CreatePendingParams { createdAt: number; } -/** - * Internal pending message manager that wraps a PendingStore. - */ export class PendingManager { constructor(private store: PendingStore) {} @@ -79,7 +73,7 @@ export class PendingManager { /** - * Finalize (confirm) and delete. + * Finalize and delete. * Called when we see our MessageSent event on-chain. * * @returns The finalized pending message, or null if not found diff --git a/packages/sdk/src/client/SessionManager.ts b/packages/sdk/src/client/SessionManager.ts index c15c073..54fd881 100644 --- a/packages/sdk/src/client/SessionManager.ts +++ b/packages/sdk/src/client/SessionManager.ts @@ -13,9 +13,6 @@ import { RatchetSession, TOPIC_TRANSITION_WINDOW_MS } from '../ratchet/types.js'; import { SessionStore } from './types.js'; -/** - * Result of topic-based session lookup. - */ export interface TopicLookupResult { session: RatchetSession; topicMatch: 'current' | 'next' | 'previous'; @@ -38,13 +35,11 @@ export class SessionManager { * Get session by conversation ID, checking cache first. */ async getByConversationId(conversationId: string): Promise { - // Check cache first const cached = this.cache.get(conversationId); if (cached) { return cached; } - // Load from store const session = await this.store.get(conversationId); if (session) { this.cache.set(conversationId, session); @@ -66,19 +61,16 @@ export class SessionManager { async getByInboundTopic(topic: string): Promise { const topicLower = topic.toLowerCase(); - // Try store's topic lookup (handles all three cases) const session = await this.store.getByInboundTopic(topic); if (!session) { return null; } - // Check cache for more recent state (important for batched operations) + // Check cache for more recent state (e.g. for batched operations) const cached = this.cache.get(session.conversationId); let workingSession = cached || session; - // Determine which topic matched if (workingSession.currentTopicInbound.toLowerCase() === topicLower) { - // Cache if not already cached if (!cached) { this.cache.set(workingSession.conversationId, workingSession); } @@ -103,8 +95,7 @@ export class SessionManager { return { session: workingSession, topicMatch: 'previous' }; } - // Topic found in store but doesn't match current session state - // This shouldn't happen normally, but handle gracefully + // Topic found in store but doesn't match current session state (this shouldn't happen normally, but handle gracefully) return null; } @@ -122,7 +113,6 @@ export class SessionManager { /** * Update cache without persisting (for batch operations). - * Call save() after batch completes. */ updateCache(session: RatchetSession): void { this.cache.set(session.conversationId, session); @@ -130,7 +120,6 @@ export class SessionManager { /** * Persist all cached sessions to store. - * Used after batch operations. */ async flushCache(): Promise { const saves = Array.from(this.cache.values()).map(s => this.store.save(s)); diff --git a/packages/sdk/src/client/types.ts b/packages/sdk/src/client/types.ts index bca60b7..105e1dc 100644 --- a/packages/sdk/src/client/types.ts +++ b/packages/sdk/src/client/types.ts @@ -35,9 +35,6 @@ export interface MessageDecryptedEvent { /** * Optional callbacks for VerbethClient events. - * - * These callbacks allow apps to react to internal state changes - * without polling or manual session inspection. */ export interface VerbethClientCallbacks { /** @@ -67,8 +64,8 @@ export interface VerbethClientConfig { export interface HandshakeResult { tx: any; - ephemeralKeyPair: nacl.BoxKeyPair; // must persist secretKey for ratchet session init - kemKeyPair: KemKeyPair; // must persist secretKey for KEM decapsulation + ephemeralKeyPair: nacl.BoxKeyPair; + kemKeyPair: KemKeyPair; } export interface HandshakeResponseResult { @@ -77,28 +74,26 @@ export interface HandshakeResponseResult { topicInbound: `0x${string}`; tag: `0x${string}`; salt: Uint8Array; - responderEphemeralSecret: Uint8Array; // must persist as dhMySecretKey in ratchet + responderEphemeralSecret: Uint8Array; responderEphemeralPublic: Uint8Array; - kemSharedSecret?: Uint8Array; // from KEM encapsulation (32 bytes) - for hybrid KDF + kemSharedSecret?: Uint8Array; } /** - * Storage interface for ratchet sessions. - * Implement this to connect VerbethClient to your storage layer. + * Storage interface for ratchet sessions (to connect VerbethClient to a storage layer) */ export interface SessionStore { get(conversationId: string): Promise; /** * Find session by any active inbound topic. - * Must check: currentTopicInbound, nextTopicInbound, previousTopicInbound (if not expired). */ getByInboundTopic(topic: string): Promise; save(session: RatchetSession): Promise; } /** - * Result of prepareMessage - contains everything needed to send and commit. + * Result of prepareMessage contains everything needed to send and commit. * * Two-phase commit pattern: * 1. prepareMessage() - encrypts and returns PreparedMessage @@ -162,9 +157,6 @@ export interface PendingStore { getByConversation(conversationId: string): Promise; } -/** - * Result of sendMessage. - */ export interface SendResult { messageId: string; txHash: string; @@ -188,18 +180,13 @@ export interface SerializedSessionInfo { currentTopicInbound: string; } -/** - * HSR event data for createInitiatorSessionFromHsr convenience method. - */ + export interface HsrEventData { inResponseToTag: `0x${string}`; responderEphemeralPubKey: Uint8Array; kemCiphertext?: Uint8Array; } -/** - * Parameters for createInitiatorSessionFromHsr convenience method. - */ export interface CreateInitiatorSessionFromHsrParams { contactAddress: string; myEphemeralSecret: Uint8Array; diff --git a/packages/sdk/src/crypto.ts b/packages/sdk/src/crypto.ts index 2e8557b..ac295b0 100644 --- a/packages/sdk/src/crypto.ts +++ b/packages/sdk/src/crypto.ts @@ -1,17 +1,14 @@ // packages/sdk/src/crypto.ts -// CLEANED VERSION - duplexTopics and legacy functions removed /** - * Cryptographic utilities for Verbeth. - * * This module handles: - * - Handshake encryption/decryption (NaCl box - one-time exchange) + * - Handshake encryption/decryption * - Tag computation for handshake responses * - * NOTE: Post-handshake message encryption uses the ratchet module. + * Post-handshake message encryption uses the ratchet module. * See `ratchet/encrypt.ts` and `ratchet/decrypt.ts` for Double Ratchet. * - * NOTE: Topic derivation is now handled entirely by the ratchet module. + * Topic derivation is handled entirely by the ratchet module. * See `ratchet/kdf.ts` for `deriveTopicFromDH`. */ @@ -30,7 +27,7 @@ import { import { IdentityProof } from './types.js'; // ============================================================================= -// Handshake Encryption (NaCl Box) +// Handshake Encryption // ============================================================================= /** @@ -88,9 +85,7 @@ export function decryptStructuredPayload( // Handshake Response Decryption // ============================================================================= -/** - * Decrypts handshake response and extracts individual keys from unified format. - */ + export function decryptHandshakeResponse( payloadJson: string, initiatorEphemeralSecretKey: Uint8Array @@ -108,15 +103,12 @@ export function decryptHandshakeResponse( ...(obj.kemCiphertext && { kemCiphertext: Uint8Array.from(Buffer.from(obj.kemCiphertext, 'base64')) }), note: obj.note, identityProof: obj.identityProof, - // topicInfo removed - no longer needed }; } ); } -/** - * Helper to decrypt handshake response and extract individual keys. - */ + export function decryptAndExtractHandshakeKeys( payloadJson: string, initiatorEphemeralSecretKey: Uint8Array @@ -145,7 +137,7 @@ export function decryptAndExtractHandshakeKeys( } // ============================================================================= -// Tag Computation (Handshake Response Linkage) +// HSR Tag Computation // ============================================================================= /** @@ -203,16 +195,4 @@ export function computeHybridTagFromInitiator( ): `0x${string}` { const ecdhShared = nacl.scalarMult(viewPrivA, R); return finalizeHybridHsrTag(kemSecret, ecdhShared); -} - -// ============================================================================= -// REMOVED FUNCTIONS: -// ============================================================================= -// -// deriveLongTermShared() - was used for duplexTopics, now use ratchet/kdf.ts dh() -// deriveDuplexTopics() - replaced by deriveTopicFromDH() in ratchet/kdf.ts -// verifyDuplexTopicsChecksum() - no longer needed, topics derive from DH -// encryptMessage() - deprecated, use ratchetEncrypt() from ratchet module -// decryptMessage() - deprecated, use ratchetDecrypt() from ratchet module -// -// ============================================================================= \ No newline at end of file +} \ No newline at end of file diff --git a/packages/sdk/src/executor.ts b/packages/sdk/src/executor.ts index 8e8da1f..737ce10 100644 --- a/packages/sdk/src/executor.ts +++ b/packages/sdk/src/executor.ts @@ -20,7 +20,6 @@ function pack128x128(high: bigint, low: bigint): bigint { return (high << 128n) | (low & ((1n << 128n) - 1n)); } -// Unpack a packed 256-bit value into two 128-bit values export function split128x128(word: bigint): readonly [bigint, bigint] { const lowMask = (1n << 128n) - 1n; return [word >> 128n, word & lowMask] as const; @@ -116,7 +115,7 @@ export class BaseSmartAccountExecutor implements IExecutor { constructor( private baseAccountProvider: any, private logChainAddress: string, - chainId = 8453, // Base mainnet by default + chainId = 8453, private paymasterServiceUrl?: string, private subAccountAddress?: string ) { @@ -126,7 +125,6 @@ export class BaseSmartAccountExecutor implements IExecutor { "function respondToHandshake(bytes32 inResponseTo, bytes32 responderEphemeralR, bytes ciphertext)", ]); - // Convert chainId to hex this.chainId = chainId === 8453 ? "0x2105" // Base mainnet @@ -200,7 +198,6 @@ export class BaseSmartAccountExecutor implements IExecutor { calls: Array<{ to: string; value: string; data: string }> ) { try { - //console.log("DEBUG: Sub account address:", this.subAccountAddress); const requestParams: any = { version: "1.0", chainId: this.chainId, @@ -210,7 +207,6 @@ export class BaseSmartAccountExecutor implements IExecutor { //** WORK IN PROGRESS */ if (this.subAccountAddress) { requestParams.from = this.subAccountAddress; - //console.log("DEBUG: Using sub account for transaction"); } if (this.paymasterServiceUrl) { @@ -219,24 +215,19 @@ export class BaseSmartAccountExecutor implements IExecutor { url: this.paymasterServiceUrl, }, }; - //console.log("DEBUG: Using paymaster for gas sponsorship"); } - //console.log("DEBUG: Request params:", requestParams); - const result = await this.baseAccountProvider.request({ method: "wallet_sendCalls", params: [requestParams], }); - // first 32 bytes are the actual userop hash if ( typeof result === "string" && result.startsWith("0x") && result.length > 66 ) { - const actualTxHash = "0x" + result.slice(2, 66); // Extract first 32 bytes - //console.log("DEBUG: extracted tx hash:", actualTxHash); + const actualTxHash = "0x" + result.slice(2, 66); return { hash: actualTxHash }; } @@ -265,7 +256,6 @@ export class UserOpExecutor implements IExecutor { "function respondToHandshake(bytes32 inResponseTo, bytes32 responderEphemeralR, bytes ciphertext)", ]); - // Smart account interface for executing calls to other contracts this.smartAccountInterface = new Interface([ "function execute(address target, uint256 value, bytes calldata data) returns (bytes)", ]); @@ -286,7 +276,7 @@ export class UserOpExecutor implements IExecutor { "execute", [ this.logChainAddress, - 0, // value + 0, logChainCallData, ] ); @@ -309,7 +299,7 @@ export class UserOpExecutor implements IExecutor { "execute", [ this.logChainAddress, - 0, // value + 0, logChainCallData, ] ); @@ -331,7 +321,7 @@ export class UserOpExecutor implements IExecutor { "execute", [ this.logChainAddress, - 0, // value + 0, logChainCallData, ] ); @@ -371,7 +361,7 @@ export class UserOpExecutor implements IExecutor { } } -// Direct EntryPoint Executor - for local testing (bypasses bundler) +// Direct EntryPoint Executor (bypasses bundler for local testing) export class DirectEntryPointExecutor implements IExecutor { private logChainInterface: Interface; private smartAccountInterface: Interface; @@ -391,7 +381,6 @@ export class DirectEntryPointExecutor implements IExecutor { "function respondToHandshake(bytes32 inResponseTo, bytes32 responderEphemeralR, bytes ciphertext)", ]); - // Smart account interface for executing calls to other contracts this.smartAccountInterface = new Interface([ "function execute(address target, uint256 value, bytes calldata data) returns (bytes)", ]); @@ -438,7 +427,7 @@ export class DirectEntryPointExecutor implements IExecutor { "execute", [ this.logChainAddress, - 0, // value + 0, logChainCallData, ] ); @@ -460,7 +449,7 @@ export class DirectEntryPointExecutor implements IExecutor { "execute", [ this.logChainAddress, - 0, // value + 0, logChainCallData, ] ); @@ -505,15 +494,12 @@ export class DirectEntryPointExecutor implements IExecutor { } as UserOpV07; } - // Pad bigints, bytes32 before signing const paddedUserOp = padBigints(userOp); - //console.log("Padded UserOp:", paddedUserOp); const signed = await this.smartAccountClient.signUserOperation( paddedUserOp ); - // Direct submit to EntryPoint const tx = await this.entryPointContract.handleOps( [signed], await this.signer.getAddress() @@ -599,7 +585,6 @@ export class ExecutorFactory { try { const provider = signerOrAccount?.provider || signerOrAccount; if (provider && typeof provider.request === "function") { - // test if provider supports wallet_sendCalls const capabilities = await provider .request({ method: "wallet_getCapabilities", @@ -650,7 +635,6 @@ export class ExecutorFactory { } } - // default to EOA executor return new EOAExecutor(contract); } } diff --git a/packages/sdk/src/identity.ts b/packages/sdk/src/identity.ts index 4696114..280c6e0 100644 --- a/packages/sdk/src/identity.ts +++ b/packages/sdk/src/identity.ts @@ -29,8 +29,7 @@ function bigIntTo32BytesBE(x: bigint): Uint8Array { } /** - * Canonicalize an Ethereum ECDSA signature (65 bytes) to low-s form. - * This is only used as KDF input. + * Canonicalize an Ethereum ECDSA signature (65 bytes) to low-s form (only used as KDF input) */ function canonicalizeEcdsaSig65(sig: Uint8Array): Uint8Array { if (sig.length !== 65) return sig; @@ -107,11 +106,10 @@ export async function deriveIdentityKeys( const enc = new TextEncoder(); const addrLower = address.toLowerCase(); - // 1) Signature-based seed const seedMessage = buildSeedMessage(addrLower); let seedSignature = await signer.signMessage(seedMessage); const seedSigBytes = canonicalizeEcdsaSig65(getBytes(seedSignature)); - seedSignature = ""; // wipe from memory + seedSignature = ""; // IKM = HKDF( canonicalSig || H(seedMessage) || "verbeth/addr:" || address_lower ) const seedSalt = enc.encode("verbeth/seed-sig-v1"); @@ -132,14 +130,13 @@ export async function deriveIdentityKeys( const ed25519_seed = hkdf(sha256, ikm, new Uint8Array(0), info_ed25519, 32); const signKeyPair = nacl.sign.keyPair.fromSeed(ed25519_seed); - // Derive secp256k1 session key (for Ethereum txs via Safe module) + // Derive secp256k1 session key for txs via Safe module const info_session = enc.encode("verbeth-session-secp256k1-v1"); const sessionSeed = hkdf(sha256, ikm, new Uint8Array(0), info_session, 32); const sessionPrivateKey = hexlify(sessionSeed); const sessionWallet = new Wallet(sessionPrivateKey); const sessionAddress = sessionWallet.address; - // wipe intermediates try { seedSigBytes.fill(0); seedMsgHash.fill(0); @@ -250,8 +247,8 @@ export async function deriveIdentityWithUnifiedKeys( ); const unifiedPubKeys = encodeUnifiedPubKeys( - result.keyPair.publicKey, // X25519 - result.keyPair.signingPublicKey // Ed25519 + result.keyPair.publicKey, + result.keyPair.signingPublicKey ); return { diff --git a/packages/sdk/src/payload.ts b/packages/sdk/src/payload.ts index fdadd15..a63b514 100644 --- a/packages/sdk/src/payload.ts +++ b/packages/sdk/src/payload.ts @@ -1,9 +1,6 @@ // packages/sdk/src/payload.ts -// CLEANED VERSION - TopicInfoWire removed import { IdentityProof } from './types.js'; -// REMOVED: TopicInfoWire import - export interface EncryptedPayload { v: number; // version @@ -124,7 +121,6 @@ export function decodeUnifiedPubKeys(pubKeys: Uint8Array): { signingPubKey: Uint8Array; } | null { if (pubKeys.length === 64) { - // Legacy return { version: 0, identityPubKey: pubKeys.slice(0, 32), @@ -133,7 +129,6 @@ export function decodeUnifiedPubKeys(pubKeys: Uint8Array): { } if (pubKeys.length === 65 && pubKeys[0] === 0x01) { - // V1: with versioning return { version: 1, identityPubKey: pubKeys.slice(1, 33), @@ -145,15 +140,15 @@ export function decodeUnifiedPubKeys(pubKeys: Uint8Array): { } export interface HandshakePayload { - unifiedPubKeys: Uint8Array; // 65 bytes: version + X25519 + Ed25519 + unifiedPubKeys: Uint8Array; ephemeralPubKey: Uint8Array; plaintextPayload: string; } export interface HandshakeResponseContent { - unifiedPubKeys: Uint8Array; // 65 bytes: version + X25519 + Ed25519 + unifiedPubKeys: Uint8Array; ephemeralPubKey: Uint8Array; - kemCiphertext?: Uint8Array; // ML-KEM-768 ciphertext (1088 bytes) for PQ hybrid handshake + kemCiphertext?: Uint8Array; note?: string; identityProof: IdentityProof; } @@ -200,7 +195,6 @@ export function decodeHandshakeResponseContent(encoded: Uint8Array): HandshakeRe ...(obj.kemCiphertext && { kemCiphertext: Uint8Array.from(Buffer.from(obj.kemCiphertext, 'base64')) }), note: obj.note, identityProof: obj.identityProof, - // REMOVED: topicInfo decoding }; } diff --git a/packages/sdk/src/send.ts b/packages/sdk/src/send.ts index 136dba5..2aa4216 100644 --- a/packages/sdk/src/send.ts +++ b/packages/sdk/src/send.ts @@ -20,7 +20,6 @@ import { IExecutor } from './executor.js'; import { computeHybridTagFromResponder } from './crypto.js'; import { kem } from './pq/kem.js'; -/** ML-KEM keypair for PQ-hybrid handshake */ export interface KemKeyPair { publicKey: Uint8Array; secretKey: Uint8Array; @@ -28,11 +27,9 @@ export interface KemKeyPair { /** * Initiates an on-chain handshake with unified keys and mandatory identity proof. - * Executor-agnostic: works with EOA, UserOp, and Direct EntryPoint (for tests) - * - * Includes ML-KEM-768 public key for post-quantum hybrid key exchange. - * - * @returns Transaction, ephemeral keypair, and KEM keypair (MUST be persisted for session init) + * Executor-agnostic: works with EOA, UserOp, and Direct EntryPoint + * + * @returns Transaction, ephemeral keypair, and KEM keypair (must be persisted for session init) */ export async function initiateHandshake({ executor, @@ -73,10 +70,9 @@ export async function initiateHandshake({ const serializedPayload = serializeHandshakeContent(handshakeContent); - // Create unified pubKeys (65 bytes: version + X25519 + Ed25519) const unifiedPubKeys = encodeUnifiedPubKeys( - identityKeyPair.publicKey, // X25519 for encryption - identityKeyPair.signingPublicKey // Ed25519 for signing + identityKeyPair.publicKey, + identityKeyPair.signingPublicKey ); // Ephemeral public key now includes KEM public key (32 + 1184 = 1216 bytes) @@ -93,17 +89,16 @@ export async function initiateHandshake({ return { tx, - ephemeralKeyPair, // Caller MUST persist secretKey for ratchet session init - kemKeyPair, // Caller MUST also persist secretKey for KEM decapsulation + ephemeralKeyPair, // Caller must persist secretKey for ratchet session init + kemKeyPair, // Caller must also persist secretKey for KEM decapsulation }; } /** * Responds to a handshake with unified keys and mandatory identity proof. - * Executor-agnostic: works with EOA, UserOp, and Direct EntryPoint (for tests) + * Executor-agnostic: works with EOA, UserOp, and Direct EntryPoint * - * Supports PQ-hybrid handshake: if initiator includes KEM public key, - * encapsulates a shared secret and includes ciphertext in response. + * If initiator includes KEM public key, encapsulates a shared secret and includes ciphertext in response. * * @returns Transaction, tag, salt, ephemeral keys, and KEM secret */ @@ -125,11 +120,11 @@ export async function respondToHandshake({ tx: any; salt: Uint8Array; tag: `0x${string}`; - /** Responder's DH ratchet secret - must persist as dhMySecretKey in ratchet session */ + // Responder's DH ratchet secret (must persist as dhMySecretKey in ratchet session) responderEphemeralSecret: Uint8Array; - /** Responder's DH ratchet public - inside encrypted payload, not on-chain */ + // Responder's DH ratchet public (inside encrypted payload) responderEphemeralPublic: Uint8Array; - /** ML-KEM shared secret (32 bytes) - MUST persist for hybrid KDF, undefined if no KEM in handshake */ + // ML-KEM shared secret (32 bytes) (must persist for hybrid KDF, undefined if no KEM in handshake) */ kemSharedSecret?: Uint8Array; }> { if (!executor) { @@ -139,13 +134,13 @@ export async function respondToHandshake({ // ========================================================================= // TWO SEPARATE KEYPAIRS for unlinkability: // - // 1. tagKeyPair (R, r): ONLY for tag computation + // 1. tagKeyPair (R, r): only for tag computation // - R goes on-chain as responderEphemeralR // - Used by Alice to verify the tag - // - NOT used for ratchet + // - not used for ratchet // // 2. ratchetKeyPair: For post-handshake encryption and first DH ratchet key - // - Public key goes INSIDE encrypted payload (not on-chain) + // - Public key goes inside encrypted payload // - Becomes dhMySecretKey/dhMyPublicKey in ratchet session // // Why this matters: With a single keypair, the on-chain R would equal the @@ -153,21 +148,16 @@ export async function respondToHandshake({ // to subsequent conversation. With two keypairs, there's no on-chain link. // ========================================================================= - // Keypair for tag computation - R goes on-chain const tagKeyPair = nacl.box.keyPair(); - - // Keypair for ratchet - public key is HIDDEN inside encrypted payload const ratchetKeyPair = nacl.box.keyPair(); // Check if initiator included KEM public key (extended format: 32 + 1184 = 1216 bytes) const hasKem = initiatorEphemeralPubKey.length === 32 + kem.publicKeyBytes; - - // Extract X25519 ephemeral key (first 32 bytes) const initiatorX25519Pub = hasKem ? initiatorEphemeralPubKey.slice(0, 32) : initiatorEphemeralPubKey; - // KEM encapsulation FIRST (needed for hybrid tag) + // KEM encapsulation needed for hybrid tag let kemCiphertext: Uint8Array | undefined; let kemSharedSecret: Uint8Array | undefined; @@ -182,7 +172,7 @@ export async function respondToHandshake({ throw new Error("KEM is required for PQ-secure handshake"); } - // Hybrid tag: combines ECDH(r, viewPubA) + kemSecret + // Hybrid tag combines ECDH(r, viewPubA) + kemSecret const inResponseTo = computeHybridTagFromResponder( tagKeyPair.secretKey, initiatorX25519Pub, @@ -190,12 +180,10 @@ export async function respondToHandshake({ ); const salt: Uint8Array = getBytes(inResponseTo); - // Response content includes ratchetKeyPair.publicKey (hidden inside encrypted payload) - // and includes kemCiphertext for PQ-hybrid handshake const responseContent = createHandshakeResponseContent( - responderIdentityKeyPair.publicKey, // X25519 identity - responderIdentityKeyPair.signingPublicKey, // Ed25519 signing - ratchetKeyPair.publicKey, // First DH ratchet key (INSIDE payload) + responderIdentityKeyPair.publicKey, + responderIdentityKeyPair.signingPublicKey, + ratchetKeyPair.publicKey, // first DH ratchet key inside payload note, identityProof, kemCiphertext @@ -209,10 +197,10 @@ export async function respondToHandshake({ ratchetKeyPair.publicKey ); - // Execute transaction - tagKeyPair.publicKey goes on-chain (NOT ratchetKeyPair) + // tagKeyPair.publicKey goes on-chain, not ratchetKeyPair const tx = await executor.respondToHandshake( inResponseTo, - hexlify(tagKeyPair.publicKey), // Tag key on-chain for tag verification + hexlify(tagKeyPair.publicKey), toUtf8Bytes(payload) ); @@ -220,8 +208,7 @@ export async function respondToHandshake({ tx, salt, tag: inResponseTo, - // Return RATCHET keys (not tag keys) for session initialization - // These are DIFFERENT from the on-chain responderEphemeralR + // Return ratchet keys for session initialization responderEphemeralSecret: ratchetKeyPair.secretKey, responderEphemeralPublic: ratchetKeyPair.publicKey, kemSharedSecret, diff --git a/packages/sdk/src/types.ts b/packages/sdk/src/types.ts index 8828f15..b57e583 100644 --- a/packages/sdk/src/types.ts +++ b/packages/sdk/src/types.ts @@ -11,19 +11,18 @@ export interface LogMessage { export interface HandshakeLog { recipientHash: string; sender: string; - pubKeys: string; // Unified field (hex string of 65 bytes: version + X25519 + Ed25519) + pubKeys: string; // hex string of 65 bytes: version + X25519 + Ed25519 ephemeralPubKey: string; - plaintextPayload: string; // always contains JSON with identityProof + plaintextPayload: string; } export interface HandshakeResponseLog { inResponseTo: string; responder: string; responderEphemeralR: string; - ciphertext: string; // Contains unified pubKeys + identityProof encrypted + ciphertext: string; } -// Identity key pair structure export interface IdentityKeyPair { // X25519 keys per encryption/decryption publicKey: Uint8Array; @@ -42,7 +41,6 @@ export interface IdentityContext { rpId?: string; } -// Identity proof structure export interface IdentityProof { message: string; signature: string; diff --git a/packages/sdk/src/utils.ts b/packages/sdk/src/utils.ts index 4245896..d940242 100644 --- a/packages/sdk/src/utils.ts +++ b/packages/sdk/src/utils.ts @@ -1,5 +1,4 @@ // packages/sdk/src/utils.ts -// CLEANED VERSION - pickOutboundTopic and DuplexTopics removed import { Contract, @@ -15,7 +14,6 @@ import { defineChain, type PublicClient, } from "viem"; -// REMOVED: DuplexTopics import no longer needed export function parseBindingMessage(message: string): { @@ -110,7 +108,7 @@ export function hasERC6492Suffix(sigHex: string): boolean { /** * Checks if an address is a smart contract that supports EIP-1271 signature verification - * Returns true if the address has deployed code AND implements isValidSignature function + * Returns true if the address has deployed code and implements isValidSignature function */ export async function isSmartContract1271( address: string, @@ -178,13 +176,4 @@ export async function isSmartContract1271( console.error("Error checking if address is smart contract:", err); return false; } -} - -// ============================================================================= -// REMOVED FUNCTIONS: -// ============================================================================= -// -// pickOutboundTopic() - removed, no longer using DuplexTopics structure -// Topics are now derived directly from ephemeral DH -// -// ============================================================================= \ No newline at end of file +} \ No newline at end of file diff --git a/packages/sdk/src/verify.ts b/packages/sdk/src/verify.ts index b1961dc..3aa1120 100644 --- a/packages/sdk/src/verify.ts +++ b/packages/sdk/src/verify.ts @@ -1,12 +1,9 @@ // packages/sdk/src/verify.ts -// CLEANED VERSION - duplexTopics verification removed import { JsonRpcProvider, getBytes, hexlify, getAddress } from "ethers"; import { decryptAndExtractHandshakeKeys, computeHybridTagFromInitiator } from "./crypto.js"; import { kem } from "./pq/kem.js"; -// REMOVED: verifyDuplexTopicsChecksum, deriveDuplexTopics imports import { HandshakeLog, HandshakeResponseLog, IdentityProof, IdentityContext } from "./types.js"; -// REMOVED: TopicInfoWire, DuplexTopics from imports import { parseHandshakePayload, parseHandshakeKeys } from "./payload.js"; import { Rpcish, @@ -120,7 +117,7 @@ export async function verifyHandshakeResponseIdentity( } /** - * Verify "IdentityProof" for EOAs and smart accounts. + * Verify IdentityProof for EOAs and smart accounts. * - Verifies the signature with viem (EOA / ERC-1271 / ERC-6492). * - Parses and checks the expected address and public key against the message content. */ From 08ca36789b98d25f8eb927cbf83bdb6a2a82b782 Mon Sep 17 00:00:00 2001 From: Marco Esposito Date: Thu, 29 Jan 2026 15:10:46 +0100 Subject: [PATCH 24/51] pruned legacy code --- packages/sdk/src/client/VerbethClient.ts | 2 +- packages/sdk/src/client/types.ts | 2 +- packages/sdk/src/crypto.ts | 34 --------- packages/sdk/src/{send.ts => handshake.ts} | 2 +- packages/sdk/src/index.ts | 4 +- packages/sdk/src/payload.ts | 79 ------------------- packages/sdk/test/crypto.test.ts | 89 ---------------------- packages/sdk/test/simulation.test.ts | 7 -- packages/sdk/test/verify.test.ts | 88 --------------------- 9 files changed, 4 insertions(+), 303 deletions(-) rename packages/sdk/src/{send.ts => handshake.ts} (99%) diff --git a/packages/sdk/src/client/VerbethClient.ts b/packages/sdk/src/client/VerbethClient.ts index fad9ea0..c3648c6 100644 --- a/packages/sdk/src/client/VerbethClient.ts +++ b/packages/sdk/src/client/VerbethClient.ts @@ -14,7 +14,7 @@ import { hexlify, getBytes, keccak256 } from 'ethers'; import { hkdf } from '@noble/hashes/hkdf'; import { sha256 } from '@noble/hashes/sha2'; -import { initiateHandshake, respondToHandshake } from '../send.js'; +import { initiateHandshake, respondToHandshake } from '../handshake.js'; import { kem } from '../pq/kem.js'; import type { IExecutor } from '../executor.js'; import type { IdentityKeyPair, IdentityProof } from '../types.js'; diff --git a/packages/sdk/src/client/types.ts b/packages/sdk/src/client/types.ts index 105e1dc..862b0c9 100644 --- a/packages/sdk/src/client/types.ts +++ b/packages/sdk/src/client/types.ts @@ -12,7 +12,7 @@ import type { IExecutor } from '../executor.js'; import type { IdentityKeyPair, IdentityProof } from '../types.js'; import type { RatchetSession } from '../ratchet/types.js'; import type nacl from 'tweetnacl'; -import type { KemKeyPair } from '../send.js'; +import type { KemKeyPair } from '../handshake.js'; /** * Event emitted when topic ratcheting occurs. diff --git a/packages/sdk/src/crypto.ts b/packages/sdk/src/crypto.ts index ac295b0..2342b4d 100644 --- a/packages/sdk/src/crypto.ts +++ b/packages/sdk/src/crypto.ts @@ -136,40 +136,6 @@ export function decryptAndExtractHandshakeKeys( }; } -// ============================================================================= -// HSR Tag Computation -// ============================================================================= - -/** - * HKDF(sha256) on shared secret, info="verbeth:hsr", then Keccak-256 -> bytes32 (0x...) - */ -function finalizeHsrTag(shared: Uint8Array): `0x${string}` { - const okm = hkdf(sha256, shared, new Uint8Array(0), toUtf8Bytes("verbeth:hsr"), 32); - return keccak256(okm) as `0x${string}`; -} - -/** - * Responder: tag = H( KDF( ECDH(r, viewPubA), "verbeth:hsr")) - */ -export function computeTagFromResponder( - rSecretKey: Uint8Array, - viewPubA: Uint8Array -): `0x${string}` { - const shared = nacl.scalarMult(rSecretKey, viewPubA); - return finalizeHsrTag(shared); -} - -/** - * Initiator: tag = H( KDF( ECDH(viewPrivA, R), "verbeth:hsr")) - */ -export function computeTagFromInitiator( - viewPrivA: Uint8Array, - R: Uint8Array -): `0x${string}` { - const shared = nacl.scalarMult(viewPrivA, R); - return finalizeHsrTag(shared); -} - // ============================================================================= // Hybrid Tag Computation (PQ-Secure) // ============================================================================= diff --git a/packages/sdk/src/send.ts b/packages/sdk/src/handshake.ts similarity index 99% rename from packages/sdk/src/send.ts rename to packages/sdk/src/handshake.ts index 2aa4216..09e61c5 100644 --- a/packages/sdk/src/send.ts +++ b/packages/sdk/src/handshake.ts @@ -1,4 +1,4 @@ -// packages/sdk/src/send.ts +// packages/sdk/src/handshake.ts import { keccak256, diff --git a/packages/sdk/src/index.ts b/packages/sdk/src/index.ts index afebb45..badd24f 100644 --- a/packages/sdk/src/index.ts +++ b/packages/sdk/src/index.ts @@ -2,7 +2,7 @@ export * from './crypto.js'; export * from './payload.js'; -export * from './send.js'; +export * from './handshake.js'; export * from './verify.js'; export * from './types.js'; export * from './utils.js'; @@ -12,9 +12,7 @@ export * from './executor.js'; export { encodeUnifiedPubKeys, decodeUnifiedPubKeys, - createHandshakePayload, createHandshakeResponseContent, - extractKeysFromHandshakePayload, extractKeysFromHandshakeResponse, parseHandshakeKeys } from './payload.js'; diff --git a/packages/sdk/src/payload.ts b/packages/sdk/src/payload.ts index a63b514..5fcfd9a 100644 --- a/packages/sdk/src/payload.ts +++ b/packages/sdk/src/payload.ts @@ -153,67 +153,6 @@ export interface HandshakeResponseContent { identityProof: IdentityProof; } -export function encodeHandshakePayload(payload: HandshakePayload): Uint8Array { - return new TextEncoder().encode(JSON.stringify({ - unifiedPubKeys: Buffer.from(payload.unifiedPubKeys).toString('base64'), - ephemeralPubKey: Buffer.from(payload.ephemeralPubKey).toString('base64'), - plaintextPayload: payload.plaintextPayload - })); -} - -export function decodeHandshakePayload(encoded: Uint8Array): HandshakePayload { - const json = new TextDecoder().decode(encoded); - const parsed = JSON.parse(json); - return { - unifiedPubKeys: Uint8Array.from(Buffer.from(parsed.unifiedPubKeys, 'base64')), - ephemeralPubKey: Uint8Array.from(Buffer.from(parsed.ephemeralPubKey, 'base64')), - plaintextPayload: parsed.plaintextPayload - }; -} - -export function encodeHandshakeResponseContent(content: HandshakeResponseContent): Uint8Array { - return new TextEncoder().encode(JSON.stringify({ - unifiedPubKeys: Buffer.from(content.unifiedPubKeys).toString('base64'), - ephemeralPubKey: Buffer.from(content.ephemeralPubKey).toString('base64'), - ...(content.kemCiphertext && { kemCiphertext: Buffer.from(content.kemCiphertext).toString('base64') }), - note: content.note, - identityProof: content.identityProof, - })); -} - -export function decodeHandshakeResponseContent(encoded: Uint8Array): HandshakeResponseContent { - const json = new TextDecoder().decode(encoded); - const obj = JSON.parse(json); - - if (!obj.identityProof) { - throw new Error("Invalid handshake response: missing identityProof"); - } - - return { - unifiedPubKeys: Uint8Array.from(Buffer.from(obj.unifiedPubKeys, 'base64')), - ephemeralPubKey: Uint8Array.from(Buffer.from(obj.ephemeralPubKey, 'base64')), - ...(obj.kemCiphertext && { kemCiphertext: Uint8Array.from(Buffer.from(obj.kemCiphertext, 'base64')) }), - note: obj.note, - identityProof: obj.identityProof, - }; -} - -/** - * Creates HandshakePayload from separate identity keys - */ -export function createHandshakePayload( - identityPubKey: Uint8Array, - signingPubKey: Uint8Array, - ephemeralPubKey: Uint8Array, - plaintextPayload: string -): HandshakePayload { - return { - unifiedPubKeys: encodeUnifiedPubKeys(identityPubKey, signingPubKey), - ephemeralPubKey, - plaintextPayload - }; -} - export function createHandshakeResponseContent( identityPubKey: Uint8Array, signingPubKey: Uint8Array, @@ -235,24 +174,6 @@ export function createHandshakeResponseContent( }; } -/** - * Extracts individual keys from HandshakePayload - */ -export function extractKeysFromHandshakePayload(payload: HandshakePayload): { - identityPubKey: Uint8Array; - signingPubKey: Uint8Array; - ephemeralPubKey: Uint8Array; -} | null { - const decoded = decodeUnifiedPubKeys(payload.unifiedPubKeys); - if (!decoded) return null; - - return { - identityPubKey: decoded.identityPubKey, - signingPubKey: decoded.signingPubKey, - ephemeralPubKey: payload.ephemeralPubKey - }; -} - /** * Extracts individual keys from HandshakeResponseContent */ diff --git a/packages/sdk/test/crypto.test.ts b/packages/sdk/test/crypto.test.ts index d841d34..9b6b0c5 100644 --- a/packages/sdk/test/crypto.test.ts +++ b/packages/sdk/test/crypto.test.ts @@ -9,14 +9,8 @@ import { computeHybridTagFromInitiator, } from "../src/crypto.js"; import { - HandshakePayload, - encodeHandshakePayload, - decodeHandshakePayload, - encodeHandshakeResponseContent, - decodeHandshakeResponseContent, HandshakeResponseContent, encodeUnifiedPubKeys, - extractKeysFromHandshakePayload, extractKeysFromHandshakeResponse, parseHandshakeKeys, } from "../src/payload.js"; @@ -298,26 +292,6 @@ describe("Encryption/Decryption", () => { }); describe("Key Extraction Functions", () => { - it("should extract keys from handshake payload", () => { - const identityPubKey = new Uint8Array(32).fill(20); - const signingPubKey = new Uint8Array(32).fill(21); - const ephemeralPubKey = new Uint8Array(32).fill(22); - const unifiedPubKeys = encodeUnifiedPubKeys(identityPubKey, signingPubKey); - - const payload: HandshakePayload = { - unifiedPubKeys, - ephemeralPubKey, - plaintextPayload: "test payload", - }; - - const extracted = extractKeysFromHandshakePayload(payload); - - expect(extracted).not.toBeNull(); - expect(extracted!.identityPubKey).toEqual(identityPubKey); - expect(extracted!.signingPubKey).toEqual(signingPubKey); - expect(extracted!.ephemeralPubKey).toEqual(ephemeralPubKey); - }); - it("should extract keys from handshake response content", () => { const identityPubKey = new Uint8Array(32).fill(25); const signingPubKey = new Uint8Array(32).fill(26); @@ -344,19 +318,6 @@ describe("Encryption/Decryption", () => { expect(extracted!.ephemeralPubKey).toEqual(ephemeralPubKey); }); - it("should return null for invalid unified keys in payload", () => { - const invalidUnifiedKeys = new Uint8Array(30).fill(1); // Wrong size - - const payload: HandshakePayload = { - unifiedPubKeys: invalidUnifiedKeys, - ephemeralPubKey: new Uint8Array(32).fill(2), - plaintextPayload: "invalid test", - }; - - const extracted = extractKeysFromHandshakePayload(payload); - expect(extracted).toBeNull(); - }); - it("should return null for invalid unified keys in response content", () => { const invalidUnifiedKeys = new Uint8Array(30).fill(1); // Wrong size @@ -536,56 +497,6 @@ describe("Encryption/Decryption", () => { }); }); - describe("Payload Encoding/Decoding", () => { - it("should encode and decode handshake payload correctly", () => { - const identityPubKey = new Uint8Array(32).fill(1); - const signingPubKey = new Uint8Array(32).fill(9); - const unifiedPubKeys = encodeUnifiedPubKeys(identityPubKey, signingPubKey); - - const payload: HandshakePayload = { - unifiedPubKeys, - ephemeralPubKey: new Uint8Array(32).fill(2), - plaintextPayload: "hello bob", - }; - - const encoded = encodeHandshakePayload(payload); - const decoded = decodeHandshakePayload(encoded); - - expect(decoded.unifiedPubKeys).toEqual(payload.unifiedPubKeys); - expect(decoded.ephemeralPubKey).toEqual(payload.ephemeralPubKey); - expect(decoded.plaintextPayload).toBe("hello bob"); - }); - - it("should encode and decode response content correctly", () => { - const identityPubKey = new Uint8Array(32).fill(3); - const signingPubKey = new Uint8Array(32).fill(10); - const unifiedPubKeys = encodeUnifiedPubKeys(identityPubKey, signingPubKey); - - const ephemeralPubKey = new Uint8Array(32).fill(4); - const note = "here is my response"; - - const identityProof: IdentityProof = { - message: "VerbEth Identity Key Identity v1\nAddress: 0xtest...", - signature: "0x" + "3".repeat(130), - }; - - const content: HandshakeResponseContent = { - unifiedPubKeys, - ephemeralPubKey, - note, - identityProof, - }; - - const encoded = encodeHandshakeResponseContent(content); - const decoded = decodeHandshakeResponseContent(encoded); - - expect(decoded.unifiedPubKeys).toEqual(unifiedPubKeys); - expect(decoded.ephemeralPubKey).toEqual(ephemeralPubKey); - expect(decoded.note).toBe(note); - expect(decoded.identityProof).toEqual(identityProof); - }); - }); - describe("Hybrid HSR Tag (PQ-Secure)", () => { it("responder and initiator compute matching hybrid tags", () => { const viewKeyPair = nacl.box.keyPair(); // Alice's ephemeral diff --git a/packages/sdk/test/simulation.test.ts b/packages/sdk/test/simulation.test.ts index 3b02028..252878e 100644 --- a/packages/sdk/test/simulation.test.ts +++ b/packages/sdk/test/simulation.test.ts @@ -31,9 +31,6 @@ function createSigningKeyPair() { return nacl.sign.keyPair(); } -/** - * Helper to create a pair of initialized sessions (Alice & Bob) - */ function createSessionPair(): { aliceSession: RatchetSession; bobSession: RatchetSession; @@ -657,7 +654,6 @@ describe("App Layer Simulation", () => { it("should handle large message", () => { const { aliceSession, bobSession, bobSigning } = createSessionPair(); - // 1MB message const largeMessage = nacl.randomBytes(1024 * 1024); const enc = ratchetEncrypt(bobSession, largeMessage, bobSigning.secretKey); const dec = ratchetDecrypt(aliceSession, enc.header, enc.ciphertext); @@ -672,15 +668,12 @@ describe("App Layer Simulation", () => { const enc = ratchetEncrypt(bobSession, new TextEncoder().encode("Original"), bobSigning.secretKey); - // First decrypt succeeds const dec1 = ratchetDecrypt(aliceSession, enc.header, enc.ciphertext); expect(dec1).not.toBeNull(); aliceSession = dec1!.session; - // Replay attempt - same header/ciphertext const dec2 = ratchetDecrypt(aliceSession, enc.header, enc.ciphertext); - // Should fail - message key was consumed expect(dec2).toBeNull(); }); diff --git a/packages/sdk/test/verify.test.ts b/packages/sdk/test/verify.test.ts index 4083f52..d6ed7ce 100644 --- a/packages/sdk/test/verify.test.ts +++ b/packages/sdk/test/verify.test.ts @@ -7,14 +7,8 @@ import { decryptAndExtractHandshakeKeys, } from "../src/crypto.js"; import { - HandshakePayload, - encodeHandshakePayload, - decodeHandshakePayload, - encodeHandshakeResponseContent, - decodeHandshakeResponseContent, HandshakeResponseContent, encodeUnifiedPubKeys, - extractKeysFromHandshakePayload, extractKeysFromHandshakeResponse, parseHandshakeKeys, } from "../src/payload.js"; @@ -296,26 +290,6 @@ describe("Encryption/Decryption", () => { }); describe("Key Extraction Functions", () => { - it("should extract keys from handshake payload", () => { - const identityPubKey = new Uint8Array(32).fill(20); - const signingPubKey = new Uint8Array(32).fill(21); - const ephemeralPubKey = new Uint8Array(32).fill(22); - const unifiedPubKeys = encodeUnifiedPubKeys(identityPubKey, signingPubKey); - - const payload: HandshakePayload = { - unifiedPubKeys, - ephemeralPubKey, - plaintextPayload: "test payload", - }; - - const extracted = extractKeysFromHandshakePayload(payload); - - expect(extracted).not.toBeNull(); - expect(extracted!.identityPubKey).toEqual(identityPubKey); - expect(extracted!.signingPubKey).toEqual(signingPubKey); - expect(extracted!.ephemeralPubKey).toEqual(ephemeralPubKey); - }); - it("should extract keys from handshake response content", () => { const identityPubKey = new Uint8Array(32).fill(25); const signingPubKey = new Uint8Array(32).fill(26); @@ -342,19 +316,6 @@ describe("Encryption/Decryption", () => { expect(extracted!.ephemeralPubKey).toEqual(ephemeralPubKey); }); - it("should return null for invalid unified keys in payload", () => { - const invalidUnifiedKeys = new Uint8Array(30).fill(1); // Wrong size - - const payload: HandshakePayload = { - unifiedPubKeys: invalidUnifiedKeys, - ephemeralPubKey: new Uint8Array(32).fill(2), - plaintextPayload: "invalid test", - }; - - const extracted = extractKeysFromHandshakePayload(payload); - expect(extracted).toBeNull(); - }); - it("should return null for invalid unified keys in response content", () => { const invalidUnifiedKeys = new Uint8Array(30).fill(1); // Wrong size @@ -534,53 +495,4 @@ describe("Encryption/Decryption", () => { }); }); - describe("Payload Encoding/Decoding", () => { - it("should encode and decode handshake payload correctly", () => { - const identityPubKey = new Uint8Array(32).fill(1); - const signingPubKey = new Uint8Array(32).fill(9); - const unifiedPubKeys = encodeUnifiedPubKeys(identityPubKey, signingPubKey); - - const payload: HandshakePayload = { - unifiedPubKeys, - ephemeralPubKey: new Uint8Array(32).fill(2), - plaintextPayload: "hello bob", - }; - - const encoded = encodeHandshakePayload(payload); - const decoded = decodeHandshakePayload(encoded); - - expect(decoded.unifiedPubKeys).toEqual(payload.unifiedPubKeys); - expect(decoded.ephemeralPubKey).toEqual(payload.ephemeralPubKey); - expect(decoded.plaintextPayload).toBe("hello bob"); - }); - - it("should encode and decode response content correctly", () => { - const identityPubKey = new Uint8Array(32).fill(3); - const signingPubKey = new Uint8Array(32).fill(10); - const unifiedPubKeys = encodeUnifiedPubKeys(identityPubKey, signingPubKey); - - const ephemeralPubKey = new Uint8Array(32).fill(4); - const note = "here is my response"; - - const identityProof: IdentityProof = { - message: "VerbEth Identity Key Identity v1\nAddress: 0xtest...", - signature: "0x" + "3".repeat(130), - }; - - const content: HandshakeResponseContent = { - unifiedPubKeys, - ephemeralPubKey, - note, - identityProof, - }; - - const encoded = encodeHandshakeResponseContent(content); - const decoded = decodeHandshakeResponseContent(encoded); - - expect(decoded.unifiedPubKeys).toEqual(unifiedPubKeys); - expect(decoded.ephemeralPubKey).toEqual(ephemeralPubKey); - expect(decoded.note).toBe(note); - expect(decoded.identityProof).toEqual(identityProof); - }); - }); }); \ No newline at end of file From f9bdffabc6f8de62f5a82bd3af948f73913ff67e Mon Sep 17 00:00:00 2001 From: Marco Esposito Date: Thu, 29 Jan 2026 16:48:30 +0100 Subject: [PATCH 25/51] first docu commit --- .claude/skills/frontend/SKILL.md | 41 ++ .cluadeignore | 4 +- .gitignore | 4 +- apps/docs/blog/2019-05-28-first-blog-post.md | 12 - apps/docs/blog/2019-05-29-long-blog-post.md | 44 --- apps/docs/blog/2021-08-01-mdx-blog-post.mdx | 24 -- .../docusaurus-plushie-banner.jpeg | Bin 96122 -> 0 bytes apps/docs/blog/2021-08-26-welcome/index.md | 29 -- apps/docs/blog/authors.yml | 25 -- apps/docs/blog/tags.yml | 19 - apps/docs/docs/concepts/_category_.json | 5 + apps/docs/docs/concepts/handshake.md | 171 ++++++++ apps/docs/docs/concepts/how-it-works.md | 101 +++++ apps/docs/docs/concepts/identity.md | 169 ++++++++ apps/docs/docs/concepts/ratchet.md | 237 ++++++++++++ apps/docs/docs/concepts/security.md | 341 ++++++++++++++++ apps/docs/docs/intro.md | 47 --- apps/docs/docs/quick-start.md | 211 ++++++++++ .../docs/docs/tutorial-basics/_category_.json | 8 - .../docs/tutorial-basics/congratulations.md | 23 -- .../tutorial-basics/create-a-blog-post.md | 34 -- .../docs/tutorial-basics/create-a-document.md | 57 --- .../docs/tutorial-basics/create-a-page.md | 43 -- .../docs/tutorial-basics/deploy-your-site.md | 31 -- .../tutorial-basics/markdown-features.mdx | 152 -------- .../docs/docs/tutorial-extras/_category_.json | 7 - .../img/docsVersionDropdown.png | Bin 25427 -> 0 bytes .../tutorial-extras/img/localeDropdown.png | Bin 27841 -> 0 bytes .../tutorial-extras/manage-docs-versions.md | 55 --- .../tutorial-extras/translate-your-site.md | 88 ----- apps/docs/docusaurus.config.ts | 115 ++---- apps/docs/sidebars.ts | 33 +- .../src/components/HomepageFeatures/index.tsx | 71 ---- .../HomepageFeatures/styles.module.css | 11 - apps/docs/src/css/custom.css | 256 ++++++++++-- apps/docs/src/pages/index.module.css | 23 -- apps/docs/src/pages/index.tsx | 42 +- apps/docs/src/pages/markdown-page.md | 7 - .../static/img/docusaurus-social-card.jpg | Bin 55746 -> 0 bytes apps/docs/static/img/docusaurus.png | Bin 5142 -> 0 bytes .../static/img/undraw_docusaurus_mountain.svg | 171 -------- .../static/img/undraw_docusaurus_react.svg | 170 -------- .../static/img/undraw_docusaurus_tree.svg | 40 -- packages/sdk/README.md | 198 +--------- plan-pq-metadata-v2.md | 366 ------------------ tests/handshaking.test.ts | 3 +- 46 files changed, 1568 insertions(+), 1920 deletions(-) create mode 100644 .claude/skills/frontend/SKILL.md delete mode 100644 apps/docs/blog/2019-05-28-first-blog-post.md delete mode 100644 apps/docs/blog/2019-05-29-long-blog-post.md delete mode 100644 apps/docs/blog/2021-08-01-mdx-blog-post.mdx delete mode 100644 apps/docs/blog/2021-08-26-welcome/docusaurus-plushie-banner.jpeg delete mode 100644 apps/docs/blog/2021-08-26-welcome/index.md delete mode 100644 apps/docs/blog/authors.yml delete mode 100644 apps/docs/blog/tags.yml create mode 100644 apps/docs/docs/concepts/_category_.json create mode 100644 apps/docs/docs/concepts/handshake.md create mode 100644 apps/docs/docs/concepts/how-it-works.md create mode 100644 apps/docs/docs/concepts/identity.md create mode 100644 apps/docs/docs/concepts/ratchet.md create mode 100644 apps/docs/docs/concepts/security.md delete mode 100644 apps/docs/docs/intro.md create mode 100644 apps/docs/docs/quick-start.md delete mode 100644 apps/docs/docs/tutorial-basics/_category_.json delete mode 100644 apps/docs/docs/tutorial-basics/congratulations.md delete mode 100644 apps/docs/docs/tutorial-basics/create-a-blog-post.md delete mode 100644 apps/docs/docs/tutorial-basics/create-a-document.md delete mode 100644 apps/docs/docs/tutorial-basics/create-a-page.md delete mode 100644 apps/docs/docs/tutorial-basics/deploy-your-site.md delete mode 100644 apps/docs/docs/tutorial-basics/markdown-features.mdx delete mode 100644 apps/docs/docs/tutorial-extras/_category_.json delete mode 100644 apps/docs/docs/tutorial-extras/img/docsVersionDropdown.png delete mode 100644 apps/docs/docs/tutorial-extras/img/localeDropdown.png delete mode 100644 apps/docs/docs/tutorial-extras/manage-docs-versions.md delete mode 100644 apps/docs/docs/tutorial-extras/translate-your-site.md delete mode 100644 apps/docs/src/components/HomepageFeatures/index.tsx delete mode 100644 apps/docs/src/components/HomepageFeatures/styles.module.css delete mode 100644 apps/docs/src/pages/index.module.css delete mode 100644 apps/docs/src/pages/markdown-page.md delete mode 100644 apps/docs/static/img/docusaurus-social-card.jpg delete mode 100644 apps/docs/static/img/docusaurus.png delete mode 100644 apps/docs/static/img/undraw_docusaurus_mountain.svg delete mode 100644 apps/docs/static/img/undraw_docusaurus_react.svg delete mode 100644 apps/docs/static/img/undraw_docusaurus_tree.svg delete mode 100644 plan-pq-metadata-v2.md diff --git a/.claude/skills/frontend/SKILL.md b/.claude/skills/frontend/SKILL.md new file mode 100644 index 0000000..2d36e82 --- /dev/null +++ b/.claude/skills/frontend/SKILL.md @@ -0,0 +1,41 @@ +--- +name: frontend +description: Create distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics. +--- + +This skill guides creation of distinctive, production-grade frontend interfaces that avoid generic "AI slop" aesthetics. Implement real working code with exceptional attention to aesthetic details and creative choices. + +The user provides frontend requirements: a component, page, application, or interface to build. They may include context about the purpose, audience, or technical constraints. + +## Design Thinking + +Before coding, understand the context and commit to a BOLD aesthetic direction: +- **Purpose**: What problem does this interface solve? Who uses it? +- **Tone**: Pick an extreme: brutally minimal, maximalist chaos, retro-futuristic, organic/natural, luxury/refined, playful/toy-like, editorial/magazine, brutalist/raw, art deco/geometric, soft/pastel, industrial/utilitarian, etc. There are so many flavors to choose from. Use these for inspiration but design one that is true to the aesthetic direction. +- **Constraints**: Technical requirements (framework, performance, accessibility). +- **Differentiation**: What makes this UNFORGETTABLE? What's the one thing someone will remember? + +**CRITICAL**: Choose a clear conceptual direction and execute it with precision. Bold maximalism and refined minimalism both work - the key is intentionality, not intensity. + +Then implement working code (HTML/CSS/JS, React, Vue, etc.) that is: +- Production-grade and functional +- Visually striking and memorable +- Cohesive with a clear aesthetic point-of-view +- Meticulously refined in every detail + +## Frontend Aesthetics Guidelines + +Focus on: +- **Typography**: Choose fonts that are beautiful, unique, and interesting. Avoid generic fonts like Arial and Inter; opt instead for distinctive choices that elevate the frontend's aesthetics; unexpected, characterful font choices. Pair a distinctive display font with a refined body font. +- **Color & Theme**: Commit to a cohesive aesthetic. Use CSS variables for consistency. Dominant colors with sharp accents outperform timid, evenly-distributed palettes. +- **Motion**: Use animations for effects and micro-interactions. Prioritize CSS-only solutions for HTML. Use Motion library for React when available. Focus on high-impact moments: one well-orchestrated page load with staggered reveals (animation-delay) creates more delight than scattered micro-interactions. Use scroll-triggering and hover states that surprise. +- **Spatial Composition**: Unexpected layouts. Asymmetry. Overlap. Diagonal flow. Grid-breaking elements. Generous negative space OR controlled density. +- **Backgrounds & Visual Details**: Create atmosphere and depth rather than defaulting to solid colors. Add contextual effects and textures that match the overall aesthetic. Apply creative forms like gradient meshes, noise textures, geometric patterns, layered transparencies, dramatic shadows, decorative borders, custom cursors, and grain overlays. + +NEVER use generic AI-generated aesthetics like overused font families (Inter, Roboto, Arial, system fonts), cliched color schemes (particularly purple gradients on white backgrounds), predictable layouts and component patterns, and cookie-cutter design that lacks context-specific character. + +Interpret creatively and make unexpected choices that feel genuinely designed for the context. No design should be the same. Vary between light and dark themes, different fonts, different aesthetics. NEVER converge on common choices (Space Grotesk, for example) across generations. + +**IMPORTANT**: Match implementation complexity to the aesthetic vision. Maximalist designs need elaborate code with extensive animations and effects. Minimalist or refined designs need restraint, precision, and careful attention to spacing, typography, and subtle details. Elegance comes from executing the vision well. + +Remember: Claude is capable of extraordinary creative work. Don't hold back, show what can truly be created when thinking outside the box and committing fully to a distinctive vision. \ No newline at end of file diff --git a/.cluadeignore b/.cluadeignore index 4799b82..4100e31 100644 --- a/.cluadeignore +++ b/.cluadeignore @@ -26,4 +26,6 @@ ignition/deployments/chain-84532 *apps/notes/ pnpm-lock.yaml -/tests \ No newline at end of file +/tests + +README.md \ No newline at end of file diff --git a/.gitignore b/.gitignore index 3c2c2ec..957d489 100644 --- a/.gitignore +++ b/.gitignore @@ -25,4 +25,6 @@ ignition/deployments/chain-84532 *apps/notes/ .claudeignore -CLAUDE.md \ No newline at end of file +CLAUDE.md + +old-plan-docs.md \ No newline at end of file diff --git a/apps/docs/blog/2019-05-28-first-blog-post.md b/apps/docs/blog/2019-05-28-first-blog-post.md deleted file mode 100644 index d3032ef..0000000 --- a/apps/docs/blog/2019-05-28-first-blog-post.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -slug: first-blog-post -title: First Blog Post -authors: [slorber, yangshun] -tags: [hola, docusaurus] ---- - -Lorem ipsum dolor sit amet... - - - -...consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet diff --git a/apps/docs/blog/2019-05-29-long-blog-post.md b/apps/docs/blog/2019-05-29-long-blog-post.md deleted file mode 100644 index eb4435d..0000000 --- a/apps/docs/blog/2019-05-29-long-blog-post.md +++ /dev/null @@ -1,44 +0,0 @@ ---- -slug: long-blog-post -title: Long Blog Post -authors: yangshun -tags: [hello, docusaurus] ---- - -This is the summary of a very long blog post, - -Use a `` comment to limit blog post size in the list view. - - - -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet - -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet - -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet - -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet - -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet - -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet - -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet - -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet - -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet - -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet - -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet - -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet - -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet - -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet - -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet - -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet diff --git a/apps/docs/blog/2021-08-01-mdx-blog-post.mdx b/apps/docs/blog/2021-08-01-mdx-blog-post.mdx deleted file mode 100644 index 0c4b4a4..0000000 --- a/apps/docs/blog/2021-08-01-mdx-blog-post.mdx +++ /dev/null @@ -1,24 +0,0 @@ ---- -slug: mdx-blog-post -title: MDX Blog Post -authors: [slorber] -tags: [docusaurus] ---- - -Blog posts support [Docusaurus Markdown features](https://docusaurus.io/docs/markdown-features), such as [MDX](https://mdxjs.com/). - -:::tip - -Use the power of React to create interactive blog posts. - -::: - -{/* truncate */} - -For example, use JSX to create an interactive button: - -```js - -``` - - diff --git a/apps/docs/blog/2021-08-26-welcome/docusaurus-plushie-banner.jpeg b/apps/docs/blog/2021-08-26-welcome/docusaurus-plushie-banner.jpeg deleted file mode 100644 index 11bda0928456b12f8e53d0ba5709212a4058d449..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 96122 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 diff --git a/apps/docs/blog/2021-08-26-welcome/index.md b/apps/docs/blog/2021-08-26-welcome/index.md deleted file mode 100644 index 349ea07..0000000 --- a/apps/docs/blog/2021-08-26-welcome/index.md +++ /dev/null @@ -1,29 +0,0 @@ ---- -slug: welcome -title: Welcome -authors: [slorber, yangshun] -tags: [facebook, hello, docusaurus] ---- - -[Docusaurus blogging features](https://docusaurus.io/docs/blog) are powered by the [blog plugin](https://docusaurus.io/docs/api/plugins/@docusaurus/plugin-content-blog). - -Here are a few tips you might find useful. - - - -Simply add Markdown files (or folders) to the `blog` directory. - -Regular blog authors can be added to `authors.yml`. - -The blog post date can be extracted from filenames, such as: - -- `2019-05-30-welcome.md` -- `2019-05-30-welcome/index.md` - -A blog post folder can be convenient to co-locate blog post images: - -![Docusaurus Plushie](./docusaurus-plushie-banner.jpeg) - -The blog supports tags as well! - -**And if you don't want a blog**: just delete this directory, and use `blog: false` in your Docusaurus config. diff --git a/apps/docs/blog/authors.yml b/apps/docs/blog/authors.yml deleted file mode 100644 index 0fd3987..0000000 --- a/apps/docs/blog/authors.yml +++ /dev/null @@ -1,25 +0,0 @@ -yangshun: - name: Yangshun Tay - title: Ex-Meta Staff Engineer, Co-founder GreatFrontEnd - url: https://linkedin.com/in/yangshun - image_url: https://github.com/yangshun.png - page: true - socials: - x: yangshunz - linkedin: yangshun - github: yangshun - newsletter: https://www.greatfrontend.com - -slorber: - name: Sรฉbastien Lorber - title: Docusaurus maintainer - url: https://sebastienlorber.com - image_url: https://github.com/slorber.png - page: - # customize the url of the author page at /blog/authors/ - permalink: '/all-sebastien-lorber-articles' - socials: - x: sebastienlorber - linkedin: sebastienlorber - github: slorber - newsletter: https://thisweekinreact.com diff --git a/apps/docs/blog/tags.yml b/apps/docs/blog/tags.yml deleted file mode 100644 index bfaa778..0000000 --- a/apps/docs/blog/tags.yml +++ /dev/null @@ -1,19 +0,0 @@ -facebook: - label: Facebook - permalink: /facebook - description: Facebook tag description - -hello: - label: Hello - permalink: /hello - description: Hello tag description - -docusaurus: - label: Docusaurus - permalink: /docusaurus - description: Docusaurus tag description - -hola: - label: Hola - permalink: /hola - description: Hola tag description diff --git a/apps/docs/docs/concepts/_category_.json b/apps/docs/docs/concepts/_category_.json new file mode 100644 index 0000000..74b831d --- /dev/null +++ b/apps/docs/docs/concepts/_category_.json @@ -0,0 +1,5 @@ +{ + "label": "Concepts", + "position": 2, + "collapsed": false +} diff --git a/apps/docs/docs/concepts/handshake.md b/apps/docs/docs/concepts/handshake.md new file mode 100644 index 0000000..07ebee9 --- /dev/null +++ b/apps/docs/docs/concepts/handshake.md @@ -0,0 +1,171 @@ +--- +sidebar_position: 3 +title: Handshake +--- + +# Handshake + +Verbeth uses a hybrid key exchange combining X25519 (classical) and ML-KEM-768 (post-quantum) to establish encrypted channels. + +## Overview + +Unlike Signal's X3DH which uses prekeys stored on a server, Verbeth uses ephemeral-only key exchange: + +| X3DH (Signal) | Verbeth | +|---------------|---------| +| Prekey server required | No server infrastructure | +| Offline initiation | Initiator must wait for response | +| Multiple DH operations | Ephemeral + KEM hybrid | + +The tradeoff: Verbeth requires the responder to come online before the channel is established, but eliminates server trust entirely. + +## Hybrid Key Exchange + +Verbeth combines two key exchange mechanisms: + +### X25519 (Classical) + +- Well-understood elliptic curve Diffie-Hellman +- 128-bit security against classical computers +- Vulnerable to quantum computers running Shor's algorithm + +### ML-KEM-768 (Post-Quantum) + +- NIST-standardized lattice-based KEM (formerly Kyber) +- 192-bit security against quantum computers +- Larger keys (1184 bytes public, 1088 bytes ciphertext) + +### Why Hybrid? + +Defense-in-depth: + +- If X25519 is broken (quantum), ML-KEM protects +- If ML-KEM is broken (cryptanalysis), X25519 protects +- Security holds if *either* primitive remains secure + +This protects against "Harvest Now, Decrypt Later" (HNDL) attacks where adversaries record encrypted traffic today hoping to decrypt with future quantum computers. + +## Protocol Flow + +``` +Alice (Initiator) Bob (Responder) +โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ + +1. Generate ephemeral X25519 keypair (a, A) +2. Generate ML-KEM-768 keypair (kemPk, kemSk) +3. Create identity proof + + โ”€โ”€โ”€โ”€โ”€โ”€โ”€ Handshake Event โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–บ + โ”‚ recipientHash: H(bob_addr) โ”‚ + โ”‚ ephemeralPubKey: A โ”‚ + โ”‚ kemPublicKey: kemPk โ”‚ + โ”‚ identityProof: {...} โ”‚ + โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ + + 4. Generate ephemeral keypair (r, R) + 5. Compute X25519: x_ss = ECDH(r, A) + 6. Encapsulate KEM: (ct, kem_ss) = Encap(kemPk) + 7. Compute hybrid tag: + tag = HKDF(x_ss || kem_ss, "verbeth:hsr-hybrid:v1") + 8. Encrypt response to A + + โ—„โ”€โ”€โ”€โ”€โ”€ HandshakeResponse โ”€โ”€โ”€โ”€โ”€โ”€ + โ”‚ inResponseTo: tag โ”‚ + โ”‚ responderEphemeralR: R โ”‚ + โ”‚ ciphertext: Enc(A, response) โ”‚ + โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ + +9. Decrypt response, extract R, ct +10. Compute X25519: x_ss = ECDH(a, R) +11. Decapsulate KEM: kem_ss = Decap(ct, kemSk) +12. Verify tag matches +13. Derive root key from hybrid secret + + โ•โ•โ•โ•โ•โ•โ• Channel Established โ•โ•โ•โ•โ•โ•โ• +``` + +## Hybrid Tag Computation + +The `inResponseTo` tag links response to handshake using the hybrid secret: + +```typescript +function computeHybridTag( + ecdhSecret: Uint8Array, // X25519 shared secret + kemSecret: Uint8Array // ML-KEM shared secret +): `0x${string}` { + const okm = hkdf(sha256, kemSecret, ecdhSecret, "verbeth:hsr-hybrid:v1", 32); + return keccak256(okm); +} +``` + +Observers cannot link `HandshakeResponse` to its `Handshake` without the shared secrets. See [Security Model](./security.md#handshake-response-unlinkability) for detailed analysis against classical and quantum adversaries. + +## Root Key Derivation + +The initial root key for the Double Ratchet combines both secrets: + +```typescript +function hybridInitialSecret( + x25519Secret: Uint8Array, + kemSecret: Uint8Array +): Uint8Array { + const combined = concat([x25519Secret, kemSecret]); + return hkdf(sha256, combined, zeros(32), "VerbethHybrid", 32); +} +``` + +This root key is post-quantum secure. All subsequent ratchet keys derive from it, propagating PQ security through the entire conversation. + +## On-Chain Events + +### Handshake Event + +```solidity +event Handshake( + bytes32 indexed recipientHash, + address indexed sender, + bytes ephemeralPubKey, // 32 bytes X25519 + bytes kemPublicKey, // 1184 bytes ML-KEM-768 + bytes plaintextPayload // Identity proof + note +); +``` + +### HandshakeResponse Event + +```solidity +event HandshakeResponse( + bytes32 indexed inResponseTo, // Hybrid tag + address indexed responder, + bytes responderEphemeralR, // 32 bytes X25519 + bytes ciphertext // Encrypted response (includes KEM ciphertext) +); +``` + +## Gas Considerations + +| Component | Size | Notes | +|-----------|------|-------| +| X25519 ephemeral | 32 bytes | Minimal | +| ML-KEM public key | 1184 bytes | Dominates handshake cost | +| ML-KEM ciphertext | 1088 bytes | In encrypted response | +| Identity proof | ~500 bytes | Signature + message | + +Handshake initiation costs more due to the KEM public key. Response is encrypted, so KEM ciphertext is hidden in the blob. + +## Executor Abstraction + +Handshake transactions can be sent via: + +- **EOA**: Direct wallet transaction +- **Safe Module**: Session key authorized by Safe + +The identity proof's `ExecutorSafeAddress` field specifies which address will send the transaction, enabling verification regardless of executor type. + +## Security Properties + +| Property | Guarantee | +|----------|-----------| +| **Forward secrecy** | Ephemeral keys provide FS from message 0 | +| **HNDL resistance** | ML-KEM protects root key against quantum | +| **Identity binding** | Proof ties keys to Ethereum address | +| **Quantum unlinkability** | Tag derivation hides handshake-response link | diff --git a/apps/docs/docs/concepts/how-it-works.md b/apps/docs/docs/concepts/how-it-works.md new file mode 100644 index 0000000..b17f599 --- /dev/null +++ b/apps/docs/docs/concepts/how-it-works.md @@ -0,0 +1,101 @@ +--- +sidebar_position: 1 +title: How It Works +--- + +# How It Works + +Verbeth is an end-to-end encrypted messaging protocol that uses Ethereum as its sole transport layer. + +## Blockchain as Transport + +Instead of running servers or relay infrastructure, Verbeth stores encrypted messages directly in Ethereum event logs. The blockchain provides: + +- **Immutability**: Messages cannot be altered or deleted +- **Availability**: No server downtime, no message loss +- **Censorship resistance**: Anyone can read/write to the contract +- **Global ordering**: Block timestamps provide message ordering + +Messages are emitted as events from the LogChain contract. Clients query these events using standard RPC calls. + +## No Servers, No Relays + +Traditional encrypted messaging requires: + +1. A server to store messages until recipients come online +2. Push infrastructure for notifications +3. Trust that the server doesn't log metadata + +Verbeth eliminates all of this. The Ethereum network stores messages indefinitely. Recipients query the blockchain when they come online. The trust model shifts from "trust our servers" to "verify the chain." + +## Identity Model + +Your Ethereum address is your identity. No usernames, no phone numbers, no email verification. + +Verbeth derives cryptographic keys from a single wallet signature: + +``` +Wallet Signature + โ†“ + HKDF Chain + โ†“ +โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” +โ”‚ X25519 (encryption) โ”‚ +โ”‚ Ed25519 (signing) โ”‚ +โ”‚ secp256k1 session key (optional) โ”‚ +โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ +``` + +A binding proof cryptographically ties these derived keys to your Ethereum address. This proof is verified on-chain or via ERC-1271/ERC-6492 for smart accounts. + +## Why Safe Accounts? + +Verbeth works with EOAs but is optimized for Safe accounts: + +- **Session keys**: Derived secp256k1 key can be authorized via Safe module, enabling messaging without repeated wallet signatures +- **Gasless messaging**: Paymasters can sponsor message transactions +- **Multi-sig recovery**: Safe's recovery mechanisms protect your messaging identity +- **ERC-1271 verification**: Smart contract signature verification built into the protocol + +## Protocol Stack + +``` +โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” +โ”‚ Application โ”‚ +โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค +โ”‚ VerbethClient โ”‚ +โ”‚ (sessions, encryption, keys) โ”‚ +โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค +โ”‚ @verbeth/sdk โ”‚ +โ”‚ (ratchet, handshake, identity) โ”‚ +โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค +โ”‚ LogChainV1 Contract โ”‚ +โ”‚ (Handshake, HandshakeResponse, โ”‚ +โ”‚ MessageSent events) โ”‚ +โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค +โ”‚ Ethereum โ”‚ +โ”‚ (event logs, finality) โ”‚ +โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ +``` + +## On-Chain Data Model + +The LogChain contract emits three event types: + +| Event | Purpose | Indexed Fields | +|-------|---------|----------------| +| `Handshake` | Initiate key exchange | `recipientHash`, `sender` | +| `HandshakeResponse` | Accept key exchange | `inResponseTo` | +| `MessageSent` | Encrypted message | `sender`, `topic` | + +Topics are derived from shared secrets. Only participants know which topics belong to their conversation. + +## Message Flow + +1. **Alice initiates**: Emits `Handshake` with her ephemeral keys and identity proof +2. **Bob responds**: Emits `HandshakeResponse` with his keys, encrypted to Alice +3. **Both derive topics**: Shared secrets produce topic hashes for the conversation +4. **Messages flow**: Each party emits `MessageSent` to their outbound topic +5. **Topics evolve**: Double Ratchet advances topics for forward secrecy + +See [Handshake](./handshake.md) and [Ratchet](./ratchet.md) for protocol details. diff --git a/apps/docs/docs/concepts/identity.md b/apps/docs/docs/concepts/identity.md new file mode 100644 index 0000000..1f79169 --- /dev/null +++ b/apps/docs/docs/concepts/identity.md @@ -0,0 +1,169 @@ +--- +sidebar_position: 2 +title: Identity +--- + +# Identity + +Verbeth binds cryptographic messaging keys to Ethereum addresses through deterministic derivation and signed proofs. + +## Key Derivation + +A single wallet signature produces all identity keys: + +``` +โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” +โ”‚ Seed Message: โ”‚ +โ”‚ "VerbEth Identity Seed v1" โ”‚ +โ”‚ "Address: 0x..." โ”‚ +โ”‚ "Context: verbeth" โ”‚ +โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ + โ†“ + Wallet Signature + โ†“ +โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” +โ”‚ IKM = HKDF( โ”‚ +โ”‚ canonicalize(sig) || H(message) || โ”‚ +โ”‚ "verbeth/addr:" || address โ”‚ +โ”‚ ) โ”‚ +โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ + โ†“ + โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” + โ†“ โ†“ โ†“ + X25519 key Ed25519 key secp256k1 + (encryption) (signing) session key +``` + +The derivation is: + +1. **Deterministic**: Same signature always produces same keys +2. **Reproducible**: User can regenerate keys by re-signing +3. **Isolated**: Different addresses produce unrelated keys + +### HKDF Chain + +```typescript +// Intermediate Key Material +const ikm = hkdf(sha256, + concat([canonicalSig, sha256(seedMessage), "verbeth/addr:" + address]), + "verbeth/seed-sig-v1", + "verbeth/ikm", + 32 +); + +// Derive individual keys +const x25519_sk = hkdf(sha256, ikm, "", "verbeth-x25519-v1", 32); +const ed25519_seed = hkdf(sha256, ikm, "", "verbeth-ed25519-v1", 32); +const session_sk = hkdf(sha256, ikm, "", "verbeth-session-secp256k1-v1", 32); +``` + +## Binding Proofs + +A binding proof cryptographically ties derived keys to an Ethereum address: + +``` +VerbEth Key Binding v1 +Address: 0xabc... +PkEd25519: 0x123... +PkX25519: 0x456... +ExecutorSafeAddress: 0xdef... +ChainId: 8453 +``` + +This message is signed by the wallet, creating proof that: + +1. The signer controls the Ethereum address +2. The signer authorizes these specific public keys +3. The proof is bound to a specific chain and executor + +### Message Structure + +| Field | Purpose | +|-------|---------| +| `Address` | Signer's Ethereum address | +| `PkEd25519` | Ed25519 signing public key | +| `PkX25519` | X25519 encryption public key | +| `ExecutorSafeAddress` | Safe address that will send transactions | +| `ChainId` | Chain ID for replay protection | + +## Verification Standards + +Verbeth supports three verification methods: + +### EOA (Externally Owned Account) + +Standard `ecrecover` verifies the signature against the address. + +### ERC-1271 (Deployed Smart Accounts) + +For deployed Safe accounts or other smart wallets: + +```solidity +function isValidSignature(bytes32 hash, bytes signature) + external view returns (bytes4); +``` + +The contract returns `0x1626ba7e` if the signature is valid. + +### ERC-6492 (Counterfactual Accounts) + +For Safe accounts that haven't been deployed yet: + +``` +signature = abi.encodePacked( + factory, + factoryCalldata, + originalSignature +) +``` + +Verification simulates deployment, then calls ERC-1271. + +## Safe Account Integration + +When using a Safe account, the binding proof includes `ExecutorSafeAddress`: + +```typescript +const { keyPair, sessionPrivateKey, sessionAddress } = + await deriveIdentityKeys(signer, address); + +const identityProof = await createBindingProof( + signer, + address, + derivedKeys, + safeAddress // ExecutorSafeAddress field +); +``` + +The derived `sessionPrivateKey` creates an Ethereum wallet that can be authorized by the Safe's session module. This enables: + +- Sending messages without repeated wallet signatures +- Gasless transactions via paymaster +- Programmatic messaging from backend services + +## Verification Flow + +When receiving a handshake or message: + +``` +1. Parse binding message +2. Extract claimed address and public keys +3. Verify signature: + - EOA: ecrecover + - Smart Account: ERC-1271 + - Counterfactual: ERC-6492 +4. Compare extracted keys against message/handshake keys +5. Validate ExecutorSafeAddress matches msg.sender +6. Check ChainId matches current chain +``` + +If any step fails, the message is rejected. + +## Security Properties + +| Property | Guarantee | +|----------|-----------| +| **Key binding** | Keys are provably controlled by address owner | +| **Replay protection** | ChainId prevents cross-chain replay | +| **Executor binding** | ExecutorSafeAddress prevents unauthorized senders | +| **Determinism** | Same inputs produce same keys (recovery) | diff --git a/apps/docs/docs/concepts/ratchet.md b/apps/docs/docs/concepts/ratchet.md new file mode 100644 index 0000000..17ae068 --- /dev/null +++ b/apps/docs/docs/concepts/ratchet.md @@ -0,0 +1,237 @@ +--- +sidebar_position: 4 +title: Double Ratchet +--- + +# Double Ratchet + +Verbeth uses the Double Ratchet algorithm for post-handshake encryption, providing forward secrecy and post-compromise security. + +## Overview + +The Double Ratchet combines two ratchets: + +1. **DH Ratchet**: New Diffie-Hellman exchange on each round-trip +2. **Symmetric Ratchet**: Key derivation for each message + +``` + Root Key + โ”‚ + โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” + โ”‚ โ”‚ โ”‚ + โ–ผ โ–ผ โ–ผ + DH Step 1 DH Step 2 DH Step 3 + โ”‚ โ”‚ โ”‚ + โ–ผ โ–ผ โ–ผ +โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” +โ”‚Chain 1โ”‚ โ”‚Chain 2โ”‚ โ”‚Chain 3โ”‚ +โ”‚ Key 0 โ”‚ โ”‚ Key 0 โ”‚ โ”‚ Key 0 โ”‚ +โ”‚ Key 1 โ”‚ โ”‚ Key 1 โ”‚ โ”‚ Key 1 โ”‚ +โ”‚ Key 2 โ”‚ โ”‚ ... โ”‚ โ”‚ ... โ”‚ +โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ +``` + +## Key Derivation Functions + +### Root Key Derivation + +When a DH ratchet step occurs: + +```typescript +function kdfRootKey(rootKey: Uint8Array, dhOutput: Uint8Array) { + const output = hkdf(sha256, dhOutput, rootKey, "VerbethRatchet", 64); + return { + rootKey: output.slice(0, 32), // New root key + chainKey: output.slice(32, 64) // New chain key + }; +} +``` + +### Chain Key Derivation + +For each message in a chain: + +```typescript +function kdfChainKey(chainKey: Uint8Array) { + return { + messageKey: hmac(sha256, chainKey, [0x01]), // Encrypt this message + chainKey: hmac(sha256, chainKey, [0x02]) // Next chain key + }; +} +``` + +## Session State + +The `RatchetSession` contains: + +```typescript +interface RatchetSession { + // Identity + conversationId: string; // keccak256(sort([topicOut, topicIn])) + myAddress: string; + contactAddress: string; + + // Root Ratchet + rootKey: Uint8Array; // 32 bytes, PQ-secure from handshake + + // DH Ratchet Keys + dhMySecretKey: Uint8Array; // My current DH secret + dhMyPublicKey: Uint8Array; // My current DH public (in message headers) + dhTheirPublicKey: Uint8Array; // Their last DH public + + // Sending Chain + sendingChainKey: Uint8Array | null; + sendingMsgNumber: number; // Ns + + // Receiving Chain + receivingChainKey: Uint8Array | null; + receivingMsgNumber: number; // Nr + + // Skip Handling + previousChainLength: number; // PN header field + skippedKeys: SkippedKey[]; // For out-of-order messages + + // Topic Ratcheting + currentTopicOutbound: `0x${string}`; + currentTopicInbound: `0x${string}`; + topicEpoch: number; +} +``` + +**Critical**: Session state must be persisted after every encrypt/decrypt operation. Failure to persist creates security vulnerabilities and message loss. + +## Topic Ratcheting + +Topics evolve with the DH ratchet to maintain forward secrecy of conversation metadata: + +```typescript +function deriveTopic( + rootKey: Uint8Array, // PQ-secure salt + dhOutput: Uint8Array, // DH shared secret + direction: 'outbound' | 'inbound' +): `0x${string}` { + const info = `verbeth:topic-${direction}:v3`; + const okm = hkdf(sha256, dhOutput, rootKey, info, 32); + return keccak256(okm); +} +``` + +The root key as HKDF salt provides quantum-resistant topic unlinkability. Even if X25519 is broken, topics from different epochs cannot be linked without the root key. + +### Topic Evolution + +``` +Epoch 0 (Handshake) Epoch 1 (Alice ratchets) Epoch 2 (Bob ratchets) +โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ +topicOutA = H(saltโ‚€) topicOutA = H(saltโ‚) topicOutA = H(saltโ‚‚) +topicInA = H(saltโ‚€) topicInA = H(saltโ‚) topicInA = H(saltโ‚‚) +``` + +### Grace Period + +When topics change, the previous inbound topic remains valid for 5 minutes (`TOPIC_TRANSITION_WINDOW_MS`). This handles: + +- Messages in flight during ratchet +- Blockchain reorgs +- Out-of-order delivery + +```typescript +interface RatchetSession { + previousTopicInbound?: `0x${string}`; + previousTopicExpiry?: number; // Date.now() + 5 minutes +} +``` + +## Out-of-Order Messages + +Blockchain delivery doesn't guarantee order. The ratchet handles this via skip keys: + +### Skip Key Storage + +When message N arrives but we expected message M (where M < N): + +```typescript +// Store keys for messages M through N-1 +for (let i = M; i < N; i++) { + const { chainKey, messageKey } = kdfChainKey(currentChainKey); + skippedKeys.push({ + dhPubKeyHex: hexlify(theirDHPub), + msgNumber: i, + messageKey: messageKey, + createdAt: Date.now() + }); + currentChainKey = chainKey; +} +``` + +### Bounds and Pruning + +| Constant | Value | Purpose | +|----------|-------|---------| +| `MAX_SKIP_PER_MESSAGE` | 100,000 | Reject messages requiring excessive skips | +| `MAX_STORED_SKIPPED_KEYS` | 1,000 | Prune oldest when exceeded | +| `MAX_SKIPPED_KEYS_AGE_MS` | 24 hours | TTL for skip keys | + +## Burned Slots + +**Rollback is forbidden**. If you decrypt a message, the session state advances. Re-using old state creates: + +- Duplicate message keys (breaks confidentiality) +- Orphan skip keys for the receiver + +Example of what NOT to do: + +```typescript +// WRONG: Not persisting state +const result = ratchetDecrypt(session, header, ciphertext); +// forgot to save result.session +// next decrypt uses old session = security failure +``` + +## DoS Protection + +Before ratchet operations, signatures are verified: + +```typescript +// O(1) rejection of invalid messages +const headerBytes = encodeHeader(header); +const dataToVerify = concat([headerBytes, ciphertext]); +const valid = nacl.sign.detached.verify(dataToVerify, signature, signingPubKey); + +if (!valid) { + return null; // Reject without touching ratchet state +} +``` + +Ed25519 verification is cheap. This prevents attackers from forcing expensive ratchet computations with invalid messages. + +## Message Format + +Binary payload structure: + +``` +โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” +โ”‚ Version โ”‚ Signature โ”‚ Header โ”‚ Ciphertext โ”‚ +โ”‚ 1 byte โ”‚ 64 bytes โ”‚ 40 bytes โ”‚ variable โ”‚ +โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ + +Header (40 bytes): +โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” +โ”‚ DH PubKey โ”‚ PN โ”‚ N โ”‚ +โ”‚ 32 bytes โ”‚ 4 bytes โ”‚ 4 bytes โ”‚ +โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ +``` + +- **DH PubKey**: Sender's current ratchet public key +- **PN**: Previous chain length (for skip key calculation) +- **N**: Message number in current chain + +## Security Properties + +| Property | Mechanism | +|----------|-----------| +| **Forward secrecy** | DH ratchet step deletes old keys | +| **Post-compromise security** | New DH exchange after compromise heals | +| **Out-of-order tolerance** | Skip keys with bounded storage | +| **DoS resistance** | Ed25519 verification before ratchet ops | +| **Topic unlinkability** | Root key salt for topic derivation | diff --git a/apps/docs/docs/concepts/security.md b/apps/docs/docs/concepts/security.md new file mode 100644 index 0000000..c42a797 --- /dev/null +++ b/apps/docs/docs/concepts/security.md @@ -0,0 +1,341 @@ +--- +sidebar_position: 5 +title: Security Model +--- + +# Security Model + +This document describes Verbeth's threat model, security guarantees, and tradeoffs compared to traditional encrypted messaging. + +## Threat Classes + +Verbeth considers three distinct adversary types: + +### 1. Passive Network Observer + +**Who**: Block explorers, chain indexers, MEV searchers + +**Capabilities**: +- Read all on-chain data (events, calldata) +- Correlate transactions by address +- Build transaction graphs + +**Cannot**: +- Read message contents (encrypted) +- Link topics to recipients (hash-based) +- Determine conversation participants from topics alone + +### 2. Active RPC Adversary + +**Who**: Your RPC provider (Infura, Alchemy, self-hosted) + +**Capabilities**: +- See all queries you make +- Observe which topics you subscribe to +- Correlate query timing with message receipt + +**Cannot**: +- Decrypt message contents +- Forge messages (no private keys) + +**Critical**: RPC providers can perform correlation attacks linking senders to receivers by observing query patterns. See [Metadata Privacy](#metadata-privacy). + +### 3. State Compromise Adversary + +**Who**: Malware, device theft, insider threat + +**Capabilities**: +- Read session state (root keys, chain keys) +- Decrypt future messages until ratchet step +- Potentially impersonate user + +**Mitigated by**: +- Forward secrecy (past messages protected) +- Post-compromise security (future messages protected after DH ratchet) + +## Authentication & Non-Repudiation + +### msg.sender as Authentication + +Ethereum's transaction model provides protocol-level sender authentication: + +- `msg.sender` is the transaction signer +- Cannot be forged without private key +- Verified by every node in the network + +### Binding Proofs + +Identity proofs add application-level authentication: + +- Signed message ties keys to Ethereum address +- Verified by recipient before decryption +- Supports EOA, ERC-1271, and ERC-6492 + +### Non-Repudiation + +**Verbeth provides non-repudiation by design.** This is a fundamental difference from Signal: + +| | Verbeth | Signal | +|---|---------|--------| +| **Message attribution** | Permanent, on-chain | Deniable | +| **Third-party verification** | Anyone can verify sender | Cannot prove authorship | +| **Legal admissibility** | Strong (blockchain evidence) | Weak (cryptographic deniability) | + +**On-chain transactions are permanent, attributable records.** A message sender cannot later deny sending a message. The blockchain provides: + +- Immutable record of who sent what +- Timestamp from block inclusion +- Cryptographic proof via transaction signature + +**Signal's deniability** works because messages are authenticated with ephemeral keys that both parties know. Either party could have forged the message. Verbeth explicitly trades deniability for trustless, verifiable communication. + +**Use cases where non-repudiation matters**: +- Business communications requiring audit trails +- Legal agreements and contracts +- Compliance-regulated messaging + +## Forward Secrecy + +**Definition**: Compromise of current keys does not reveal past messages. + +### Mechanism + +1. Each DH ratchet step derives new keys +2. Old keys are deleted after derivation +3. Even with current state, past messages cannot be decrypted + +### Unconditional from Message 0 + +Unlike some protocols that require multiple messages before FS kicks in, Verbeth provides forward secrecy immediately: + +- Handshake uses ephemeral keys only +- No long-term keys in key exchange +- First message is already protected + +### Key Deletion Importance + +Forward secrecy only works if old keys are actually deleted: + +```typescript +// SDK wipes keys after use +try { + messageKey.fill(0); + chainKey.fill(0); +} catch {} +``` + +Application developers must ensure session state isn't backed up in ways that preserve old keys. + +## Post-Compromise Security + +**Definition**: Security recovery after state compromise. + +### Against Classical Adversary + +**Full PCS**: After a DH ratchet step, security is restored. + +``` +Compromise here + โ†“ +[msg 1] [msg 2] [msg 3] [DH ratchet] [msg 4] [msg 5] + โœ— โœ— โœ— โ”‚ โœ“ โœ“ + โ””โ”€โ”€ Security restored +``` + +The attacker can read messages until the next DH exchange. After that, they're locked out. + +### Against Quantum Adversary + +Two scenarios to consider: + +**Passive quantum (HNDL)**: +- Adversary records ciphertext now, decrypts later with quantum computer +- **Fully protected**: Root key is PQ-secure from ML-KEM +- All messages inherit this protection + +**Active quantum + state compromise**: +- Adversary has quantum computer AND compromises device state +- **PCS degraded**: Subsequent DH ratchets use X25519 (quantum-vulnerable) +- Attacker can compute future DH shared secrets + +This is an honest limitation. Full PQ PCS would require hybrid KEM ratcheting (future work). + +## Post-Quantum Security + +### HNDL Resistance + +"Harvest Now, Decrypt Later" attacks are mitigated: + +1. **Handshake**: ML-KEM-768 protects initial key exchange +2. **Root key derivation**: Hybrid secret (X25519 + ML-KEM) +3. **Key propagation**: All chain keys derive from PQ-secure root +4. **Result**: All messages protected, not just handshake + +### Why Hybrid (X25519 + ML-KEM) + +Defense-in-depth principle: + +| Threat | X25519 | ML-KEM | Hybrid | +|--------|--------|--------|--------| +| Classical attack | Secure | Secure | Secure | +| Quantum attack (Shor) | Broken | Secure | Secure | +| Cryptanalytic breakthrough | Secure | ? | Secure | + +ML-KEM is NIST-standardized but newer. X25519 is battle-tested. Combining them ensures security if either remains secure. + +### Limitations + +Honest assessment of what's NOT quantum-secure: + +- **DH ratchet steps**: Use X25519 only (practical tradeoff) +- **Active quantum + state compromise**: No full PCS +- **Topic derivation**: Uses DH output (though salted with PQ-secure root) + +## Metadata Privacy + +### On-Chain Visibility + +Observers see: + +| Visible | Hidden | +|---------|--------| +| Sender addresses | Recipient identity | +| Topic hashes | Topic-to-recipient mapping | +| Ciphertext blobs | Message content | +| Transaction timing | Conversation relationships | +| Gas costs | | + +### Handshake-Response Unlinkability + +The `Handshake` and `HandshakeResponse` events have no plaintext link. The only connection is the `inResponseTo` tag, which requires shared secrets to compute: + +``` +tag = keccak256(HKDF(kemSecret, ecdhSecret, "verbeth:hsr-hybrid:v1")) +``` + +**Against passive classical adversary**: +- Observer sees Alice's ephemeral public key in `Handshake` +- Observer sees `inResponseTo` tag in `HandshakeResponse` +- Cannot compute tag without Bob's ephemeral secret (never published) + +**Against passive quantum adversary**: +- Quantum computer could solve ECDH from public keys (Shor's algorithm) +- But tag derivation also requires `kemSecret` from ML-KEM +- ML-KEM ciphertext is inside the encrypted response payload +- Cannot decrypt payload without Alice's ephemeral secret +- Result: still cannot link handshake to response + +### Handshake-to-Message Unlinkability + +After handshake, messages use topics derived from the hybrid root key: + +``` +rootKey = HKDF(x25519Secret || kemSecret, "VerbethHybrid") +topic = keccak256(HKDF(dhOutput, rootKey, "verbeth:topic")) +``` + +**Against passive classical adversary**: +- Topics are hashes with no reversible link to handshake public keys +- Cannot determine which `Handshake` led to which `MessageSent` topic + +**Against passive quantum adversary**: +- Even with ECDH broken, `rootKey` includes `kemSecret` +- Topics inherit PQ security from root key salt +- Cannot link handshake ephemeral keys to message topics + +### The RPC Problem + +**Critical trust boundary**: Your RPC provider sees your queries. + +When you query for messages: +```typescript +// RPC sees this query +contract.queryFilter("MessageSent", { topic: myTopic }) +``` + +The RPC can: +1. Note which topics you query +2. Correlate with message emission timing +3. Link sender address to querying address + +**Mitigations**: +- Self-hosted node (eliminates RPC trust) +- Tor/VPN (hides query origin) +- Decoy queries (noise injection) +- Query aggregation services (future) + +## Replay & DoS Protection + +### Ethereum's Gas Model + +Spam resistance through economics: +- Every message costs gas +- Attack cost scales linearly +- No free amplification attacks + +### Ed25519 Signature Verification + +Before any ratchet state changes: + +```typescript +// O(1) verification, O(n) ratchet ops +if (!nacl.sign.detached.verify(data, sig, pubKey)) { + return null; // Reject immediately +} +``` + +Invalid signatures are rejected before expensive key derivation. + +### Nonce Tracking (Optional) + +For applications requiring strict deduplication: +- Track message hashes or (topic, n) pairs +- Reject duplicates at application layer +- SDK provides hooks for custom logic + +## Comparison with Signal Protocol + +| Property | Verbeth | Signal | +|----------|---------|--------| +| **Transport** | Blockchain (public, immutable) | Server relay (private, ephemeral) | +| **Authentication** | `msg.sender` + binding proof | X3DH with identity keys | +| **Non-repudiation** | Yes (on-chain attribution) | No (deniable) | +| **Prekey infrastructure** | None | Required (server-hosted) | +| **Forward secrecy** | From message 0 | From message 0 | +| **PCS (classical)** | Full | Full | +| **PCS (quantum)** | Degraded (active + compromise) | Degraded (same) | +| **HNDL resistance** | Yes (ML-KEM-768 hybrid) | Yes (PQXDH) | +| **Offline delivery** | Yes (blockchain stores forever) | Yes (server queues) | +| **Metadata privacy** | RPC trust required | Server trust required | + +### Verbeth Advantages + +- **No server infrastructure**: Eliminates server trust entirely +- **Trustless delivery**: Blockchain finality guarantees delivery +- **Smart account integration**: Session keys, gasless messaging +- **Audit trail**: Compliance-friendly immutable records +- **Censorship resistance**: Permissionless access + +### Verbeth Tradeoffs + +- **No deniability**: On-chain = permanent attribution +- **Higher latency**: Block times (2s L2, 12s L1) +- **Gas costs**: Each message costs money +- **RPC metadata**: Query patterns visible to provider +- **Larger handshakes**: ML-KEM public keys are 1184 bytes + +## Summary + +Verbeth provides strong security guarantees with explicit tradeoffs: + +| Guarantee | Status | +|-----------|--------| +| End-to-end encryption | Yes | +| Forward secrecy | Yes, from message 0 | +| Post-compromise security (classical) | Yes | +| HNDL resistance | Yes | +| Sender authentication | Yes, protocol-level | +| Recipient privacy | Yes, from chain observers | +| Deniability | No (explicit design choice) | +| Metadata privacy from RPC | No (requires self-hosting) | +| Full PQ PCS | No (active quantum + compromise) | diff --git a/apps/docs/docs/intro.md b/apps/docs/docs/intro.md deleted file mode 100644 index 88f9571..0000000 --- a/apps/docs/docs/intro.md +++ /dev/null @@ -1,47 +0,0 @@ ---- -sidebar_position: 1 ---- - -# Tutorial Intro - -Let's discover **Docusaurus in less than 5 minutes**. - -## Getting Started - -Get started by **creating a new site**. - -Or **try Docusaurus immediately** with **[docusaurus.new](https://docusaurus.new)**. - -### What you'll need - -- [Node.js](https://nodejs.org/en/download/) version 20.0 or above: - - When installing Node.js, you are recommended to check all checkboxes related to dependencies. - -## Generate a new site - -Generate a new Docusaurus site using the **classic template**. - -The classic template will automatically be added to your project after you run the command: - -```bash -npm init docusaurus@latest my-website classic -``` - -You can type this command into Command Prompt, Powershell, Terminal, or any other integrated terminal of your code editor. - -The command also installs all necessary dependencies you need to run Docusaurus. - -## Start your site - -Run the development server: - -```bash -cd my-website -npm run start -``` - -The `cd` command changes the directory you're working with. In order to work with your newly created Docusaurus site, you'll need to navigate the terminal there. - -The `npm run start` command builds your website locally and serves it through a development server, ready for you to view at http://localhost:3000/. - -Open `docs/intro.md` (this page) and edit some lines: the site **reloads automatically** and displays your changes. diff --git a/apps/docs/docs/quick-start.md b/apps/docs/docs/quick-start.md new file mode 100644 index 0000000..c50939a --- /dev/null +++ b/apps/docs/docs/quick-start.md @@ -0,0 +1,211 @@ +--- +sidebar_position: 1 +slug: /quick-start +title: Quick Start +--- + +# Quick Start + +Get end-to-end encrypted messaging working in your dApp. + +## Install + +```bash +npm install @verbeth/sdk ethers +``` + +## Setup Client + +```typescript +import { + createVerbethClient, + deriveIdentityKeyPairWithProof, + ExecutorFactory +} from '@verbeth/sdk'; +import { ethers } from 'ethers'; + +// Contract address (Base mainnet) +const LOGCHAIN_ADDRESS = '0x62720f39d5Ec6501508bDe4D152c1E13Fd2F6707'; + +// 1. Connect wallet +const provider = new ethers.BrowserProvider(window.ethereum); +const signer = await provider.getSigner(); +const address = await signer.getAddress(); + +// 2. Derive identity keys (requires 2 wallet signatures) +const { identityKeyPair, identityProof } = await deriveIdentityKeyPairWithProof( + signer, + address +); + +// 3. Create executor for contract interactions +const contract = new ethers.Contract(LOGCHAIN_ADDRESS, LOGCHAIN_ABI, signer); +const executor = ExecutorFactory.createEOA(contract); + +// 4. Create client +const client = createVerbethClient({ + address, + signer, + identityKeyPair, + identityProof, + executor, +}); +``` + +## Send a Handshake + +Start a conversation by sending a handshake to another address. +The returned secrets must be stored until the recipient responds. + +```typescript +const recipientAddress = '0x...'; + +const { tx, ephemeralKeyPair, kemKeyPair } = await client.sendHandshake( + recipientAddress, + 'Hello from Verbeth!' +); +await tx.wait(); +``` + +## Accept a Handshake + +When you receive a handshake, accept it to establish the encrypted channel. You can implement your own storage to persist the session. + + +```typescript +// Parse incoming handshake event from blockchain logs +const initiatorEphemeralPubKey = handshakeEvent.ephemeralPubKey; + +const { + tx, + topicOutbound, + topicInbound, + responderEphemeralSecret, + responderEphemeralPublic, + salt, + kemSharedSecret, +} = await client.acceptHandshake(initiatorEphemeralPubKey, 'Hey!'); + +await tx.wait(); + +const session = client.createResponderSession({ + contactAddress: handshakeEvent.sender, + responderEphemeralSecret, + responderEphemeralPublic, + initiatorEphemeralPubKey, + salt, + kemSharedSecret, +}); + +await sessionStore.save(session); +``` + +## Create Session from Response + +When the recipient responds to your handshake, create your session using the previously stored secrets. + +```typescript +// hsrEvent is the HandshakeResponse event from the blockchain +const session = client.createInitiatorSessionFromHsr({ + contactAddress: recipientAddress, + myEphemeralSecret: storedEphemeralSecret, + myKemSecret: storedKemSecret, + hsrEvent: { + responderEphemeralPubKey: hsrEvent.responderEphemeralPubKey, + inResponseToTag: hsrEvent.inResponseTo, + kemCiphertext: hsrEvent.kemCiphertext, + }, +}); + +await sessionStore.save(session); +``` + +## Send Messages + +Once you have a session, configure the storage and send encrypted messages. + +```typescript +client.setSessionStore(sessionStore); +client.setPendingStore(pendingStore); + +const result = await client.sendMessage( + session.conversationId, + 'This message is end-to-end encrypted!' +); + +console.log('Sent:', result.txHash); +``` + +## Decrypt Messages + +Decrypt incoming messages from the blockchain. + +```typescript +const decrypted = await client.decryptMessage( + messageEvent.topic, + messageEvent.payload, + senderSigningKey, + false // isOwnMessage +); + +if (decrypted) { + console.log('Received:', decrypted.plaintext); +} +``` + +## Full Example + +```typescript +import { + createVerbethClient, + deriveIdentityKeyPairWithProof, + ExecutorFactory +} from '@verbeth/sdk'; +import { ethers } from 'ethers'; + +const LOGCHAIN_ADDRESS = '0x62720f39d5Ec6501508bDe4D152c1E13Fd2F6707'; + +async function initVerbeth() { + const provider = new ethers.BrowserProvider(window.ethereum); + const signer = await provider.getSigner(); + const address = await signer.getAddress(); + + const { identityKeyPair, identityProof } = await deriveIdentityKeyPairWithProof( + signer, + address + ); + + const contract = new ethers.Contract(LOGCHAIN_ADDRESS, LOGCHAIN_ABI, signer); + const executor = ExecutorFactory.createEOA(contract); + + const client = createVerbethClient({ + address, + signer, + identityKeyPair, + identityProof, + executor, + }); + + return { client, identityKeyPair }; +} + +async function startConversation(client, recipientAddress: string) { + const { tx, ephemeralKeyPair, kemKeyPair } = await client.sendHandshake( + recipientAddress, + 'Starting secure conversation' + ); + + await tx.wait(); + + return { + ephemeralSecret: ephemeralKeyPair.secretKey, + kemSecret: kemKeyPair.secretKey, + }; +} +``` + +## Next Steps + +- **Identity binding**: Keys are cryptographically bound to your Ethereum address via signed messages +- **Handshake flow**: X3DH-like protocol with ML-KEM-768 for post-quantum security +- **Double Ratchet**: Forward secrecy with automatic topic evolution diff --git a/apps/docs/docs/tutorial-basics/_category_.json b/apps/docs/docs/tutorial-basics/_category_.json deleted file mode 100644 index 2e6db55..0000000 --- a/apps/docs/docs/tutorial-basics/_category_.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "label": "Tutorial - Basics", - "position": 2, - "link": { - "type": "generated-index", - "description": "5 minutes to learn the most important Docusaurus concepts." - } -} diff --git a/apps/docs/docs/tutorial-basics/congratulations.md b/apps/docs/docs/tutorial-basics/congratulations.md deleted file mode 100644 index 04771a0..0000000 --- a/apps/docs/docs/tutorial-basics/congratulations.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -sidebar_position: 6 ---- - -# Congratulations! - -You have just learned the **basics of Docusaurus** and made some changes to the **initial template**. - -Docusaurus has **much more to offer**! - -Have **5 more minutes**? Take a look at **[versioning](../tutorial-extras/manage-docs-versions.md)** and **[i18n](../tutorial-extras/translate-your-site.md)**. - -Anything **unclear** or **buggy** in this tutorial? [Please report it!](https://github.com/facebook/docusaurus/discussions/4610) - -## What's next? - -- Read the [official documentation](https://docusaurus.io/) -- Modify your site configuration with [`docusaurus.config.js`](https://docusaurus.io/docs/api/docusaurus-config) -- Add navbar and footer items with [`themeConfig`](https://docusaurus.io/docs/api/themes/configuration) -- Add a custom [Design and Layout](https://docusaurus.io/docs/styling-layout) -- Add a [search bar](https://docusaurus.io/docs/search) -- Find inspirations in the [Docusaurus showcase](https://docusaurus.io/showcase) -- Get involved in the [Docusaurus Community](https://docusaurus.io/community/support) diff --git a/apps/docs/docs/tutorial-basics/create-a-blog-post.md b/apps/docs/docs/tutorial-basics/create-a-blog-post.md deleted file mode 100644 index 550ae17..0000000 --- a/apps/docs/docs/tutorial-basics/create-a-blog-post.md +++ /dev/null @@ -1,34 +0,0 @@ ---- -sidebar_position: 3 ---- - -# Create a Blog Post - -Docusaurus creates a **page for each blog post**, but also a **blog index page**, a **tag system**, an **RSS** feed... - -## Create your first Post - -Create a file at `blog/2021-02-28-greetings.md`: - -```md title="blog/2021-02-28-greetings.md" ---- -slug: greetings -title: Greetings! -authors: - - name: Joel Marcey - title: Co-creator of Docusaurus 1 - url: https://github.com/JoelMarcey - image_url: https://github.com/JoelMarcey.png - - name: Sรฉbastien Lorber - title: Docusaurus maintainer - url: https://sebastienlorber.com - image_url: https://github.com/slorber.png -tags: [greetings] ---- - -Congratulations, you have made your first post! - -Feel free to play around and edit this post as much as you like. -``` - -A new blog post is now available at [http://localhost:3000/blog/greetings](http://localhost:3000/blog/greetings). diff --git a/apps/docs/docs/tutorial-basics/create-a-document.md b/apps/docs/docs/tutorial-basics/create-a-document.md deleted file mode 100644 index c22fe29..0000000 --- a/apps/docs/docs/tutorial-basics/create-a-document.md +++ /dev/null @@ -1,57 +0,0 @@ ---- -sidebar_position: 2 ---- - -# Create a Document - -Documents are **groups of pages** connected through: - -- a **sidebar** -- **previous/next navigation** -- **versioning** - -## Create your first Doc - -Create a Markdown file at `docs/hello.md`: - -```md title="docs/hello.md" -# Hello - -This is my **first Docusaurus document**! -``` - -A new document is now available at [http://localhost:3000/docs/hello](http://localhost:3000/docs/hello). - -## Configure the Sidebar - -Docusaurus automatically **creates a sidebar** from the `docs` folder. - -Add metadata to customize the sidebar label and position: - -```md title="docs/hello.md" {1-4} ---- -sidebar_label: 'Hi!' -sidebar_position: 3 ---- - -# Hello - -This is my **first Docusaurus document**! -``` - -It is also possible to create your sidebar explicitly in `sidebars.js`: - -```js title="sidebars.js" -export default { - tutorialSidebar: [ - 'intro', - // highlight-next-line - 'hello', - { - type: 'category', - label: 'Tutorial', - items: ['tutorial-basics/create-a-document'], - }, - ], -}; -``` diff --git a/apps/docs/docs/tutorial-basics/create-a-page.md b/apps/docs/docs/tutorial-basics/create-a-page.md deleted file mode 100644 index 20e2ac3..0000000 --- a/apps/docs/docs/tutorial-basics/create-a-page.md +++ /dev/null @@ -1,43 +0,0 @@ ---- -sidebar_position: 1 ---- - -# Create a Page - -Add **Markdown or React** files to `src/pages` to create a **standalone page**: - -- `src/pages/index.js` โ†’ `localhost:3000/` -- `src/pages/foo.md` โ†’ `localhost:3000/foo` -- `src/pages/foo/bar.js` โ†’ `localhost:3000/foo/bar` - -## Create your first React Page - -Create a file at `src/pages/my-react-page.js`: - -```jsx title="src/pages/my-react-page.js" -import React from 'react'; -import Layout from '@theme/Layout'; - -export default function MyReactPage() { - return ( - -

My React page

-

This is a React page

-
- ); -} -``` - -A new page is now available at [http://localhost:3000/my-react-page](http://localhost:3000/my-react-page). - -## Create your first Markdown Page - -Create a file at `src/pages/my-markdown-page.md`: - -```mdx title="src/pages/my-markdown-page.md" -# My Markdown page - -This is a Markdown page -``` - -A new page is now available at [http://localhost:3000/my-markdown-page](http://localhost:3000/my-markdown-page). diff --git a/apps/docs/docs/tutorial-basics/deploy-your-site.md b/apps/docs/docs/tutorial-basics/deploy-your-site.md deleted file mode 100644 index 1c50ee0..0000000 --- a/apps/docs/docs/tutorial-basics/deploy-your-site.md +++ /dev/null @@ -1,31 +0,0 @@ ---- -sidebar_position: 5 ---- - -# Deploy your site - -Docusaurus is a **static-site-generator** (also called **[Jamstack](https://jamstack.org/)**). - -It builds your site as simple **static HTML, JavaScript and CSS files**. - -## Build your site - -Build your site **for production**: - -```bash -npm run build -``` - -The static files are generated in the `build` folder. - -## Deploy your site - -Test your production build locally: - -```bash -npm run serve -``` - -The `build` folder is now served at [http://localhost:3000/](http://localhost:3000/). - -You can now deploy the `build` folder **almost anywhere** easily, **for free** or very small cost (read the **[Deployment Guide](https://docusaurus.io/docs/deployment)**). diff --git a/apps/docs/docs/tutorial-basics/markdown-features.mdx b/apps/docs/docs/tutorial-basics/markdown-features.mdx deleted file mode 100644 index 35e0082..0000000 --- a/apps/docs/docs/tutorial-basics/markdown-features.mdx +++ /dev/null @@ -1,152 +0,0 @@ ---- -sidebar_position: 4 ---- - -# Markdown Features - -Docusaurus supports **[Markdown](https://daringfireball.net/projects/markdown/syntax)** and a few **additional features**. - -## Front Matter - -Markdown documents have metadata at the top called [Front Matter](https://jekyllrb.com/docs/front-matter/): - -```text title="my-doc.md" -// highlight-start ---- -id: my-doc-id -title: My document title -description: My document description -slug: /my-custom-url ---- -// highlight-end - -## Markdown heading - -Markdown text with [links](./hello.md) -``` - -## Links - -Regular Markdown links are supported, using url paths or relative file paths. - -```md -Let's see how to [Create a page](/create-a-page). -``` - -```md -Let's see how to [Create a page](./create-a-page.md). -``` - -**Result:** Let's see how to [Create a page](./create-a-page.md). - -## Images - -Regular Markdown images are supported. - -You can use absolute paths to reference images in the static directory (`static/img/docusaurus.png`): - -```md -![Docusaurus logo](/img/docusaurus.png) -``` - -![Docusaurus logo](/img/docusaurus.png) - -You can reference images relative to the current file as well. This is particularly useful to colocate images close to the Markdown files using them: - -```md -![Docusaurus logo](./img/docusaurus.png) -``` - -## Code Blocks - -Markdown code blocks are supported with Syntax highlighting. - -````md -```jsx title="src/components/HelloDocusaurus.js" -function HelloDocusaurus() { - return

Hello, Docusaurus!

; -} -``` -```` - -```jsx title="src/components/HelloDocusaurus.js" -function HelloDocusaurus() { - return

Hello, Docusaurus!

; -} -``` - -## Admonitions - -Docusaurus has a special syntax to create admonitions and callouts: - -```md -:::tip My tip - -Use this awesome feature option - -::: - -:::danger Take care - -This action is dangerous - -::: -``` - -:::tip My tip - -Use this awesome feature option - -::: - -:::danger Take care - -This action is dangerous - -::: - -## MDX and React Components - -[MDX](https://mdxjs.com/) can make your documentation more **interactive** and allows using any **React components inside Markdown**: - -```jsx -export const Highlight = ({children, color}) => ( - { - alert(`You clicked the color ${color} with label ${children}`) - }}> - {children} - -); - -This is Docusaurus green ! - -This is Facebook blue ! -``` - -export const Highlight = ({children, color}) => ( - { - alert(`You clicked the color ${color} with label ${children}`); - }}> - {children} - -); - -This is Docusaurus green ! - -This is Facebook blue ! diff --git a/apps/docs/docs/tutorial-extras/_category_.json b/apps/docs/docs/tutorial-extras/_category_.json deleted file mode 100644 index a8ffcc1..0000000 --- a/apps/docs/docs/tutorial-extras/_category_.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "label": "Tutorial - Extras", - "position": 3, - "link": { - "type": "generated-index" - } -} diff --git a/apps/docs/docs/tutorial-extras/img/docsVersionDropdown.png b/apps/docs/docs/tutorial-extras/img/docsVersionDropdown.png deleted file mode 100644 index 97e4164618b5f8beda34cfa699720aba0ad2e342..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 25427 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 diff --git a/apps/docs/docs/tutorial-extras/img/localeDropdown.png b/apps/docs/docs/tutorial-extras/img/localeDropdown.png deleted file mode 100644 index e257edc1f932985396bf59584c7ccfaddf955779..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 27841 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 JrC|B>e*nH7H{}2T diff --git a/apps/docs/docs/tutorial-extras/manage-docs-versions.md b/apps/docs/docs/tutorial-extras/manage-docs-versions.md deleted file mode 100644 index ccda0b9..0000000 --- a/apps/docs/docs/tutorial-extras/manage-docs-versions.md +++ /dev/null @@ -1,55 +0,0 @@ ---- -sidebar_position: 1 ---- - -# Manage Docs Versions - -Docusaurus can manage multiple versions of your docs. - -## Create a docs version - -Release a version 1.0 of your project: - -```bash -npm run docusaurus docs:version 1.0 -``` - -The `docs` folder is copied into `versioned_docs/version-1.0` and `versions.json` is created. - -Your docs now have 2 versions: - -- `1.0` at `http://localhost:3000/docs/` for the version 1.0 docs -- `current` at `http://localhost:3000/docs/next/` for the **upcoming, unreleased docs** - -## Add a Version Dropdown - -To navigate seamlessly across versions, add a version dropdown. - -Modify the `docusaurus.config.js` file: - -```js title="docusaurus.config.js" -export default { - themeConfig: { - navbar: { - items: [ - // highlight-start - { - type: 'docsVersionDropdown', - }, - // highlight-end - ], - }, - }, -}; -``` - -The docs version dropdown appears in your navbar: - -![Docs Version Dropdown](./img/docsVersionDropdown.png) - -## Update an existing version - -It is possible to edit versioned docs in their respective folder: - -- `versioned_docs/version-1.0/hello.md` updates `http://localhost:3000/docs/hello` -- `docs/hello.md` updates `http://localhost:3000/docs/next/hello` diff --git a/apps/docs/docs/tutorial-extras/translate-your-site.md b/apps/docs/docs/tutorial-extras/translate-your-site.md deleted file mode 100644 index b5a644a..0000000 --- a/apps/docs/docs/tutorial-extras/translate-your-site.md +++ /dev/null @@ -1,88 +0,0 @@ ---- -sidebar_position: 2 ---- - -# Translate your site - -Let's translate `docs/intro.md` to French. - -## Configure i18n - -Modify `docusaurus.config.js` to add support for the `fr` locale: - -```js title="docusaurus.config.js" -export default { - i18n: { - defaultLocale: 'en', - locales: ['en', 'fr'], - }, -}; -``` - -## Translate a doc - -Copy the `docs/intro.md` file to the `i18n/fr` folder: - -```bash -mkdir -p i18n/fr/docusaurus-plugin-content-docs/current/ - -cp docs/intro.md i18n/fr/docusaurus-plugin-content-docs/current/intro.md -``` - -Translate `i18n/fr/docusaurus-plugin-content-docs/current/intro.md` in French. - -## Start your localized site - -Start your site on the French locale: - -```bash -npm run start -- --locale fr -``` - -Your localized site is accessible at [http://localhost:3000/fr/](http://localhost:3000/fr/) and the `Getting Started` page is translated. - -:::caution - -In development, you can only use one locale at a time. - -::: - -## Add a Locale Dropdown - -To navigate seamlessly across languages, add a locale dropdown. - -Modify the `docusaurus.config.js` file: - -```js title="docusaurus.config.js" -export default { - themeConfig: { - navbar: { - items: [ - // highlight-start - { - type: 'localeDropdown', - }, - // highlight-end - ], - }, - }, -}; -``` - -The locale dropdown now appears in your navbar: - -![Locale Dropdown](./img/localeDropdown.png) - -## Build your localized site - -Build your site for a specific locale: - -```bash -npm run build -- --locale fr -``` - -Or build your site to include all the locales at once: - -```bash -npm run build -``` diff --git a/apps/docs/docusaurus.config.ts b/apps/docs/docusaurus.config.ts index 671bab5..a31c571 100644 --- a/apps/docs/docusaurus.config.ts +++ b/apps/docs/docusaurus.config.ts @@ -2,34 +2,29 @@ import {themes as prismThemes} from 'prism-react-renderer'; import type {Config} from '@docusaurus/types'; import type * as Preset from '@docusaurus/preset-classic'; -// This runs in Node.js - Don't use client-side code here (browser APIs, JSX...) - const config: Config = { - title: 'My Site', - tagline: 'Dinosaurs are cool', + title: 'Verbeth SDK', + tagline: 'End-to-end encrypted messaging over Ethereum logs', favicon: 'img/favicon.ico', - // Future flags, see https://docusaurus.io/docs/api/docusaurus-config#future future: { - v4: true, // Improve compatibility with the upcoming Docusaurus v4 + v4: true, }, - // Set the production url of your site here - url: 'https://your-docusaurus-site.example.com', - // Set the // pathname under which your site is served - // For GitHub pages deployment, it is often '//' + url: 'https://verbeth.dev', baseUrl: '/', - // GitHub pages deployment config. - // If you aren't using GitHub pages, you don't need these. - organizationName: 'facebook', // Usually your GitHub org/user name. - projectName: 'docusaurus', // Usually your repo name. + organizationName: 'okrame', + projectName: 'verbeth-sdk', onBrokenLinks: 'throw', - // Even if you don't use internationalization, you can use this field to set - // useful metadata like html lang. For example, if your site is Chinese, you - // may want to replace "en" with "zh-Hans". + markdown: { + hooks: { + onBrokenMarkdownLinks: 'warn', + }, + }, + i18n: { defaultLocale: 'en', locales: ['en'], @@ -41,26 +36,9 @@ const config: Config = { { docs: { sidebarPath: './sidebars.ts', - // Please change this to your repo. - // Remove this to remove the "edit this page" links. - editUrl: - 'https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/', - }, - blog: { - showReadingTime: true, - feedOptions: { - type: ['rss', 'atom'], - xslt: true, - }, - // Please change this to your repo. - // Remove this to remove the "edit this page" links. - editUrl: - 'https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/', - // Useful options to enforce blogging best practices - onInlineTags: 'warn', - onInlineAuthors: 'warn', - onUntruncatedBlogPosts: 'warn', + editUrl: 'https://github.com/okrame/verbeth-sdk/tree/main/apps/docs/', }, + blog: false, theme: { customCss: './src/css/custom.css', }, @@ -69,80 +47,39 @@ const config: Config = { ], themeConfig: { - // Replace with your project's social card - image: 'img/docusaurus-social-card.jpg', colorMode: { + defaultMode: 'dark', respectPrefersColorScheme: true, }, navbar: { - title: 'My Site', - logo: { - alt: 'My Site Logo', - src: 'img/logo.svg', - }, + title: 'Verbeth', items: [ { type: 'docSidebar', - sidebarId: 'tutorialSidebar', + sidebarId: 'docsSidebar', position: 'left', - label: 'Tutorial', + label: 'Docs', }, - {to: '/blog', label: 'Blog', position: 'left'}, { - href: 'https://github.com/facebook/docusaurus', + href: 'https://github.com/okrame/verbeth-sdk', label: 'GitHub', position: 'right', }, + { + href: 'https://www.npmjs.com/package/@verbeth/sdk', + label: 'npm', + position: 'right', + }, ], }, footer: { style: 'dark', - links: [ - { - title: 'Docs', - items: [ - { - label: 'Tutorial', - to: '/docs/intro', - }, - ], - }, - { - title: 'Community', - items: [ - { - label: 'Stack Overflow', - href: 'https://stackoverflow.com/questions/tagged/docusaurus', - }, - { - label: 'Discord', - href: 'https://discordapp.com/invite/docusaurus', - }, - { - label: 'X', - href: 'https://x.com/docusaurus', - }, - ], - }, - { - title: 'More', - items: [ - { - label: 'Blog', - to: '/blog', - }, - { - label: 'GitHub', - href: 'https://github.com/facebook/docusaurus', - }, - ], - }, - ], - copyright: `Copyright ยฉ ${new Date().getFullYear()} My Project, Inc. Built with Docusaurus.`, + copyright: `Verbeth SDK. Built with Docusaurus.`, }, prism: { theme: prismThemes.github, darkTheme: prismThemes.dracula, + additionalLanguages: ['bash', 'typescript', 'solidity'], }, } satisfies Preset.ThemeConfig, }; diff --git a/apps/docs/sidebars.ts b/apps/docs/sidebars.ts index 2897139..4a93de9 100644 --- a/apps/docs/sidebars.ts +++ b/apps/docs/sidebars.ts @@ -1,33 +1,20 @@ import type {SidebarsConfig} from '@docusaurus/plugin-content-docs'; -// This runs in Node.js - Don't use client-side code here (browser APIs, JSX...) - -/** - * Creating a sidebar enables you to: - - create an ordered group of docs - - render a sidebar for each doc of that group - - provide next/previous navigation - - The sidebars can be generated from the filesystem, or explicitly defined here. - - Create as many sidebars as you want. - */ const sidebars: SidebarsConfig = { - // By default, Docusaurus generates a sidebar from the docs folder structure - tutorialSidebar: [{type: 'autogenerated', dirName: '.'}], - - // But you can create a sidebar manually - /* - tutorialSidebar: [ - 'intro', - 'hello', + docsSidebar: [ + 'quick-start', { type: 'category', - label: 'Tutorial', - items: ['tutorial-basics/create-a-document'], + label: 'Concepts', + items: [ + 'concepts/how-it-works', + 'concepts/identity', + 'concepts/handshake', + 'concepts/ratchet', + 'concepts/security', + ], }, ], - */ }; export default sidebars; diff --git a/apps/docs/src/components/HomepageFeatures/index.tsx b/apps/docs/src/components/HomepageFeatures/index.tsx deleted file mode 100644 index c2551fb..0000000 --- a/apps/docs/src/components/HomepageFeatures/index.tsx +++ /dev/null @@ -1,71 +0,0 @@ -import type {ReactNode} from 'react'; -import clsx from 'clsx'; -import Heading from '@theme/Heading'; -import styles from './styles.module.css'; - -type FeatureItem = { - title: string; - Svg: React.ComponentType>; - description: ReactNode; -}; - -const FeatureList: FeatureItem[] = [ - { - title: 'Easy to Use', - Svg: require('@site/static/img/undraw_docusaurus_mountain.svg').default, - description: ( - <> - Docusaurus was designed from the ground up to be easily installed and - used to get your website up and running quickly. - - ), - }, - { - title: 'Focus on What Matters', - Svg: require('@site/static/img/undraw_docusaurus_tree.svg').default, - description: ( - <> - Docusaurus lets you focus on your docs, and we'll do the chores. Go - ahead and move your docs into the docs directory. - - ), - }, - { - title: 'Powered by React', - Svg: require('@site/static/img/undraw_docusaurus_react.svg').default, - description: ( - <> - Extend or customize your website layout by reusing React. Docusaurus can - be extended while reusing the same header and footer. - - ), - }, -]; - -function Feature({title, Svg, description}: FeatureItem) { - return ( -
-
- -
-
- {title} -

{description}

-
-
- ); -} - -export default function HomepageFeatures(): ReactNode { - return ( -
-
-
- {FeatureList.map((props, idx) => ( - - ))} -
-
-
- ); -} diff --git a/apps/docs/src/components/HomepageFeatures/styles.module.css b/apps/docs/src/components/HomepageFeatures/styles.module.css deleted file mode 100644 index b248eb2..0000000 --- a/apps/docs/src/components/HomepageFeatures/styles.module.css +++ /dev/null @@ -1,11 +0,0 @@ -.features { - display: flex; - align-items: center; - padding: 2rem 0; - width: 100%; -} - -.featureSvg { - height: 200px; - width: 200px; -} diff --git a/apps/docs/src/css/custom.css b/apps/docs/src/css/custom.css index 2bc6a4c..22d451d 100644 --- a/apps/docs/src/css/custom.css +++ b/apps/docs/src/css/custom.css @@ -1,30 +1,238 @@ /** - * Any CSS included here will be global. The classic template - * bundles Infima by default. Infima is a CSS framework designed to - * work well for content-centric websites. + * Verbeth SDK Documentation + * Brutalist minimal theme */ -/* You can override the default Infima variables here. */ :root { - --ifm-color-primary: #2e8555; - --ifm-color-primary-dark: #29784c; - --ifm-color-primary-darker: #277148; - --ifm-color-primary-darkest: #205d3b; - --ifm-color-primary-light: #33925d; - --ifm-color-primary-lighter: #359962; - --ifm-color-primary-lightest: #3cad6e; - --ifm-code-font-size: 95%; - --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.1); -} - -/* For readability concerns, you should choose a lighter palette in dark mode. */ + /* Electric blue accent */ + --ifm-color-primary: #3B82F6; + --ifm-color-primary-dark: #2563EB; + --ifm-color-primary-darker: #1D4ED8; + --ifm-color-primary-darkest: #1E40AF; + --ifm-color-primary-light: #60A5FA; + --ifm-color-primary-lighter: #93C5FD; + --ifm-color-primary-lightest: #BFDBFE; + + /* Light mode */ + --ifm-background-color: #FAFAFA; + --ifm-background-surface-color: #FFFFFF; + --ifm-font-color-base: #171717; + + /* Typography */ + --ifm-font-family-base: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; + --ifm-font-family-monospace: 'JetBrains Mono', 'Fira Code', 'SF Mono', Consolas, monospace; + --ifm-code-font-size: 0.875rem; + --ifm-heading-font-weight: 600; + + /* Layout */ + --ifm-navbar-background-color: transparent; + --ifm-footer-background-color: transparent; + --ifm-global-radius: 0; + + /* Code highlighting */ + --docusaurus-highlighted-code-line-bg: rgba(59, 130, 246, 0.1); +} + [data-theme='dark'] { - --ifm-color-primary: #25c2a0; - --ifm-color-primary-dark: #21af90; - --ifm-color-primary-darker: #1fa588; - --ifm-color-primary-darkest: #1a8870; - --ifm-color-primary-light: #29d5b0; - --ifm-color-primary-lighter: #32d8b4; - --ifm-color-primary-lightest: #4fddbf; - --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.3); + /* Dark mode - crypto-native default */ + --ifm-background-color: #0A0A0A; + --ifm-background-surface-color: #171717; + --ifm-font-color-base: #E5E5E5; + --ifm-color-primary: #60A5FA; + --ifm-color-primary-dark: #3B82F6; + --ifm-color-primary-darker: #2563EB; + --ifm-color-primary-darkest: #1D4ED8; + --ifm-color-primary-light: #93C5FD; + --ifm-color-primary-lighter: #BFDBFE; + --ifm-color-primary-lightest: #DBEAFE; + --ifm-color-emphasis-200: #262626; + --ifm-color-emphasis-300: #404040; + + --docusaurus-highlighted-code-line-bg: rgba(96, 165, 250, 0.15); +} + +/* Brutalist touches */ +.navbar { + border-bottom: 1px solid var(--ifm-color-emphasis-200); + backdrop-filter: blur(8px); +} + +[data-theme='dark'] .navbar { + background: rgba(10, 10, 10, 0.8); +} + +[data-theme='light'] .navbar { + background: rgba(250, 250, 250, 0.8); +} + +/* No rounded corners - brutalist */ +code { + border-radius: 0; +} + +pre { + border-radius: 0; + border: 1px solid var(--ifm-color-emphasis-200); +} + +/* Buttons */ +.button { + border-radius: 0; +} + +/* Cards and containers */ +.card { + border-radius: 0; +} + +/* Table of contents */ +.table-of-contents { + border-left: 1px solid var(--ifm-color-emphasis-200); +} + +/* Sidebar */ +.menu__link { + border-radius: 0; +} + +/* Hero section for landing page */ +.hero-verbeth { + min-height: calc(100vh - 60px); + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + text-align: center; + padding: 4rem 2rem; +} + +.hero-verbeth h1 { + font-size: 4rem; + font-weight: 700; + margin-bottom: 1rem; + letter-spacing: -0.02em; +} + +.hero-verbeth p { + font-size: 1.25rem; + color: var(--ifm-color-emphasis-700); + margin-bottom: 2rem; + max-width: 500px; +} + +[data-theme='dark'] .hero-verbeth p { + color: var(--ifm-color-emphasis-600); +} + +.hero-buttons { + display: flex; + gap: 1rem; + flex-wrap: wrap; + justify-content: center; +} + +.hero-buttons a { + padding: 0.75rem 1.5rem; + font-weight: 500; + text-decoration: none; + border: 1px solid var(--ifm-color-emphasis-300); + transition: all 0.15s ease; +} + +.hero-buttons a:first-child { + background: var(--ifm-color-primary); + color: white; + border-color: var(--ifm-color-primary); +} + +.hero-buttons a:first-child:hover { + background: var(--ifm-color-primary-dark); + border-color: var(--ifm-color-primary-dark); +} + +.hero-buttons a:not(:first-child) { + background: transparent; + color: var(--ifm-font-color-base); +} + +.hero-buttons a:not(:first-child):hover { + background: var(--ifm-color-emphasis-100); +} + +[data-theme='dark'] .hero-buttons a:not(:first-child):hover { + background: var(--ifm-color-emphasis-200); +} + +/* Responsive hero */ +@media screen and (max-width: 768px) { + .hero-verbeth h1 { + font-size: 2.5rem; + } + + .hero-verbeth p { + font-size: 1rem; + } +} + +/* Footer minimal */ +.footer { + border-top: 1px solid var(--ifm-color-emphasis-200); + padding: 1.5rem; +} + +.footer__copyright { + font-size: 0.875rem; + color: var(--ifm-color-emphasis-600); +} + +/* Code blocks - more prominent */ +pre code { + font-size: 0.875rem; + line-height: 1.6; +} + +/* Inline code */ +:not(pre) > code { + background: var(--ifm-color-emphasis-100); + padding: 0.125rem 0.375rem; + font-size: 0.875em; +} + +[data-theme='dark'] :not(pre) > code { + background: var(--ifm-color-emphasis-200); +} + +/* Markdown content */ +.markdown h1 { + font-size: 2.25rem; +} + +.markdown h2 { + font-size: 1.75rem; + margin-top: 2.5rem; +} + +.markdown h3 { + font-size: 1.25rem; + margin-top: 2rem; +} + +/* Admonitions - brutalist style */ +.admonition { + border-radius: 0; + border-left-width: 3px; +} + +/* Links */ +a { + text-decoration: none; +} + +a:hover { + text-decoration: underline; +} + +/* Doc page layout */ +.docMainContainer { + max-width: 800px; } diff --git a/apps/docs/src/pages/index.module.css b/apps/docs/src/pages/index.module.css deleted file mode 100644 index 9f71a5d..0000000 --- a/apps/docs/src/pages/index.module.css +++ /dev/null @@ -1,23 +0,0 @@ -/** - * CSS files with the .module.css suffix will be treated as CSS modules - * and scoped locally. - */ - -.heroBanner { - padding: 4rem 0; - text-align: center; - position: relative; - overflow: hidden; -} - -@media screen and (max-width: 996px) { - .heroBanner { - padding: 2rem; - } -} - -.buttons { - display: flex; - align-items: center; - justify-content: center; -} diff --git a/apps/docs/src/pages/index.tsx b/apps/docs/src/pages/index.tsx index 2e006d1..d319e8b 100644 --- a/apps/docs/src/pages/index.tsx +++ b/apps/docs/src/pages/index.tsx @@ -1,43 +1,19 @@ import type {ReactNode} from 'react'; -import clsx from 'clsx'; import Link from '@docusaurus/Link'; -import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; import Layout from '@theme/Layout'; -import HomepageFeatures from '@site/src/components/HomepageFeatures'; -import Heading from '@theme/Heading'; - -import styles from './index.module.css'; - -function HomepageHeader() { - const {siteConfig} = useDocusaurusContext(); - return ( -
-
- - {siteConfig.title} - -

{siteConfig.tagline}

-
- - Docusaurus Tutorial - 5min โฑ๏ธ - -
-
-
- ); -} export default function Home(): ReactNode { - const {siteConfig} = useDocusaurusContext(); return ( - -
diff --git a/package.json b/package.json index b835aad..9dbf0ff 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "name": "verbeth-sdk", + "name": "verbeth", "private": true, "scripts": { "test:integration": "./packages/sdk/node_modules/.bin/vitest run tests/*.test.ts --config vitest.integration.config.mjs --pool=threads", diff --git a/packages/sdk/README.md b/packages/sdk/README.md index f16876c..cb12646 100644 --- a/packages/sdk/README.md +++ b/packages/sdk/README.md @@ -45,10 +45,10 @@ MPL-2.0 ## Links -- [GitHub Repository](https://github.com/okrame/verbeth-sdk) +- [GitHub Repository](https://github.com/okrame/verbeth) - [Demo App](https://verbeth-demo.vercel.app/) -- [Contract Source](https://github.com/okrame/verbeth-sdk/tree/main/packages/contracts) +- [Contract Source](https://github.com/okrame/verbeth/tree/main/packages/contracts) --- -**Questions or feedback?** Open an issue on [GitHub](https://github.com/okrame/verbeth-sdk/issues). \ No newline at end of file +**Questions or feedback?** Open an issue on [GitHub](https://github.com/okrame/verbeth/issues). \ No newline at end of file From 64f1bf0089bf97e375ef78d27ac3b0cd4f9ae575 Mon Sep 17 00:00:00 2001 From: Marco Esposito Date: Fri, 6 Feb 2026 17:43:44 +0100 Subject: [PATCH 39/51] switched to websocket transport --- apps/demo/config.ts | 3 +- apps/demo/src/App.tsx | 3 +- apps/demo/src/components/CelebrationToast.tsx | 2 +- apps/demo/src/hooks/useMessageListener.ts | 42 ++++++- apps/demo/src/rpc.tsx | 111 +++++++++++++----- 5 files changed, 125 insertions(+), 36 deletions(-) diff --git a/apps/demo/config.ts b/apps/demo/config.ts index c73219b..c7b2942 100644 --- a/apps/demo/config.ts +++ b/apps/demo/config.ts @@ -6,6 +6,7 @@ import { metaMaskWallet, walletConnectWallet, } from '@rainbow-me/rainbowkit/wallets'; +import { BASESEPOLIA_HTTP_URL } from './src/rpc.js'; const projectId = 'abcd4fa063dd349643afb0bdc85bb248'; @@ -33,7 +34,7 @@ export const config = createConfig({ connectors, chains: [baseSepolia, base, mainnet], transports: { - [baseSepolia.id]: http('https://sepolia.base.org'), + [baseSepolia.id]: http(BASESEPOLIA_HTTP_URL), [base.id]: http('https://base-rpc.publicnode.com'), [mainnet.id]: http(), }, diff --git a/apps/demo/src/App.tsx b/apps/demo/src/App.tsx index a41c3c1..d20228d 100644 --- a/apps/demo/src/App.tsx +++ b/apps/demo/src/App.tsx @@ -184,7 +184,8 @@ export default function App() { address: address ?? undefined, emitterAddress: emitterAddress ?? undefined, onLog: addLog, - onEventsProcessed: processEvents + onEventsProcessed: processEvents, + viemClient, }); const { diff --git a/apps/demo/src/components/CelebrationToast.tsx b/apps/demo/src/components/CelebrationToast.tsx index 84dc9c3..b8b4538 100644 --- a/apps/demo/src/components/CelebrationToast.tsx +++ b/apps/demo/src/components/CelebrationToast.tsx @@ -11,7 +11,7 @@ export function CelebrationToast({ show, onClose }: CelebrationToastProps) { if (!show) return; const t = setTimeout(onClose, 3000); return () => clearTimeout(t); - }, [show, onClose]); + }, [show]); // eslint-disable-line react-hooks/exhaustive-deps const width = 320; const margin = 16; diff --git a/apps/demo/src/hooks/useMessageListener.ts b/apps/demo/src/hooks/useMessageListener.ts index f16d779..df47e58 100644 --- a/apps/demo/src/hooks/useMessageListener.ts +++ b/apps/demo/src/hooks/useMessageListener.ts @@ -27,6 +27,8 @@ interface UseMessageListenerProps { emitterAddress: string | undefined; onLog: (message: string) => void; onEventsProcessed: (events: ProcessedEvent[]) => void; + /** When provided, uses watchBlockNumber (WS subscription) instead of setInterval polling. */ + viemClient?: any; } export const useMessageListener = ({ @@ -35,6 +37,7 @@ export const useMessageListener = ({ emitterAddress, onLog, onEventsProcessed, + viemClient, }: UseMessageListenerProps): MessageListenerResult => { const [isInitialLoading, setIsInitialLoading] = useState(false); const [isLoadingMore, setIsLoadingMore] = useState(false); @@ -522,13 +525,20 @@ export const useMessageListener = ({ ]); // real time scanning for new blocks + // Uses watchBlockNumber (WS subscription) when viemClient is available, + // otherwise falls back to setInterval polling. + const isScanningRef = useRef(false); + useEffect(() => { if (!readProvider || !address || !lastKnownBlock) return; - const interval = setInterval(async () => { + const handleNewBlock = async (blockNumber: number) => { + // Guard against overlapping scans (WS blocks can arrive faster than scans complete) + if (isScanningRef.current) return; + isScanningRef.current = true; + try { - const currentBlock = await readProvider.getBlockNumber(); - const maxSafeBlock = currentBlock - REAL_TIME_BUFFER; + const maxSafeBlock = blockNumber - REAL_TIME_BUFFER; if (maxSafeBlock > lastKnownBlock) { const startScanBlock = lastKnownBlock + 1; @@ -546,11 +556,35 @@ export const useMessageListener = ({ } } catch (error) { onLog(`โš ๏ธ Real-time scan error: ${error}`); + } finally { + isScanningRef.current = false; + } + }; + + // Prefer WS subscription via viem's watchBlockNumber + if (viemClient) { + const unwatch = viemClient.watchBlockNumber({ + onBlockNumber: (blockNumber: bigint) => { + handleNewBlock(Number(blockNumber)); + }, + emitOnBegin: false, + pollingInterval: 4_000, // fallback polling interval when WS is down + }); + return unwatch; + } + + // Fallback: HTTP polling (identical to original behavior) + const interval = setInterval(async () => { + try { + const currentBlock = await readProvider.getBlockNumber(); + handleNewBlock(currentBlock); + } catch (error) { + onLog(`โš ๏ธ Real-time scan error: ${error}`); } }, 5000); return () => clearInterval(interval); - }, [readProvider, address, lastKnownBlock, onLog, onEventsProcessed]); + }, [readProvider, address, lastKnownBlock, onLog, onEventsProcessed, viemClient]); // clear state when address changes useEffect(() => { diff --git a/apps/demo/src/rpc.tsx b/apps/demo/src/rpc.tsx index 927494d..41a2b2c 100644 --- a/apps/demo/src/rpc.tsx +++ b/apps/demo/src/rpc.tsx @@ -1,51 +1,103 @@ import { createContext, useContext, useEffect, useState, useMemo } from "react"; import { JsonRpcProvider } from "ethers"; -import { createPublicClient, http, fallback } from "viem"; -import { base, baseSepolia } from "viem/chains"; +import { createPublicClient, http, webSocket, fallback } from "viem"; +import { baseSepolia } from "viem/chains"; +const WS_URL = import.meta.env.VITE_RPC_WS_URL as string | undefined; +const ALCHEMY_HTTP_URL = WS_URL?.replace(/^wss:\/\//, "https://"); + +const PUBLIC_HTTP_1 = "https://sepolia.base.org"; +const PUBLIC_HTTP_2 = "https://base-sepolia-rpc.publicnode.com"; + +/** Best available HTTP URL โ€“ Alchemy when configured, otherwise public. */ +export const BASESEPOLIA_HTTP_URL = ALCHEMY_HTTP_URL ?? PUBLIC_HTTP_1; + +export type TransportStatus = + | "ws" + | "http-alchemy" + | "http-public" + | "disconnected"; + type RpcState = { ethers: JsonRpcProvider | null; - viem: ReturnType | null; + viem: ReturnType | null; + transportStatus: TransportStatus; }; - const RpcCtx = createContext(null); export function RpcProvider({ children }: { children: React.ReactNode }) { const [ethersProvider, setEthersProvider] = useState(null); + const [transportStatus, setTransportStatus] = useState( + WS_URL ? "ws" : "http-public" + ); useEffect(() => { let mounted = true; (async () => { - try { - const p = new JsonRpcProvider("https://sepolia.base.org", undefined, { - polling: true, - pollingInterval: 3000, - }); - await p.getBlockNumber(); - if (mounted) setEthersProvider(p); - } catch (e) { - console.error("Ethers RPC failed:", e); + const urls = ALCHEMY_HTTP_URL + ? [ALCHEMY_HTTP_URL, PUBLIC_HTTP_1, PUBLIC_HTTP_2] + : [PUBLIC_HTTP_1, PUBLIC_HTTP_2]; + + for (const url of urls) { + try { + const p = new JsonRpcProvider(url, undefined, { + polling: true, + pollingInterval: 3000, + }); + await p.getBlockNumber(); + if (mounted) { + setEthersProvider(p); + if (!WS_URL) { + setTransportStatus( + url === ALCHEMY_HTTP_URL ? "http-alchemy" : "http-public" + ); + } + } + return; + } catch (e) { + console.warn(`Ethers RPC failed for ${url}:`, e); + } + } + if (mounted) { + console.error("All ethers RPC endpoints failed"); + setTransportStatus("disconnected"); } })(); return () => { mounted = false; }; }, []); - const viemClient = useMemo( - () => - createPublicClient({ - chain: baseSepolia, - transport: fallback([ - http("https://sepolia.base.org"), - http("https://base-sepolia-rpc.publicnode.com"), - ]), - }), - [] - ); + const viemClient = useMemo(() => { + const transports = []; + + if (WS_URL) { + transports.push( + webSocket(WS_URL, { + reconnect: { attempts: 5, delay: 2_000 }, + }) + ); + } + if (ALCHEMY_HTTP_URL) { + transports.push(http(ALCHEMY_HTTP_URL)); + } + transports.push(http(PUBLIC_HTTP_1)); + transports.push(http(PUBLIC_HTTP_2)); + + return createPublicClient({ + chain: baseSepolia, + transport: fallback(transports), + }); + }, []); return ( - + {children} ); @@ -58,9 +110,10 @@ export function useRpcClients() { } export function useRpcStatus() { - const provider = useContext(RpcCtx); + const ctx = useContext(RpcCtx); return { - isConnected: provider !== null, - provider + isConnected: ctx !== null && ctx.ethers !== null, + transportStatus: ctx?.transportStatus ?? "disconnected", + provider: ctx, }; -} \ No newline at end of file +} From 57622c94dc3854fac5df573faa65034499c13c3e Mon Sep 17 00:00:00 2001 From: Marco Esposito Date: Fri, 6 Feb 2026 18:29:38 +0100 Subject: [PATCH 40/51] cleaned logs --- apps/demo/src/App.tsx | 113 ++---------------- apps/demo/src/hooks/useChatActions.ts | 62 ++-------- apps/demo/src/hooks/useInitIdentity.ts | 39 ++---- apps/demo/src/hooks/useMessageListener.ts | 57 ++------- apps/demo/src/hooks/useMessageProcessor.ts | 39 ++---- apps/demo/src/hooks/useMessageQueue.ts | 48 ++------ apps/demo/src/hooks/useSessionSetup.ts | 27 +---- apps/demo/src/services/DbService.ts | 2 +- .../src/services/EventProcessorService.ts | 44 ++----- 9 files changed, 75 insertions(+), 356 deletions(-) diff --git a/apps/demo/src/App.tsx b/apps/demo/src/App.tsx index d20228d..2639f3c 100644 --- a/apps/demo/src/App.tsx +++ b/apps/demo/src/App.tsx @@ -1,4 +1,4 @@ -import { useEffect, useRef, useState, useCallback } from "react"; +import { useEffect, useState } from "react"; import { Fingerprint, RotateCcw, X } from "lucide-react"; import { ConnectButton } from '@rainbow-me/rainbowkit'; import { useAccount, useWalletClient } from 'wagmi'; @@ -40,33 +40,13 @@ export default function App() { const [showHandshakeForm, setShowHandshakeForm] = useState(true); const [handshakeToasts, setHandshakeToasts] = useState([]); const [showToast, setShowToast] = useState(false); - const [isActivityLogOpen, setIsActivityLogOpen] = useState(false); - const [activityLogs, setActivityLogs] = useState(""); const [verbethClient, setVerbethClient] = useState(null); const [healthBannerDismissed, setHealthBannerDismissed] = useState(false); const [isResettingContacts, setIsResettingContacts] = useState(false); - const logRef = useRef(null); const chainId = Number(import.meta.env.VITE_CHAIN_ID); - const addLog = useCallback((message: string) => { - const timestamp = new Date().toLocaleTimeString(); - const logEntry = `[${timestamp}] ${message}\n`; - - setActivityLogs(prev => { - const newLogs = prev + logEntry; - - setTimeout(() => { - if (logRef.current && isActivityLogOpen) { - logRef.current.scrollTop = logRef.current.scrollHeight; - } - }, 0); - - return newLogs; - }); - }, [isActivityLogOpen]); - const { identityKeyPair, @@ -97,7 +77,6 @@ export default function App() { chainId, readProvider, ready, - addLog, onIdentityCreated: () => setShowToast(true), onReset: () => { setSelectedContact(null); @@ -117,7 +96,6 @@ export default function App() { sessionSignerAddr, chainId, readProvider, - addLog, isSafeDeployed, isModuleEnabled, setIsSafeDeployed, @@ -144,11 +122,10 @@ export default function App() { }); setVerbethClient(client); - addLog(`VerbethClient initialized for ${currentAddress.slice(0, 8)}...`); } else { setVerbethClient(null); } - }, [executor, identityKeyPair, identityProof, identitySigner, address, addLog]); + }, [executor, identityKeyPair, identityProof, identitySigner, address]); const { messages, @@ -168,7 +145,6 @@ export default function App() { emitterAddress: emitterAddress ?? undefined, identityKeyPair, verbethClient, - onLog: addLog }); const { hasPendingReset, pendingHandshake: pendingResetHandshake, limboAfterTimestamp } = usePendingSessionReset(selectedContact, pendingHandshakes); @@ -183,7 +159,6 @@ export default function App() { readProvider, address: address ?? undefined, emitterAddress: emitterAddress ?? undefined, - onLog: addLog, onEventsProcessed: processEvents, viemClient, }); @@ -197,7 +172,6 @@ export default function App() { getContactQueueStatus, } = useChatActions({ verbethClient, - addLog, updateContact: async (contact: Contact) => { await updateContact(contact); }, addMessage: async (message: any) => { await addMessage(message); }, updateMessageStatus, @@ -617,85 +591,20 @@ export default function App() {
- + title="End-to-end encrypted messaging over Ethereum" + description="Verbeth SDK - End-to-end encrypted messaging protocol using Ethereum as the transport layer"> +
+

Verbeth SDK

+

End-to-end encrypted messaging over Ethereum

+
+ Get Started + GitHub +
); diff --git a/apps/docs/src/pages/markdown-page.md b/apps/docs/src/pages/markdown-page.md deleted file mode 100644 index 9756c5b..0000000 --- a/apps/docs/src/pages/markdown-page.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -title: Markdown page example ---- - -# Markdown page example - -You don't need React to write simple standalone pages. diff --git a/apps/docs/static/img/docusaurus-social-card.jpg b/apps/docs/static/img/docusaurus-social-card.jpg deleted file mode 100644 index ffcb448210e1a456cb3588ae8b396a597501f187..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 55746 zcmbq(by$^M)9+14OPA6h5)#tgAkrW$rF5rshja^@6p-$cZlt9Iq*J;!NH?5&>+^i? zd%l0pA7}Qy_I1b1tTi)h&HByS>tW_$1;CblCG!e^g989K@B=)|13|!}zl4PJ2n7Wh z1qB@q6%`E~2jemL!Fh^}hYfz85|I!R5RwovP?C~TGO*Io(y{V!aPUb>O6%!)!~Op% zc=!h3pup!KRwBSr0q{6*2sm&L-2e})oA3y5u+IKNa7f6Ak5CX$;b9M9ul{`jn)3(= z0TCG<li6i8=o)3kSrx^3DjJi7W8(8t_%PJ~8lVjC z2VTPD&_&_>060+qq1c&?u#iAbP9wbT2jg5_aX>LlOOXw|dQJ8p&2XYYDc|J+YUT?3|Fxm{f?d*1vFWPGwXt8P3T#_TQB*NSP3+0+ndOe%v- zTZotCfofsS06&ki{<`Cj8{s5jFZc&1dl<{IBW%#V_!JjOm6+#&aRi;8ODL(?0fENIOtiNXjMhdO24CeDB#rNcC*<=TwpueFfx=2=r z-lt`qW^;vEFji%7kO25#YkwjKyZ93WFbbY!Q6-@Jz!9kqj>xgp2VhEYyMJwMYyHZV zG;7!MV>54LS*F?==$6(Z9S zfrEy``J-iu6G?#+q=$58MlrE}+C~G-hEMn#CuNuuVV;8#FHuD_feqmtfw~Ran|V#C zy+f^&q>|d(X{ubCVWs3Ai;Fz>-kAk`yX{^Qj_xV#NEV8oxtfCsq3%uYN0U4+Kcu%j z?Rzr+fnu%QVSgx7Z8;iqDfklVK3tl(C|B5~_ywyQf&|IJgyoV|q( z<1`6^2G=2%pTX$m#~!Q-7f>sA;n6 zsy{fJ>o;yxpRCMtZFb#E)dl;n&K%g;H?#HaC_HvnHuqN*d+9vB7ZNpfqqTsk*(((>8<~)=+HX!*Ss3~|# zShAf@XL@`g)$G$rAA9cU; zk+0v$7Rl=PDs_rN&*@^DQ<3}LIqeDu_8cvBZoZQK#xaB*@qDhG^d_fYSBG@Y_wC5B zy{FTF=4jI`H0PRGXlulcwJ$*KBs^);$y@AfTWB!przp%+gn+%ZU2qD$Eml|2m?K;y zsAx49(J!Aq5lqX4u5Rlh{1hD6V?uI0-0}%=eSBZT$;aWCJrM*G=&(~P~7QxUJFlHF+63{SfFhWU%gt&D(4Z~X54CH?JsJEHzO9{;5# z5f-P_*$Y>=CXYL(i4Vw1)$Y&DwihU}jeLyuS2hQ>zS%^7!rET)y)?ZI;W^c(neZ5; zcYHr@l=i48ImXZ(y)o<7>Av^Nw!8t!KDn{67gef*G5f-&iZ;`G@ej`@uBTkn0_QVc zw|RGr%!y|LdrjWk$H6iyi9+o%)D%pY)DHt@e}~ z-ryeSdskl$jkA%Gje(z=CvGUb4lqb$@>K02q8; zBpGv48m)G3Jz8nD`*7z;ch+s~JId9q{~KmJV4qG#VyhtwGh1U7ZW~XgF&CHVcfjI@4|IAMzt7B{D4ttmRhW76WO-cP6HX>7cPSIon_Pic=YB^cwH;qqm2b=+@OjfH55;lLt@>%R&7MejNBW98rLJXZZQtF zmm<7wrV(U^X%O}rZp($;Nb;(nTO##-Fk_K%y2c4)Yt?EsKDLVz&SyIxmRvPYUf)~A zkMkfE4X%Dz8*f>*I$-5J)wLSdUUaV&xP%U!WXidR7*F!E3|fu1supvKyq>T*84`M& z=Dt)zp4h*&a^3bbAWSy|{$~mRt znU?J9X@W)z1+)2SKH;RDEk{C{F~PxzePOC4k2I22=OxAKZEhYTo#jZLnzJRvL-#I` z%_%U{YhbA5LxSuc7mb|<#t0l8BZHy-cvj?r(|M5YOMU0wJ}PLj6z+91PP@u~sUN(0 zoPkUiqj+}m^;#5WI-p1sl3!d`><`0$1U4*Tus{#@{oJ~C_^ll&fIY{RWHLB)Iw~-5 z_trhoc*;Xx|5u&|7Q=~%>SU9dJXt>XnSP z$}G4aR=bB#EC~i5U_z8$Olb|B1Ec2J6a`$P64P%*8UxnscnAmYxki;vGRSH!M<=El z7AwT}?l;S3Ju)fk9NDaW<~K*9J6DCaimLP@Zry38*StONeVaYg4GMSV1sb;$0#63E znXJh6$=|17p)3iget{zQI-ZcSA4kztpbVusXh9 z97)P(^GVx?9}T_w+?VG}Hu2dxs!PdI;c!Skm{8crbnUpgGsmO6Y~0f~`3af#=;}JO zs+>jl(}Ww@TF9nIIp*io9|Ar+SXKeoJ2p0xqq^dDIUaz_3UMRe!*?g>RKH02EKY^8E=Ov%mKqCKc_O8|58B$F z2nPy$8uP`nq5-GE>)_IseB*$*+;W_EcowmS_|Q%w=6aW(&AB z%OtxG-1&Xrq>E%{bjzK4kBw z>Fssz$u`@4(H4(yPd(wlj>oT~6v>IV?P zZDj-meBV3Xh&lOz7Q@p@Wg;VMtEtz0tWmBTlY%+n#pR{sF{)xA5u*BuDd zu~BvH^44yI-2poCTSulFIMHH|6$HIN2!U|l513rs>o5b7&T060H4stH!Rj6uhJ>*c z|EXULN z@Ms{ehhc57nJbz5tP(eS6gqwNx4;1P!wL~Xzd!0hhz^)}wUrh90P!E%NrcHnd5moayrW^mwAO&F9eVphr}#sl@u5#&@cZG3Pef_5ki2d4No`s`w>3E)~NzQq~(%!wQ~iX zS=!>QgW*;6d%-30eCYi-s{}L5+4xRvjRMVc-|_!cJZOOW|D`V>G$9BAul9zT%D`1W z9M}_f^IBfCT+$nV07$(ZMgM6Q>awY7HarX62K->7rWiZ>Plf%@Tc$X)SUE~YSzKHO zOo@t904vq~)2~8z9N~Y(5ghjQaweijSq9}$13ISo#S19Gyn+S8<}IqydMB*M2Fv(F;m*Z^NjCKA@hf(byh~F_Wz8Y|LB9G zj>CREj|u0+^+~|!q^Z4wYAm~DH8vU0K5hJLx;^WW) zn1WdmfwUxh0&F)Ge zJJ$CZ;Gif2pJe@g3jR{7X$9eG;iwp*gh^4;#?q$usU`sYWi;VGk9zUsuxLCqS?i4> zU*!nKB+RzHh&TF;OaYU1boXkFHseTZ9^7*ClUf6WeOAm2`Zgc?XVxs@; z3fyjS*rbEGB3x27NK$sQDLqTsoYX+=I47hKrjQhxw>;|F(o#M)1Zs3=vHf+{4*=lU zQU(~L2n)P!C zOzn-%j;-zdo*A78MJ(b}aNl*Pd%bH4<%$K3cP@a%?zXvnXr7tnRf8PyxM=h2%x6XV zGm+MfF#t#t=FVq6y^o&};nl4gZ1=OgS0W6oT4??aAn_EswVeD=G?0*F3Ky5X?YMg! z*>m;`U68Bw-j3*NS)Xv59AyM$#IrAaBLy!3%T~RztCkOyD`0Oh)~c45m`f(fWkn+8 zFDQ?ehB?iesKfXr>kR(d+^nK;|$bJ0BgK9l#= zSZkY0hNH`T%pTpu&S<)sN$BmKep32<*GjviX5<~dm2S)BRn}Za<=11?iR0CbzUy=Y zs!S!r=YBKN!Hvrz2HB~apVp)gQ@jZ_C@MZHwF>*RQt`RvqEl`)rFXy;*9O;aJ^+IS zAuxBFkwxDhrD+zs6}YE;!WWE7N;x=xxy(hv8tOrT%;~evWtP_;i-tw#{=|s|_1gD} z+$ZPC>;C15y?f=k!B)}XV?@W+W5Jl7E#au2n|eXFYo52!7iV_nr>%rHTLnmp5t__ zeQ~n3Y!)Mwq>pgU`A+DOtI(5{uM`!T&#y7{XqPhrZyx}q50{b`55VTpH9@&go43WC zqZc?IJ_ikEfm4 zqiap;*teY3XjF&M`E)w#v0j2fK8>&^=3ARl7X5?sL7($cGUyT(&GjZ}T7K}UWUq6o zgZIm=(`C|a=eg_1ZeQ8aAv^V`3$rbeo%f|J-#teM&do=aJ4+|bCGzXl53;$~hV*A0ZA5ycpm&br> z1s-woGI3ag*H2HL@1`7`+#zk!nQo^`L}FmXBF9_OVvslb3Qd{^lg7NlT6j-eh)ldq zIsckeM z_udDHz~0vrwpZ3KkTG;-vI!dRfSCp$d>Y)?cj8N5Tr%KDYlI~&_w+W~Esn4I>jEK8 zFVT=y$0H**Z{;PZsC?US7QBb(=tZKtCHDjvqV8L^j>>H?^4A4kTvR^*B7Ecb4?qFk z;I3A-%I#4)i|WCd)!jLZw1itTxsZ$F`MsNa(gzoB&z!Z262^le=~~4I&U`Eb`C+z^ z-VqlxQ;MGC=e90n>dE>aoHV5TkqviF0s?l+z${VoH%t8KFvbH=8^6e$^AlVGU~39o z`MtfitBvEM13&NqqE=`^fHwS_HEw#UDbHmBR+1A|sO+c44k$ zHR9{S!q-(m1a+=}nRGQkrWg-S#Cg;_7%!4Ry2VnE5r>E(^0Gl4^r-P`1z2qO@^9(pRjEp!;DAe7B)FZP$pa4?IWYcn*v>YZ(G2ETw zy|C4)s}8H`Ddud6ogaW9O%*z&O_X=V^6P+mS%uG2EcbTZmk$RT3*(0o4D%(Ts3kn3 zR^3eYF*}KjX-S8m()tqnj4;!Sp!Ho z(7&2M@h1HM;%Et+(u{~Toh0sg@7K`vuJ8O(-mWug9HRvjKP2RmGqWQF%DK(bM_*a0 z>f3#KhBt~#=bL&FWEC}JiXdh?Q9fn5e)7$+{?1Bdf8>;*vDW!BMGjU0?$JBadm(AQ zHAmi$WF|HJ@r5-F$f^VPE+X>suAfbT1DUvi%}6k2#y?ZFyltx!?p zAr?D|oG4gh_c+U9sb>u3LP&?IzmiCo$x4%SP!Q8Q(jEtG(-GPNIhRV_K5L z7Q77k6Jdl2*V9zOs=X@?=vUZ(27Ngc&%L;RjmxGl273=|7++0XC*K z9Zp<^Y~Pm)w3D*jwEo<^OkS4Y<#>lqUb=O)W%Fa5t!Yi<%z$TRIO#_Z7Q3QZ2H5BD@(x_63h;Y($5taTf_%0;ZvK_v)P3}%^YaRF4ri60UEoVB z9tvN{)Jtntfs9Z(yp!blwx06#5$P9W8ouO?r4Ila4@;@S!F4qL>h!`rvxwm8$-&c` zq^<(9nR=GK@B4e0qjX45ZoSs3?|jeZ@13@KMK0R)%1IlSsLp0DH)BFK20FoEM2kwW zSasI{O!BwCJ+a#u@A3ot$06uqU?n&`1G^@J*u|t@Fqwmwe+Wf0fpg%{_PCq6A2+)j z2hE=ehK9p~efCY}}Fj~mMr1Qr~qOdueZ6a_2SDwHZ*lG#r|D%`UFa~RYpuWgUN;*|PxsXBBeqTj`RJnU2 z9PE7zrU|}#_j#k%TQeT63k<&b?|z^RNGOSfltB4MjA|mxqLrdoZ?;jS1BSRxcR{3 z&%l5U(~v7ESy(7pNhyb$1x}p^+*ny$*~6KoZMdfentT6QH1Dr`Dd@U^^%MTqyRNen zJ1b!yKUiiizxRn-n~&g}YvqM*{G%USoM1&>P*AuSldPnqET|FpU!M=af1wNq_3z-J zu56ng_&fk$SpR2Tg&VxTY(oJPP3gAh>wSjZ5#J1#nHbkU`Cof;dA1dQz?$+;E7aQf zK?$L1IL6d(9>vPMi+iISD+SJz*W!e)X$i&Pwc(XN-;gZPke+O!zgm29u4?v!xUP9C zcK48Y@K`NN;M7x{1@te z=@S`oF&M(3^!G8wji3Z4u|IZUp?p~QVc?q&l}!U>SAWC+@B3Q=M8Gx8SMIb+e*r+q z{Yg@g$}_Sz-mgRV1*RA!0Rj$rc-W8!5u7m!h@?;r;RvN(6Nx9m1}wb6UV=69pH!1u4ND1C3^0#GV9Vk5v%jLF1iBkM+~_oe#(k6e04;|1 zqVxcTK}B~<8@cW$rb+NWw4LZ7KVGkN-UHS;bD^cK+2-3`Rj^V98<9f`kPTuKt;S`5 z?|)V)15P$Dy~TG^p+BRJpbTIN2fb57!5|jT#s_X^pnNi>exLT+xuR}kI zLTF>DrKH5As1d;xUMq}JD`rE#xm<3PV^bKt~*|K(@>_s$+l6?PG9c;I$Y$I9Wx zA;xF_MZf_#OaTl`qJ^-80rMXYZnX;yHMnC5N`v2j=zq5Pz&RPG92*Z}aj95Z+R(pq z5>Xr9FJ8qsGy#`dMOy$X4%|!w<&^&whNI5zri}lV6#?4!$Ljbv_f0<2-3Nu?974eOh|NodBrc6s{g264H^#+vv zkI(-F!??JN@B<(iW`KcV-0ngu+-@)j;0A>UFo`kAQKI6|7gl5B1rI>b2tj!?@U%?! zpFY4#g}oL@l|*Hrm#l)1qwa_0RO)Vc;oKlpABihvuq26}r$$LgB-%uwqRxuRrpyG- z63Ji#aENg52nfiiNRQwVk-^yt-aSGBkWsL4aPbK7DcQKVMb!z2h+ndEs=YI%qUPWc zQ>IZ-)zB2Te@6Q%>$!xa)SLHy;OQb1@YE3;2Jiq}T8Nyd)7_1XLd)Qqf~l-gf<mu~bv_xL2)jRuX@t1;#}dEe+$KYBs8Ozc8vKSmQMe zW+znS+=sB{$!eWdtEK&;U{CqQ65Mz$g8{KO3091K?+PmZnxe)Uj z+Qa!s1zBptH)^y=Y^r;+YwUV(!nv}S<^CwP->`OJJ9$f5gUG$;btdeT%D1lTQVA%c1zi!li^! zRC4P;e}Vde23*`#o$}dkJ+39wA!C@gdHJNz_ROozn%~qZ35{gxr zfiN+FJmv8BeiZfN4}PZY+~4(EHI@`4GB%VeN^dL-nxv{!>bS=G=d1&YuW4g(RYo?9 z1bQp@-L75k9jgsahz$6&S+Al>N$6|(Uspyh?G^CV(>yb-uEMv?{QHK7y|JZHbV$py z%-C#HQ^wHzF5_m4mG%K(t4T}wM0ZA{r9PYV^B7{;x3r!Xhwb>CR?<2{=4)iW>-lFp zYAZW-ff6Srzcmf>ey26kFp~2&CwAle919+v=b#GbfQ_k(^GDH^U5h6Ij_hJl+$cY7 z`$l|J9)NY0%G=H3-AiTp4`ibZCebLFOx0X*^9LW5S-jM98V1l7TC$z>H_cy3Z}AyT z7cVLl@}RT$dt1%R4$rYgTUqZJB_<@D5gGBnLzk|&Ap3rHOWJjl)n=4BT|4ZgqT{Y# zt8otJt6vZPNdUZ->2VQc|t#}@1f$zuiGu7Z`2Eq_iUO7kLfvf z3+3l;rJH=!P82eCED=AEqW3F^^w0nBW|fbIo$+A)nzK!N%82P?SXGa`4vSNK00<2u zG?U_{jq8ikbd8p@c-wd;R3TJ+v(c9o9< z15te~^)#o6%yp?zaR-=9=hVgU2)|jpPHt`JGmCnIB+qepbmFikm>#nfBmU{7vA8^z zhTK~#rjjnUOtV*azuR=2pq%=qDo}!HCW$#qTWyAliZ8Xa(cAZ0uV^tvuLjr-#E|<6 zgACc9`oD!F+lpA=rLNEf$nCx{x6Vg$hB|ia>mt1(@zkT4(zdKQrNiynVbyP`+<(GC zZSyg_F+eKZ$i9krPDP!?9!-GQV7-#k7*{YGhxdf%D@)yd=P%=c?r60bP2qytty%-G zh7;7A?%TTQIkk;cPgbW*m6aq{m1>`^R}`Bmi$Y$X?QaEJ3_Auk*q^L1i~N3dGM6CL zP<_JeZDBHK(^_7!@i}$(_U*t}@%hy|H{~Q{;gP|bU)fn%xGdctI%`>elX|Q^@vKaK z!d+`Jp@j=)v%^wXH{7|-__X;}-BP#uIY3=_0IGNc zu~4o%m8|B~5EtZ$^}=3sv!lGEYU+H?Y3%_wM6P8#*6#HJvT!3ul#<{n9ja- zRGu5okTwJ1Zmk}BqcGi4_;~IURanbdr+P5iXG<{exUhhs+*pLQ^{jA#EZ#>o0{+2Mh|5& za#ugek0I`(zQL#5eLDARVY*Xa(DwdUqkel}vhN3?;f0iO-H(xqufvN&!zQI78i>uE z8>&m)ewHaoGgtXPku_dEb6PORWr~;1cC<+G5K=KBl%`A&gp6C>lB)v5Ri$FsN;P4>0AbJz7kC<~Dg6Mg7fXVHmZhEHpA*eA&u za?3ON*{!W8PYLPoTR+cR&PxuH$lp`AWkTjWWz)Zkn3TIiCEofih+Lm=9GE(9)!Yfc zt(H1<`s=^*222e=?7hC0lh4e7B}PtVI_{cAdxGNtdfZX}Ca>Ti9YS^NB6cCtzFtR} zgaj!>#THZKLuuFqeb58ou+VPMIV94Az9}?pq(nm5%Nr@`CDh7dQqUo_(1Ka~Jk;oawETtB8>b`mRyBtgh zO#hV*Tx!lPBM`YD{&wUnqnt2DkRmgRC{h$?KYyR zNy|HI%;HhKQrs~er!LN>c2+qWT)k%E+~E5H9eFKV;EhkieNbfqMTavz)YO`;;q)r^ zRKcAY}gLEwaGA zNB*t;%C<*Y+tgCdcJX-=MUjGgyz~ESiO9#&b61{-h<+|2 zO;mjRZ}0|pCLmN$E}rD#(9h}~)QpVO*=OQA z#Y%e{>N&D?0uC{dY5L(<8J1$SoXTWsj~6x5e9=~^#nEWa^lWqnid)H7wg`B&H>nuf zicIgRBoFD2ii?SfJ43AUH&TVFO^DDYcT;;?zvOP%hwr9IDk(8n^Rrc$KG_W$S^CCU zJn=ZugG;lxxPrOnJdw}Typ5n~t5&$I{si5!MLacZa-r_WCh{j~l7-Op=$9TV5idhN zglm&=R)0UNEvq|kz+%&#x}Q{2@c3ZLBldp!yX7N~c^eZPht|o%1isQe*+RisbVF_% zc)4$!;>pF);4JrP4@@UX#!&8hI;B{0l7;+j>*r10Q|es&1NFKQ)-tV2$Om$A@O-## zCLqC6viD-87K8StG^Ws5ct0&olMkYox>$?+Dv3O{NlG}G;g5QSmf4?q;BsuQo`^U|{x}>ACKXRkdd^tU`U+|LS znWy0^S2)LcB@0!EdDt(Vij$36^78r3tM}C?KI}e^X9-D}*M!iFT%zNr0Gf&Ck7!`A>(uLE(OdeRwb4qX3EiMVz=vWC3?2PE%-wA%a1ap0C zl~rRJyzSkY8Ag$Lm-Lq^*t1^}+zs%@8si;z!Aaw5c$|~Vez}RpL6m1>KPeiGJ-kE2 zbc5&X&fJgVtRw*RtiMc#4#s3H)KgHzHqg{R3E#R(bk3b8<&|L5d#($dxdtH$sL)Ko zW+BbDfPQKTs#e36Joca~N!pf`_Le7~Lv03)(7sml@e{h^6)?B<b% z4<^3n;sOFVdZ|+>M(^LPJA^2T?>N`FCB!o7f5xo^osCpJG~aJR*pRaJ`|hF>b2{X( z4aKEJ#QV2I?XR1|0J3}|ZH&ySn!Nm=`P+m<#hI$;xz?{pkF56P+%fUR#QbB?5vU@D z`>PliKDIXEyl0$1ZZC5zk$jU4dGg+)S}VQJ{2eA&|CmIoN#1+}`@$?!Mu3F2+9T02 ze0p5ot83?2=!y%bJ6DW(u9o4&WO$pZ4(odr6?FoB7XL4e)f!oeU;7hCto!x9u^3y2 z_p)OlA3aa{6K=F7$1_8Kool5Rz84;b!W+-X$m#2JgTdGR`~%<5^BB{h$tmHspv zRGNoo-aTFhEpL1CiLM*gJ|XE30ntfqZ6RW8RmFz7r7ZSdo2F`+dbIqX^P95F?^XML zEd;Je?~!LW2b^bUTSOUq6$IdZfuOEh#~DDY>}8&v?k$U}JNqeWBw+k5RaOv)s}jE= zQ}Q=>D-=P$ONyT$s*Ds6LSFrpWZV z9vm@*jijy=tPX3=aU<`d%SuI}+t_(ucyRkiyAE)B^U$L7DbCd`ZfC1GSJ8C#vU2#vSFtvhw(~TDanF;rn!a zWgH2WF*ekmAnI0Qm{vS{Le0(+uM5o()7|2IRkMwT_#?fPo-fNKuG}%_?WB5XSGAlb zor5}ub|f^JD<-m8x~AHfvW<5`F`lhl67hM38YaG)q~vy{D&^Yntrm?>4z^ZOsgY#Q z1rH+LbV>KeLE_&Mx4guoLMo);;h{zA@6Vg{<*=;A?ow0;2nhIdN=lYmb%EU~F+?HH zLaoso&FKfglw9l+vgl0wD}L>5CraD=W3%oYoYELRdWj9p+A0?Z!6LgiDg#Eu>Ssf0 z&g1y!IZG_R=3hb@lHbRp(1j)&W)S7%^q<5B2`lgE5Sih9hn&%pLfAg~&g4O!dAzEw zr6}!RX6}Ey-TL;=D!pNqHJX2g5o#)RC9PgCs$st=+TNbHeB0ziMr46BDXhn3@+9lb zakzM5tAy8y(qP%tE{ZSGapnb4Z^LN!*_y7=s>e||+mVpl^pnes7OO}vC4KH*VY&(u zBMQ9fD2JG^z22EVkkJ~(SO;UACk7d9{ug7_|C8~{@mt)aT#ZU+DQOUbF#6axF}^Fd zmhtBwd{#Y3lNT?|FIsK&gZ~-#n-Y__6Paff`W5$GI_?&4)>Y6wNn%X>=Sz?np7Qyo zZH9g7Vq#S+Wke2_L1>5intVG>$_RV=;j_%`e4O#OwWIFnFw^vf``;Nw$R9Y&G7L@Q zEpjyn?t&uTR?$ToG6e_w*elUbNC~oP3@8{6T6R7*{BS$ppthlyGy84Q%jeFbF-1n> zO)SGM6LD+T;r0urWn8w~gEyVb*0_W98_BXWEHC7aW9+`WLmR`7N+r~9=L(~xq$Jgb zc0`M~DlkIF1Q$x214|&HJK67p$TCg(T6J$4SH->xR%+&~^((0Nxq2lp^|OY^7-4i; zBL#gyG5+ECIpe3%Ik#hK5FP>?%G+Pa7_Z}b`G(asWH1;##`0)}=0g~DiAQ%12Cj5i z28T%p_C$R@L_1|{@r`H-3@utWDI40LfR4i!SA32m0qYI@45{@x~z)w#KlJvgXw}%|m zRo=DGsu9QXI-g+Tl7VIjr}mX;4fZ(YL6iQz z`lznb+}yW8^|YL;n26~KwXN#Dv2^Jf8J;RGE5MC0?77MSdMq!OZES zr@rC*vXhutbr*g#pI;TJ7-h(_N3>Ax$cW*Hvendxf#T2KHpKfFv0s*GVYIHa#ER76 zH)fn1{!z7-v31;4FFC;np`(vIh~mi%Kk6K0qRrbY_10$&xciNpno*F#wFH=MCWkdaFgK=U$FHh6#XJ6e393;9h_D1Zj72KeX!pg_>9E<8*a-g z^}Kf2k*_7=T(WO~W~`LQ`#b^ur_5KjDOs!UUZE)a4ErIxiW)A?ryWE_hQ{K-z66() zy-hd_Wf6g>qeoGlrK;PChpG^jPZRHd1~2MDVv*}eCafA~rLyFEm7f|EuG-#T2SgA< zQulXvo;0LIo^229Q9ItQ+RBrWH?~QpcDh9k(_=n;aXhtJh!9kR$kCNj9kJ=~BEU51 ziIB~(jdq=S3*TzWE4mQ!!I|ecuJydbjIPp*Xw5Ghu@wSqzc$S6Ix+3baF**T>Mt41 zK!k+2I%~h$4?s4Ot~MGVS3+Ob?$pC%AG>el2v|PfPf#)JsHx(Ctgl_0O>zUrPSn=nDj;t;8OUo=NMf=eZW`H&)xh@0RbL zug`wD9%>dDMf!g1Mmbzz7-EO^Yys;ref6{S7=chPEbgzvK3Ygwd;HLVo?}5(#ACVb zWsLd8mLOML?j@oEu`Ybe-Ndygs{ANWu zTYi}_YQ<948Jzmju!q^KwWli0(I_g&4zh3T`JS8oyS-JxRIlxlOkv13y^u$ebFvDyZKo49C5A{;Tr}MGMfceW3vqv{k;$^5ymBa8D>MecFsutjT zA|2ncpoEfZ3}EUt@Ng34X@75@l=LMd z^xZ7gESH4|2|k980z_jCp=#YZA)wxX8X~1diHoFqFvh?^Q;)oZcQ^W-l}yf5-ITM^aKZ zdfcjKlYl-&+8kEemP6lOR$P)7OO`b%yP(T25cq|hroP0p;{1@NydW2?&Uu!(^E(fD z#^%)iOUjTB^}P|c>sOo(_ivgq!yorSoV_H}q{tDvSL(K+bRbh52yrU?;o;#a1$BI; zG0RiGi1qO#MDdZ{{&bK@3)dmD(0ps&@XAgmQ$@l-h4Gx@t|NQC$u0q^d(ku>t~*n- zd~721PFdAKA^EX@ux5Tar!^~Q?kN4Q#)8B>%mcd&9luSEH|o>s^4tryTublkdEEI{ zKR#&=Y~)FcH*t4`M?g&TY~~}M>#}&vt3FYW)XMt2n{6+LCM@Vc2}fP)OONUg_(3`R zRab{`pOc0H4Vwb&4_9$Hs=7gmE~%pp$%I+QRt~Z=N*)eeji{_PhDB=gEL1PPqQmXj ziAC29F0k*5&JI!cBe@oy3-j>BSk^9W)qi|x9siuq!?B_AiaL9Ia3GgP?P`@aa0sC%Vx~ z4_H;|sIZ_baSi_@V?ArUq-+ig)fyk1eXqmTJP^R3h2&8I=PKcQB=1Si$Yi>2^`ec` zWhT-zHa%mNK+fB?4Hfg(dl$9ssVh57orM0LPj=M|2|5Z33$ZS1MD#ToTy?*a5E<)o zZ^vgVRHt{{s?S|cu9e|pBs<_KW^^?c+z zVk*-fa)Av4H$i8mAsYz;V>N#~@y4qSwKG%ox#ZW_-xaK$Fo)u_7H+~xDQI%!Bh|re zEIa^~TT?%8*jT^u!yxl1>%qYTu)I_Iwf#Cm!)=kQd!PDS6W_)FgT0q+ohn_P|7b-8%kc;m zg1^9mPpG^{HSkKoxNcleZ|3O*V?9Y(hvnWYam7N)*3PotcW%Kd$xrtzn4cx+@DGp{ zFPwjuW6B=Zy)W%}`8}SIrnZJ4SEixC`5nMMSLxD`jCML$)Oa|F+)t9}6J=&fRyZ_^ z*(>evV$1-$K&$Aa2X9j!@6ZDeqAYa1l-8b9FTg}aF(uUeG0nO9eI}>KD(22{Y3iez z8sj(PllCVvngk!res$*`DI4Nz8|c28;b3g=9C+P-zJQd-I3R2Rjn*zpn2l7K`Dk-4 zq4GHFR>DRKlZC)XE(X!Rv+KEpkgX@Ph)0`3j~T?RfLQbFSRt^V`+L0ShrurdA)6#R zbvLEIWqYfi#>&qP=f_x+*)14zkd8ci08%!rf(xnWtQ7*>#*Q3lqkb5ZF8F>;{gl*e(oha^!C7JqB6_d~123dt*fdvJq(?6p*0LOR6U zl~o@(cjQPyT3~|OL^gOFW$f2uVn7?jn#?#D74*G0zSOzzEpH3+v@4X!>%a#ZdTNAo z02SDS+U^x)AN~i#!qbx+7~#+diA%C-494h3`5HW7V|SpXT!d-y6K;E6??0eZ_5aM0iGa7jgD1?z-2)tt(?%)HrV0P2IbUwxg)d%!3 z4(Qq8t4L!w^x)eVTb&7NdkTc^eWb9hI4uNo=4Vx(!X0`ZmUUTkqhL%zXoLtLh)Z5V zt{c8kL1$SYHBbFM)7D;w($|K!o|>Tg+asAc(_eT~?!65~_r`GLc;t~??0R+=C$8+% zSU9dXJbLgR#?h~h;~9v{d|1ty%Q<2)Xi_iT>Z%Bt?C^@A1-{?xP6+qny4pNWax8sr zh$_z;Rh0)xfA?_O?hY?gv-D6ddJNR4@Y&jc|MeC)wpLV5P2%7;{EV$#ZcqAzo!qmx z?ntfHdsSvdZRqSGv5P*ec0FDX*}Bmbt}B=gb58YCcP~YrMboq0D&KRi(a*1$I=D`) z(2;{aX$+9#~ce9s7Dc;AlEy)1ge>u4P`ls#tV!AH}{Mrf3Ev0g>k_on;O1VUFJ zja5^PD~MNp_xa--s%kd#tw&d-JDVyx?UVu)d+29O8LvL)y+8u|%P4{5!jguGKBVVX zp!?(Q-W+--0V4ud;Ga3@%BC&Ar4xVyW%TLQs?ySqbxoXLB9 zegDO|`1jpj(`&Du>guZMs^_U@SzO2wiCx{s6}xlc&#oh~?+TXf7P=r0OSNAfr7?9= z+=L&!eF>@TAe>!T(a=TM0@E)Zl#UnR35M&^|&$%M!ToyO7X*>OO8DdjGdIhHXPX z?svWHw5|YD^yy!Ed6saf6-1ZQANVTlA1J0y8BhWitD!fgc0O*ZogU?W{Bt5=|3G*4 z0jq4((3_~e7hRJuRM`){U|z**Fm`udnq^RoEE9-!$k5NS%TzM(uPX~_hfO9JTpe|K z%R@gT`}pR!(lNGD0G4yAhj zMEi$N{5aLE!7mDWy`(!%x!PN3{hv3%S)|U`OK02zn;mkigLW|8Cqk||nYC#RM3piP z1hL@Q<|b|GXjZHE1wYf7mwb8HTsHNp&aOo8IRTPw{J4rdTvT7LGO=6`h|uC8t^tE^ z2nXn^x%`~8UdLhe>F%x^KudaWuj^CIgH|`GNqTS1huhCeAzR|zcVN*+D^GZvg@t6{ zt%Jlv;t+k^cO{`*Oyu4vy&A6z3MJqkIX9c1AKljGEZooh3;N(+_BT<651L-I+e8z) zJj{Ug6s~`2z968B!3)qy`JqVw0XcMz?Z)C-ni;Puf&MR5s_EUj`9^N zc;)D0ekKK2F19`-g_u62@O@lqzi$?uQmFd1QaNobI;MW=A>yG|U2xA+(&{n4;JspG zJ-vAO_MWK+!A_SoceK(e*pjJyX<)UFz?T`Y9-H}d$jADsFSt4t`-_TXMgbZ8=s-uI zN}uEaz=#(l8|*5;4k$FC@p&!SWuo}TbavOrfL;Xic}AxxdwTfr^OtTM9$#(&gBgL1 zCgRm~-OP9kaZ(%GS-8HpsZuFAHf+g8Ui_asA_>2N z{}WoY+y{;)wte$I9;{JE2LYtY*L*^DeR{mjQxi_YwYJXSbXjlVYbWV!4!n?iElyk& zy^M>mx?ICf@W0anrFqwS(ZZjxm2p{Ct18%;%=`5whuQRB?n4Dp#-@jXfH)`T4>T}@ z(>zL!clT~7L2ehKJ&TDg2W)5kvy+LcyuryarP5q}=lE*g1$Wvc=HHClGs`X=cHYVQ zV}5aV#pFaKx{*62j~+E^{o=!<`%)BcQ1;0AmTT>}S>h0q=-1Jorgo9}7wS1Vyu?Kz`8EX1p_-4{J;lNJ2x?N3deQ?__Q4X`u)~;kVttI`SSwqY})U zf!AS6{dh$TKArl?Vs+3KubJMLAtooil(z? zH&-|YJnm*^mH@3dxDfSU*-TRgaxN1LCP6qu6!CF@J3Oh0=h9*XU1M@+6Ladmu>#JL zivIKXm3}!-e;8OYA`>woR4Cl#xB3fxB-`Hfqdc^pNib+J^$P$`DP<2hsrEp}I zQ_(``<1Ijf%natpKc5HM-Rbhu=J%eJL$8^zKwH{4agt`@cU1m zpuThV^OMMoOu|w6wC==YEgygQfoIad0O`QgblvY9_mqR|jApUcdy(Lkr*{YU$F~Ua zvVw5Wf>5GNfOcC6tG6U_>qy0qoKn(JYXY~@{Ms4=6*zcF8aRn@6ME~GsrJ;*92N6^ zY&>yh34%;EV*Zw;eUAUiZ&wupmR#g{_0^$e6Jn*c<*U&c;U$E65sQ5)%m&SUYzMv% zL@{=a8s{6R;#~Aq!_0ZP+Tc)HXZ5ttQ41tW7Sc)-6RcWb|JVmk8IeRFVEm!eAw1hE z38h>Y8j7T!0u5>#PY-3{)X9)G95$Wv?EN>(`ptIATg601g<1x!fptG-rH!E8_D@^y z1dNbQ@fN$x9!1XHW+PoaRWA7IS^)5E@W13I|A?-6U)7!w%dBI^uO*pI%56K)#`Thv z-ykObUb-b&0wAUMakr6}NE zsL^B24*0tdMdL@1LP5fH`2~=$lzpVC69|=}~RgpfhWupn~ZWk?Y`?*YnkT_6$PAm99BukW^KI)qfJ>l z7gXMiPUofoC9Bro+CW7mC0xY!TbAfh0b1`nTbEap3tQFSf^P~N%gc}L-aK4q7FyV7 z-@5mo0)~jBS5zmee1R-;UOJh> z6|SRB=#IA`W&$$?_C^Vd&&Iv7(>d?yU;US>%S-BE#sGTl9D^{`XhF(sl)+s)nO|&? ze4$V+tST@VS}vAD#eC`K%Zkygf8sG>Pkk)Z^}zOVizMU#CQ8@4t$~e;W)dyD-enef^M{H?8TfvnQ52E(dj(=QWa6&O0Hv@R6& zpj@3*{UYB9a;QNv9v$&h2&FMY3{H@X_2m2D0qm|zED*}8veH-axyoutqwF+`s)m|j zar8t1hZeL@p<%kzlZ}vgS;u%!PwYlakwmV{6rHdH6q~lQx|_r;Y%Ugs)4647*q_6- zwwzIk*Nalst^J^^%Bw8uzG*yzsz3`;;iL@i*opd5c?gEWnV1H?)A63{rHAr_EeJa! zvLVTlcpd~f@!0}a1uC}NP)0oLH_psD)Bjj%z?;CVe~Ob-vUkv+@w|UkHrAF6MB^bW zXERG#+UDPn6}LdfiHN*L4Y63-QVWLf!d<@>3DgG5QHbSQ0JwNPO~03wt&=#W40a`s znR6ty-#LlsAr&j8WQN5p%Z(NJ26hwHL~*DZ#|M_0tKqlLJC0TPJ6p-04~_mvsh2yJ zcF|vIuCXa-`NLj43JP}KqP;}qDCMonly(h@e*0Mh66D5NoA6m#T_!NLI=5w|`!(Ki0SOZ$ zAkviwBa7y?yDKq$8j(Iryu&3z*5dMo_^O$^eVtYvG5y>wBjjSkU=jo>qer@qPsa{4_M z(Xibqwva-z)kVxKEJq4Xr}L8~Cea8ByVGjJxFPv1my_RMIXt})#m?ixGH;vQLnGs& z(%FW1e$SO?YtGfHiyh}F)3FgT*q%X`S4URO%=#xn@3tOVYJ8{~sR?|^irvM{_V*at zT}D$9Hho10>?JS#r@W#HExX0O;Wi%j-mV4;`RymI_fb#wWcsYLnJnWd4+R zQTCq409!kbtSIN$TtcWjf>tL_i%h(cneO6VujA%+V$YUuQNPitngyJsBYmT?m*Ew)fQL(Vb{TWhqd;;-aCMu8Jqy zw2Yd4`Iz-T{h?>b=3Q-OxR>m>!p8lX-+x@r`JYI8mIyx0sOg>cvh<4&)gh4hba2An zmR(mU>;-6VwQc7Xa@K?Gzs5RDL)+B7sH@|A+w)j!YwDZLn}&KJI*N59c#fg7>AE=i zINsqY>+;Z6qnqY*iv1VLEcom0AhDH{^4ovv?*(W=TKE((gi)J1#w**@D^sPqAJ0Z^ z$j~1H?&D{nlhjt!m+STEj0Qt@%!(D8{b_$=V*B5$ zHD`O^3SIt%ifHf~oz})(b3JpS2zs40H@I9~Uii*uhH}v@Y~*(dvxFpw zA+1~<>mw=oBLbi^HIV`mbpE*1zc|AKIGkV{vP6dakoiot8>A z4!wuo%14@qFmIw*7bgnXj!kmRyL%p#H&@EfeAD#S@6H6OJ&LhiV{HA!) zQ8Y`L$Bq9Tg)GEP$gy?S^oPqB1^qt zJMHL~Uk18aQ&>09jAbl$r2d*J!NI)XdVmo{RWDpYz_TPN^D#*p!zvS2^PUf-Z`G5nB9L zSnclzT+*fn7R5oMKo14@r@pE`I ze3}FQ5~U+Xv;woLD?&R1@SMdKn`3N0%}d>SwkoGzP}bmzboU+(ZNONteR?hP#JA9zYRE}5ryhmi9r+hJ}$VsJ66eF~hT_rk;{+D>g#GN`L(iD)H$%URv4H-v_z zS8NRLobH1LD(Vn>O8?W?juDIdbm`_;YC+B)1Uot(VJV@yVyEpYT*ztMXMPbjVW8}s zm5yBhVX3%jNNmB6FX15?X~x&$8R~&CKro?`7e;CJVecI@#=9J?J&k1Q^zj%F84qTP zbPUJI4atIQxEPyO2mpT|-1O;d9>CnVUAH11ws;v8$ccDV}ac2<q3&_&!wTy->U&lk5cVKJxb9R0Iig(AXDxJKGq4N#1xnY{BZl`vUHL;ndgi>@XYSTCgUxaNIFXF0C@0)X7TNicC_GjvQ ztr@xX9n#fJzpT7HS-e#ry?SurQZh;zH%PMWs>_Q+ei|7D16dA89Ot^8%zgP*V-v;V z=UU|U2G|-D8cN~^u(ut)Rh_yuZ}zoAT;cspnTQ{#fT*Eg*#53NQJgvbq0%VMGSDbB zpb12ox#9fUH9M8l()~6kFyoVTD4>7o((h*{n^hL83_%gyHLpBs2$HvORIcz zeCP>s?ytt!8_cs@Kg(fmNgZDKmHV0dwaV7N6|UkBG!>1)20n)#j(JYa%t$>0zji+} za(I*i?l~5PWHk;{KLKT^rnEG~8l^h^YHg=X0+8S;iFhD;M&s5W?zLD*NAI+~f6yf} zKsOhU;09vj)lK8lKuBOASqSsTD7D-#En9kwA@-+-bRERwB3TUftK_4_Gm?`W+rJ!c z8V*JIk;*wSu&`-(aKZz7DE<=O?H%1}`%`rBr zj`aar@#AMRq6?B}^4GFhz(Rlf(G}q@E_-E(N2^4H4!m)stH`W-#k?bK%{74=H4{x? zB6Sf18yibRl+kUyIyX#xSlTo!%M^xGb_^_!6y?X^k$#TFQI(WqH{T2PZMF2=p?MaK z2f!Y}ERcH7vn^|tZDLR;0H-Q^tbyZ?G?7UlIkYr6KLrPnMT&w8A=at-$*^CUQv$la zp*9NVcNaT)Z4*HU@}|f)v~;r1TiNK{CzI(r&Ce|YW^v0?QWB=GA|{?GZx%-c9-R17 zFIQ(Ho+B8)3+Qc6%zd&1h6YkP-6YVeQyuPFU$C)p3rLVssmFk34c79jC=rG=fH_L} z^Y#K1?Mb0x)=!J||1f;^50rWdxXAD`3LnH{VPjo8ZIU;CtkU)`gRuK(SmaFPNsB?h0arwM+5SUmvL&Q%t z85E>Z5&~)b2YQ3}A8^Anl4O#Q@7JY9uv|(8MfPz@rOe0;uCAy?;gwAQjVi0yGES_p z?h;`bIU-*q3wf!=5{2HAS(DdEVOAT5ktuKFsN8)J)Y{zvD( zr(Est_{Q#>jx-F`7Sx_j`{92xv^}bPxiykDTFQ7~dhc4A)ww_DiR`WAxzl>{`o9N( z23n=16>qh~Uek0wAtr-93J#q}{)OT_uu%z*yL|am1DU7rKoo%Cg8&XS^;dh8k40{m zE=(7&Eip3z6LBvq!&2ENm480+ewx!>8(vQr6mXVD_?ehccU1DFeJ7Q2ad{f(;^Fkv z_~G?yb;CeO%B=tU3D!-NNs+Yg+aH!2&dZYQMC~r|yH+W)S$rG*8rtKGb#O3CEpl^1 zSh5~E6-$!GS;vmz1S#jKVxJn_e|1i^#X3hK|2)_+Kg3m46!vITR(~Ad3(8S4wzuY( zA;t(*RNzdUbA{*q60*myOKCfZ zSSAEwT-~zu*X>h2S~ZU{TrIutUC)Y4){tO$t$tCTRF~NRP*E=~Y~GJ|U90UU14#;S zGlsxY?~zzZ-Q~ECZxsCiarmZ3iQd5$o&UJZ{ze1gP*l`P|}5>3^b#oXr3*IAUlL2je^D^~`l@z_vZ0u{S%M$&)aS*Ij! z-hNtY`2m7T{0c%9|7%sFe=RsVD`#s|FqQD7t3d;di(Lj|YHU}Qc*d$<$J=VPXT>6B z3OU;=WJVhDIq*|VAFqnsn}13D!LHm&D&u8PG(5yyF{(^`e(D=p=Oq90U*n3qEJ&2G zpti}lu$a4dBmQsh1T1Hdtcc{D~%)d5FjW%D3q_w1^wDc{5;~1iM3c$bb ziJQs-Loo06jkNuWrh>(DsmpA1L12D+XMxS{ERq)f@ZtAINzybplW5i2;}=KW_=G3* z#>w(6BIiecp~@#>B+daN?Ao??)o#UGYVLxg&$*(b>wsS7=$Wd=@Z7&p@^8}U3e}2I z&g_oikS81WguVK^CTR-3(7l#(1>}LSVCd>55Y_z~W@bYElp0Mq%K~P51c>4+RYI}# zpHXYgig7oHso2kqR5CT>4Vog>TkDZ1;`D_O$+AiB30ftzWGbmUT>wr5G@@Rc3$vp% zwdPLsKfcn3JmVIMPKP(X+q4WaR%_kR*l_QkFEq(l06CN)lu03-g|Ut+8I`MPPiltK zUwhM@^z=`bUARfFT!x4ff^N_3hREaZ#Iedfq2eVISz$jaT$2!k3k*Sw^Pq(Ou-M_EdYrJSmwf?&JJNH!_h z-&nn%za86-q5g$ZFcdR-`E&#G7iw-Pp71@j%fI)|O_)H9>d{R@v1Bk4E3&^lL&z65 z`3F^p>MQ_bmEhhsR+N8LEp|bjUJVh#-Cctu^UNw-{z9>z=PvyT{0n6dp>%6tLBT-7 zKyHLUMngn^hlhsrkbr@O!iK}b!KDO>Nd?+E=P?XvLpD4QvuD;_jeuoU_ zdTp8HsN%CkkDWX31pK(5KTPPoK)qkZ`gd|CNDHIW1XVYb9qXU(_}v9vU!H=*47UB$ z*$cZhOzSf#glqL0HAK2;FZCmX%5-pt!mg?>kr_5M^hu1!>8{L`ol;qZV_Sc_sY|nNi*)U(D*Xv7rj{`V!YA62maFW)Vpu|rqFC}$p5&0|Kpp+-+8Wlgw7 zAQZzc&Ci8mdQQset|dG**wvXDu|ml7hKXO9efs42=9dusiH~G#^M#Gy=eC?4R@ov1 zJ4fKK+_7vJ^)Y9!;xZ1Q*AJQ^e%i3HQ>76`>C+u*zSGf7?4W9w6AiS z{*B=>e%(MRyo{x>>`#_6pxkvxuG8H92y^(dkWbd2AiqI5D9!~#X1t&74A4Q;@x!ag zp(~3(KLdM(*s1MVeb+jg%F1G^u=x|=$zPwK)g zuZVuc^RjBB{duk~!{6{nx4v0l@&8dulgc(YTL!P)2I^c*(#Sy)T}E_xO={>vLE9fo zDS4r6X);W{Vubd45iK6*n)ezQ{>a`P{wico?6@lm<1yl1o3|Ird6>Eiwa>$xDl8fA zjFw0y=?Jh2N4W_EjGemBg!I%smb8Z&vox@8d5*|s339AStKf9EMUadr{cmY}9+3(N zB&YiZ2dLxFALeEIWAE3eLmUBq0k!jVfbnGdUU*0dtk+NxCF>hZYhmMrhX35)&ki5< zRKD=;(}eFDD6zICwOjjo4(3+Z*o*>q=Yy{~=hZp+cPw}Xfbu`v?hL+OCj}}k3%CN^ za&G0;z4*D?xv86kMhJE3+F1A(Y@h56I#S7q>L}JoPw^k#(hfA^eKQp)8ctVr;tQX5n(wuC4>kK@S(aHHUirpOekHpjGJxdjR!jmLzfy*fo- z{YS#~|0H|~_wJGwD7lOeKu`C~?!x~wqfY|UO?@^=h36)OWMaxhtSi22FgnLc9Q@^A zd@C#cd(B!UK~Dqc&Nzx^p`@+1GFUDZtKdv-1(Cld;55%WQWuXVQu81wyEm8a`^$|r z?Ipi{w-@&=Mfk^jBH$!fn64N-@Z8Lik7PGy(9K+WT7BmMe-ehgUTh67LNl(+e8(86 z28`2V&HTG8o{C|uf(1dE(9#qNHaR2FS*?|Wr1p4xkn)3``BsuUh5?#^Ro5J!p)xv~ z64E&ugeoFvk8wDxv0+UE(YQFf|DkZ13t0&&sP%UT?*fV;+c`sJtj(WV4rR7S*OR!} ze4;W@_5(1%`E^C|MShYGaWHW$zgFPjV?ys|zw^u)|mp zzZW@8AK3(#)WH~G<;aq4UyCnJPZjD`|KPIx3zcGfApP~X&2xa+8MM(ojn(Popz(Qh z7LG&zWPViDV}{J>c)!JXK3RV9G|@|#S6)(M^44FdY@Zo?KI^^N>16@>h=gV5YxNKC zt%4U8djc{e>f-tJ=JpK#?4uW9#L)@1iZN!!>c`KH41fNk0y}{qA^&mO_5+Xn-sN;{16^U3|i^_$7(e>3CjR*S7Qh z-mmCR%`tAs|zS#Rkr16}7&uyK*XNwU$%GAwx$C8-|d_cgGnyx0WU(pT3CT!&mTp zWBoGJqLPYmBJ>c^8d`?a<_E??^-Ti@hT)~TYLICauV8jGC#<8)4ii}I{b#p$82XoN z%5mXx5|{dBy}@jMw$WV230l~>3h42FD;|c-XS_dbGEtfX$+wxY21XHsb5V68*q&geyI&{ zy*^xJUJ9U{Q$06$n$w_}=ecFqIxIwAw2+E_F(m=sH< zPMV=Un^53GazGVHYZQPz>+7va$>6C6!_XiuUQee(~nJ_cz!L9acq+1SWfk&Z+1iAR*D_6J*f1! zQPQ7tK(uHUane||)U8SSB$Dfl2s{4q4Hd=-x1B;G@JI4@f-V%60@uF_Q2$0>Qimm zs5YcBp${DH<$NXM=zy(r?kI7@oD~dpszm+>%BXCTSm$U3u4j)`1j1Ua9P_ms^?zzAxdspPHo>g%$ZYb`dF-ZNrrx^6Mt4KiV>?b0pL)nYE~_ zP$NYeGJGE%|B*; z360 z=oF>sY+arM$80X*tGzsw7EB*>n+4SniQp>A$lxp75~+-xSL~p^JiDx2V-V3xY@;$O z%NdIb#SY#8v#?`ld6Tg{OmAq?i@GwZP~S=LWiP-DO2 zfPQfik0+e)UhF2jS_}+b2F1xi5y*zbJ#vULGVD8G8!5#cpJ{*>FEGjEQ~`dQ zcOU0y^v1QfPn5adbKorrTEV`n1jZ+_CsbJ?7Kr{!{MaVr<5I+;lH8( zlWWm?@-3xS25%g{URt*s)5O45P+KHTQmBiS5l41G*l2XM69dicDjS8R&7MI?rhX$| z9OeEVX^1FAvg=?cGlm5GH&pt&yd*=Av8$S^(AY%ltYRug)@W2>D^WA(SW;|dj#Bb* zPY9}ZL!MjVzPnal92|C{3IUIgvC$FM07?EV&8XVOsA2{>=keTXV!WOswB5r0g)(
sH`pxVp$E*LSx0bY$^ho1gZ(Ce+BX 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 fgzs%Vr*-jYG(YMS<ttdtee# diff --git a/apps/docs/static/img/docusaurus.png b/apps/docs/static/img/docusaurus.png deleted file mode 100644 index f458149e3c8f53335f28fbc162ae67f55575c881..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5142 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 F{0H{b<4^zq diff --git a/apps/docs/static/img/undraw_docusaurus_mountain.svg b/apps/docs/static/img/undraw_docusaurus_mountain.svg deleted file mode 100644 index af961c4..0000000 --- a/apps/docs/static/img/undraw_docusaurus_mountain.svg +++ /dev/null @@ -1,171 +0,0 @@ - - Easy to Use - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/apps/docs/static/img/undraw_docusaurus_react.svg b/apps/docs/static/img/undraw_docusaurus_react.svg deleted file mode 100644 index 94b5cf0..0000000 --- a/apps/docs/static/img/undraw_docusaurus_react.svg +++ /dev/null @@ -1,170 +0,0 @@ - - Powered by React - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/apps/docs/static/img/undraw_docusaurus_tree.svg b/apps/docs/static/img/undraw_docusaurus_tree.svg deleted file mode 100644 index d9161d3..0000000 --- a/apps/docs/static/img/undraw_docusaurus_tree.svg +++ /dev/null @@ -1,40 +0,0 @@ - - Focus on What Matters - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/packages/sdk/README.md b/packages/sdk/README.md index cb06600..801562e 100644 --- a/packages/sdk/README.md +++ b/packages/sdk/README.md @@ -1,200 +1,16 @@ # @verbeth/sdk -Verbeth enables secure, E2EE messaging using Ethereum event logs as the only transport layer. No servers, no relaysโ€”just the blockchain. +End-to-end encrypted messaging over public EVM blockchains. -## Features +### Install +npm install @verbeth/sdk -- **End-to-end encryption** using NaCl Box (X25519 + XSalsa20-Poly1305) -- **Forward secrecy** with ephemeral keys per message -- **Handshake protocol** for secure key exchange -- **EOA and Smart Account support** (Safe modules, ERC-1271/6492 compatible) -- **Fully on-chain** - no centralized infrastructure - -## Installation - -```bash -npm install @verbeth/sdk ethers tweetnacl -``` - -## Quick Start - -### 1. Initialize with VerbethClient (Recommended) - -```typescript -import { VerbethClient, ExecutorFactory, deriveIdentityKeyPairWithProof } from '@verbeth/sdk'; -import { Contract, BrowserProvider } from 'ethers'; -import { LogChainV1__factory } from '@verbeth/contracts/typechain-types'; - -// Setup -const provider = new BrowserProvider(window.ethereum); -const signer = await provider.getSigner(); -const address = await signer.getAddress(); - -// Create contract instance -const contract = LogChainV1__factory.connect(LOGCHAIN_ADDRESS, signer); - -// Derive identity keys (done once, then stored) -// Also derives session signer key for meta transactions -const { keyPair: identityKeyPair, identityProof, sessionPrivateKey, sessionAddress } = - await deriveIdentityKeyPairWithProof(signer, address, safeAddress); - -// Create executor (handles transaction submission) -const executor = ExecutorFactory.createEOA(contract); - -// Initialize client -const client = new VerbethClient({ - executor, - identityKeyPair, - identityProof, - signer, - address -}); - -// Send a handshake to start chatting -const { tx, ephemeralKeyPair } = await client.sendHandshake( - '0xRecipientAddress...', - 'Hello! Want to chat?' -); - -// Store ephemeralKeyPair. you'll just need it to decrypt the handshake response! - -// Accept a handshake -const { tx, duplexTopics } = await client.acceptHandshake( - handshakeEvent.ephemeralPubKey, - handshakeEvent.identityPubKey, - 'Sure, lets chat!' -); - -// Send encrypted messages -await client.sendMessage( - duplexTopics.topicOut, - recipientIdentityPubKey, - 'This message is encrypted!' -); - -// Decrypt received messages -const decrypted = await client.decryptMessage( - messageEvent.ciphertext, - senderIdentityPubKey -); -``` - -### 2. Low-level API - -For more control, use the low-level functions: - -```typescript -import { - initiateHandshake, - respondToHandshake, - sendEncryptedMessage, - decryptMessage, - deriveIdentityKeyPairWithProof -} from '@verbeth/sdk'; - -// Generate identity keys (two-phase for when Safe address isn't known upfront) -import { deriveIdentityKeys, createBindingProof } from '@verbeth/sdk'; - -// Phase 1: Derive keys from seed signature -const derivedKeys = await deriveIdentityKeys(signer, address); -// derivedKeys.sessionAddress can now be used to predict Safe address - -// Phase 2: Create binding proof with Safe address -const identityProof = await createBindingProof(signer, address, derivedKeys, safeAddress); - -// Or use combined function if Safe address is already known: -const { keyPair, identityProof, sessionPrivateKey, sessionAddress } = - await deriveIdentityKeyPairWithProof(signer, address, safeAddress); - -// Initiate handshake -const ephemeralKeyPair = nacl.box.keyPair(); -const tx = await initiateHandshake({ - executor, - recipientAddress: '0xBob...', - ephemeralPubKey: ephemeralKeyPair.publicKey, - identityKeyPair, - identityProof, - plaintextPayload: 'Hi Bob!' -}); - -// Send encrypted message -await sendEncryptedMessage({ - executor, - topic: derivedTopic, - message: 'Secret message', - recipientPubKey: bobsIdentityKey, - senderAddress: myAddress, - senderSignKeyPair: identityKeyPair, - timestamp: Date.now() -}); - -// Decrypt message -const plaintext = decryptMessage( - ciphertext, - senderIdentityPubKey, - myIdentityKeyPair.secretKey -); -``` - -## Smart Account Support - -Verbeth works with ERC-4337 smart accounts: - -```typescript -import { ExecutorFactory } from '@verbeth/sdk'; - -// For UserOp-based execution -const executor = ExecutorFactory.createUserOp( - contract, - bundler, - smartAccount, - signer -); - -// For direct EntryPoint execution -const executor = ExecutorFactory.createDirectEntryPoint( - contract, - entryPoint, - smartAccountAddress, - signer -); +### Minimal example +```ts +const client = await createVerbethClient(...) +await client.send("hello") ``` -## Contract Addresses - -**LogChainV1 Singleton:** `0x41a3eaC0d858028E9228d1E2092e6178fc81c4f0` - -**ERC1967Proxy:** `0x62720f39d5Ec6501508bDe4D152c1E13Fd2F6707` - -## How It Works - -1. **Identity Keys**: Each account derives long-term X25519 (encryption) + Ed25519 (signing) + secp256k1 (session) keys from a single seed signature, then binds them to their Safe address via a second signature -2. **Handshake**: Alice sends her ephemeral key + identity proof to Bob via a `Handshake` event -3. **Response**: Bob verifies Alice's identity and responds with his keys + duplex topics -4. **Messaging**: Both parties derive shared topics and exchange encrypted messages via `MessageSent` events -5. **Decryption**: Recipients monitor their inbound topic and decrypt with their identity key - - -## Security Considerations - -- **Forward Secrecy**: Fresh ephemeral keys per message provide sender-side forward secrecy -- **Identity Binding**: Addresses are cryptographically bound to long-term keys via signature -- **Non-Repudiation**: Optional Ed25519 signatures prove message origin -- **Privacy**: RecipientHash hides recipient identity; duplex topics separate communication channels - -โš ๏ธ **Note**: Current design provides sender-side forward secrecy. Recipient-side FS requires ephemeralโ†”ephemeral or session ratcheting (e.g., Double Ratchet). - -## Built With - -- [TweetNaCl](https://tweetnacl.js.org/) - Encryption primitives -- [Ethers v6](https://docs.ethers.org/v6/) - Ethereum interactions -- [Viem](https://viem.sh/) - EIP-1271/6492 verification -- [Noble Curves](https://github.com/paulmillr/noble-curves) - Elliptic curve operations - -## Examples - -Check out the [demo application](https://github.com/okrame/verbeth-sdk/tree/main/apps/demo) for a complete implementation. - ## Documentation For detailed protocol documentation, security analysis, and improvement proposals, see the [main repository](https://github.com/okrame/verbeth-sdk). diff --git a/plan-pq-metadata-v2.md b/plan-pq-metadata-v2.md deleted file mode 100644 index a6628f8..0000000 --- a/plan-pq-metadata-v2.md +++ /dev/null @@ -1,366 +0,0 @@ -# Plan v2: PQ-Secure Metadata Unlinkability (Meno Invasivo) - -## Obiettivo -Stesso del piano v1: eliminare metadata leak per avversari quantum passivi. Non ci interessa migrazione. - -**Vincolo aggiuntivo**: NON modificare il contratto LogChainV1.sol. R (responderEphemeralR) deve rimanere utile. -Non essere ridondante con i commenti nel nuovo codice. - -## Le Due Vulnerabilita - -### 1. Topic Epoch 0 (VerbethClient.ts:338-342) -```typescript -// Attuale: solo X25519 DH + salt -const ephemeralShared = dh(mySecret, theirPublic); -const okm = hkdf(sha256, ephemeralShared, salt, info, 32); -``` -**Problema**: Un quantum attacker puo derivare `ephemeralShared` dalle chiavi pubbliche on-chain. - -### 2. inResponseTo (crypto.ts:162-168) -```typescript -// Attuale: solo ECDH -const shared = nacl.scalarMult(rSecretKey, viewPubA); -return finalizeHsrTag(shared); -``` -**Problema**: Con R e viewPubA entrambi on-chain, un quantum attacker puo calcolare `shared` e linkare HSโ†’HSR. - ---- - -## Soluzione: Tag Ibrido (Mantiene R Utile) - -### Idea Chiave -Invece di rimuovere R dal calcolo del tag, combiniamo **sia kemSecret che ECDH**: - -``` -tag = H(KDF(kemSecret, ECDH(r, viewPubA), "verbeth:hsr-hybrid")) -``` - -**Proprieta**: -- R e ancora necessario (per calcolare ECDH) -- kemSecret e necessario (PQ-secure component) -- Un quantum attacker puo rompere ECDH ma NON puo forgiare kemSecret -- Il contratto NON cambia - ---- - -## Refactor 1: Topic Epoch 0 PQ-Secure - -**File**: `packages/sdk/src/client/VerbethClient.ts` - -### Cambiamento -Aggiungere `kemSecret` come parametro e usarlo nel derivation: - -```typescript -private deriveTopicsFromDH( - mySecret: Uint8Array, - theirPublic: Uint8Array, - salt: Uint8Array, - isInitiator: boolean, - kemSecret?: Uint8Array // NUOVO parametro opzionale -): { topicOutbound: `0x${string}`; topicInbound: `0x${string}` } { - const ephemeralShared = dh(mySecret, theirPublic); - - // Se kemSecret presente, usa derivazione ibrida - const inputKeyMaterial = kemSecret - ? hybridInitialSecret(ephemeralShared, kemSecret) - : ephemeralShared; - - const deriveEpoch0Topic = (direction: 'outbound' | 'inbound'): `0x${string}` => { - const info = `verbeth:topic-${direction}:v2`; - const okm = hkdf(sha256, inputKeyMaterial, salt, info, 32); - return keccak256(okm) as `0x${string}`; - }; - // ... rest unchanged -} -``` - -### Call Sites da Aggiornare - -1. **acceptHandshake()** (linea ~185): passare `kemSharedSecret` -2. **createInitiatorSession()** (linea ~237): passare `kemSecret` (da decapsulation) - -### Impatto -- Minimo: solo aggiunta parametro opzionale -- Backward compat: senza kemSecret comportamento invariato - ---- - -## Refactor 2: Tag HSR Ibrido (R Rimane Utile) - -**File**: `packages/sdk/src/crypto.ts` - -### Nuove Funzioni - -```typescript -/** - * Hybrid HSR tag: combines KEM secret (PQ) and ECDH (classical). - * Both are required - quantum attacker cannot compute without kemSecret. - * - * R is still necessary to compute ecdhShared. - */ -export function computeHybridHsrTag( - kemSecret: Uint8Array, - ecdhShared: Uint8Array -): `0x${string}` { - // kemSecret as IKM, ecdhShared as salt -> both required - const okm = hkdf(sha256, kemSecret, ecdhShared, toUtf8Bytes("verbeth:hsr-hybrid:v1"), 32); - return keccak256(okm) as `0x${string}`; -} - -/** - * Responder computes hybrid tag. - * Uses R's secret key for ECDH + kemSecret from encapsulation. - */ -export function computeHybridTagFromResponder( - rSecretKey: Uint8Array, - viewPubA: Uint8Array, - kemSecret: Uint8Array -): `0x${string}` { - const ecdhShared = nacl.scalarMult(rSecretKey, viewPubA); - return computeHybridHsrTag(kemSecret, ecdhShared); -} - -/** - * Initiator computes hybrid tag for verification. - * Uses viewPrivA for ECDH + kemSecret from decapsulation. - */ -export function computeHybridTagFromInitiator( - viewPrivA: Uint8Array, - R: Uint8Array, - kemSecret: Uint8Array -): `0x${string}` { - const ecdhShared = nacl.scalarMult(viewPrivA, R); - return computeHybridHsrTag(kemSecret, ecdhShared); -} -``` - -### Perche R Rimane Utile -- `computeHybridTagFromInitiator(viewPrivA, R, kemSecret)` richiede R -- Senza R, l'initiator non puo calcolare `ecdhShared` -- Il tag dipende da entrambi: KEM (PQ) + ECDH (classical binding a R) - ---- - -## Refactor 3: send.ts (respondToHandshake) - -**File**: `packages/sdk/src/send.ts` - -### Cambiamento (linee 173-176) - -```typescript -// PRIMA: -const inResponseTo = computeTagFromResponder(tagKeyPair.secretKey, initiatorX25519Pub); - -// DOPO: -const inResponseTo = computeHybridTagFromResponder( - tagKeyPair.secretKey, - initiatorX25519Pub, - kemSharedSecret // gia disponibile da encapsulation (linea 187) -); -``` - -**Nota**: Bisogna riordinare il codice per fare KEM encapsulation PRIMA del tag computation. - -### Riordino Necessario - -```typescript -// 1. Handle KEM FIRST (spostare prima del tag) -let kemSharedSecret: Uint8Array | undefined; -let kemCiphertext: Uint8Array | undefined; -if (initiatorEphemeralPubKey.length === 32 + 1184) { - const initiatorKemPub = initiatorEphemeralPubKey.slice(32); - const result = kem.encapsulate(initiatorKemPub); - kemCiphertext = result.ciphertext; - kemSharedSecret = result.sharedSecret; -} - -// 2. Compute tag (now has kemSharedSecret) -const inResponseTo = kemSharedSecret - ? computeHybridTagFromResponder(tagKeyPair.secretKey, initiatorX25519Pub, kemSharedSecret) - : computeTagFromResponder(tagKeyPair.secretKey, initiatorX25519Pub); // fallback classico -``` - ---- - -## Refactor 4: HsrTagIndex (Matching Ibrido) - -**File**: `packages/sdk/src/client/HsrTagIndex.ts` - -### Cambiamento Dati - -```typescript -interface PendingContactEntry { - address: string; - handshakeEphemeralSecret: Uint8Array; // viewPrivA - MANTIENI - kemSecretKey?: Uint8Array; // NUOVO: per decapsulation -} -``` - -### Matching Logic Ibrida - -```typescript -/** - * Match HSR to pending contact. - * - * @param inResponseToTag - Tag from HSR event - * @param R - responderEphemeralR from event (still needed!) - * @param kemCiphertext - KEM ciphertext from decrypted payload (optional) - */ -matchByTag( - inResponseToTag: `0x${string}`, - R: Uint8Array, - kemCiphertext?: Uint8Array -): string | null { - // Fast path: cache lookup - const cached = this.tagToAddress.get(inResponseToTag); - if (cached) return cached; - - // Slow path: try each contact - for (const [address, entry] of this.entries) { - let expectedTag: `0x${string}`; - - if (kemCiphertext && entry.kemSecretKey) { - // Hybrid matching (PQ-secure) - const kemSecret = kem.decapsulate(kemCiphertext, entry.kemSecretKey); - expectedTag = computeHybridTagFromInitiator( - entry.handshakeEphemeralSecret, - R, // R e ancora usato! - kemSecret - ); - } else { - // Classic matching (backward compat) - expectedTag = computeTagFromInitiator(entry.handshakeEphemeralSecret, R); - } - - // Cache for future lookups - this.tagToAddress.set(expectedTag, address); - - if (expectedTag === inResponseToTag) { - return address; - } - } - return null; -} -``` - -### R e Ancora Usato! -Nel nuovo matching, R serve per: -1. Calcolare `ecdhShared = ECDH(viewPrivA, R)` -2. Combinare con kemSecret per il tag ibrido - ---- - -## Refactor 5: verify.ts (Verifica HSR) - -**File**: `packages/sdk/src/verify.ts` (linee 263-270) - -### Cambiamento - -```typescript -// PRIMA: -const expectedTag = computeTagFromInitiator(initiatorEphemeralSecretKey, Rbytes); - -// DOPO: -const expectedTag = kemSecret - ? computeHybridTagFromInitiator(initiatorEphemeralSecretKey, Rbytes, kemSecret) - : computeTagFromInitiator(initiatorEphemeralSecretKey, Rbytes); -``` - ---- - -## Riepilogo Modifiche - -| File | Modifica | Invasivita | -|------|----------|------------| -| `crypto.ts` | Aggiungi funzioni ibride (mantieni le vecchie) | Bassa | -| `send.ts` | Riordina KEM prima del tag, usa hybrid | Media | -| `VerbethClient.ts` | Aggiungi param `kemSecret` a deriveTopicsFromDH | Bassa | -| `HsrTagIndex.ts` | Aggiungi `kemSecretKey`, matching ibrido | Media | -| `verify.ts` | Supporto verifica ibrida | Bassa | -| **LogChainV1.sol** | **NESSUNA MODIFICA** | - | - ---- - -## Cosa NON Cambia - -1. **Contratto**: LogChainV1.sol rimane identico -2. **Evento HSR**: `responderEphemeralR` rimane nel contratto e viene usato -3. **Funzioni esistenti**: `computeTagFromResponder/Initiator` restano (backward compat) -4. **R on-chain**: Necessario per ECDH nel tag ibrido - ---- - -## Proprieta di Sicurezza - -| Proprieta | Prima | Dopo | -|-----------|-------|------| -| Topic Epoch 0 (quantum) | X (solo ECDH) | V (ibrido) | -| HSโ†’HSR Unlinkability (quantum) | X (R linkabile) | V (kemSecret required) | -| R utilita | V (tag ECDH) | V (tag ibrido) | -| Backward compat | - | V (fallback classico) | - ---- - -## Test - -```typescript -describe('PQ-secure hybrid tag', () => { - it('requires both kemSecret and R to compute tag', () => { - const viewPrivA = randomBytes(32); - const viewPubA = getPublicKey(viewPrivA); - const { secretKey: r, publicKey: R } = nacl.box.keyPair(); - const kemSecret = randomBytes(32); - - // Responder computes - const tagResp = computeHybridTagFromResponder(r, viewPubA, kemSecret); - - // Initiator verifies (needs R!) - const tagInit = computeHybridTagFromInitiator(viewPrivA, R, kemSecret); - - expect(tagResp).toBe(tagInit); - }); - - it('different kemSecret = different tag (PQ unlinkability)', () => { - const viewPrivA = randomBytes(32); - const viewPubA = getPublicKey(viewPrivA); - const { secretKey: r } = nacl.box.keyPair(); - - const tag1 = computeHybridTagFromResponder(r, viewPubA, randomBytes(32)); - const tag2 = computeHybridTagFromResponder(r, viewPubA, randomBytes(32)); - - // Same ECDH, different KEM -> different tags - expect(tag1).not.toBe(tag2); - }); - - it('quantum attacker cannot compute tag without kemSecret', () => { - // Attacker has: viewPubA (from HS), R (from HSR), can compute ECDH - // Attacker missing: kemSecret (encrypted in HSR payload) - // Result: cannot compute hybrid tag -> no linkability - }); -}); -``` - ---- - -## Demo App (apps/demo) - -Le modifiche alla demo app saranno minime perche il core logic e nell'SDK. - -**useMessageListener.ts**: -- Estrarre `kemCiphertext` dal payload HSR decryptato -- Passarlo a `matchByTag(tag, R, kemCiphertext)` - -**useChatActions.ts**: -- Salvare `kemSecretKey` quando si manda un HS (gia fatto per `handshakeKemSecret`) - ---- - -## Ordine di Implementazione - -1. `crypto.ts` - Aggiungere funzioni ibride -2. `send.ts` - Usare tag ibrido -3. `VerbethClient.ts` - Propagare kemSecret a deriveTopicsFromDH -4. `HsrTagIndex.ts` - Matching ibrido -5. `verify.ts` - Verifica ibrida -6. Test -7. Demo app adjustments diff --git a/tests/handshaking.test.ts b/tests/handshaking.test.ts index a017da2..a57af33 100644 --- a/tests/handshaking.test.ts +++ b/tests/handshaking.test.ts @@ -18,8 +18,9 @@ import { deriveIdentityKeyPairWithProof, verifyHandshakeIdentity, verifyHandshakeResponseIdentity, - computeTagFromInitiator, + computeHybridTagFromInitiator, decodeUnifiedPubKeys, + kem, } from "../packages/sdk/src/index.js"; import { From a008f23e63d6c5815be075434d179aec52642e3c Mon Sep 17 00:00:00 2001 From: Marco Esposito Date: Thu, 29 Jan 2026 17:30:52 +0100 Subject: [PATCH 26/51] update readmes --- README.md | 187 ++--------------------------------------- packages/sdk/README.md | 29 ++++++- 2 files changed, 33 insertions(+), 183 deletions(-) diff --git a/README.md b/README.md index 0451446..1f21d92 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ #### Built with - +- [**Noble**](https://paulmillr.com/noble/) โ€“ audited JS implementations for curves, hashes, secp256k1, and ML-KEM-768 (post-quantum) - [**TweetNaCl**](https://tweetnacl.js.org/) โ€“ for encryption/decryption with NaCl box - [**Ethers v6**](https://docs.ethers.org/v6/) โ€“ for all Ethereum interactions - [**Viem**](https://viem.sh/) โ€“ specific for EIP-1271/6492 verification @@ -36,140 +36,19 @@ --- -## How can Alice & Bob use Verbeth? - -Alice wants to initiate a secure chat with Bob: - -1. Alice generates a new **ephemeral keypair**. -2. She emits a `Handshake` event that includes: - - her ephemeral public key (for this handshake only) - - her long-term unified keys (X25519 + Ed25519) - - a plaintext payload carrying her identityProof and an optional note - - the recipientHash mapping to Bob -3. Bob watches logs for handshake events addressed to him (matching his recipientHash), and: - - verifies Aliceโ€™s identity with the included identityProof, - - prepares his `HandshakeResponse` -4. Bob computes a response tag and emits the response event: - - - Bob generates an ephemeral keypair (R, r) dedicated to the tag (i.e. Bob can't forge a response for someone else other than Alice) - - He computes the tag `H( HKDF( ECDH( r, Alice.viewPub ), "verbeth:hsr"))` - - He encrypts the response to Aliceโ€™s handshake ephemeral public key and includes: - - his ephemeral public key for post-handshake - - his identity keys (unified) + identityProof - - topicInfo (see below) inside the encrypted payload - - the public R and response tag in the log - -5. Using her view (ephemeral) secret key and Bobโ€™s public R, Alice recomputes the tag. She can then filter handshake response logs by this tag and decrypt the matching one. - -6. Once handshake is complete, both derive duplex topics and start emitting `MessageSent` events: - -- Using a long-term diffieโ€“hellman shared secret and the response tag as salt, they derive: - ``` - shared = ECDH( Alice , Bob ) - topic = keccak256( HKDF(sha256, shared, salt, info) ) - ``` - N.B: with the tag salt, each handshake creates fresh topics -- Alice encrypts messages using Bobโ€™s identity key with a fresh ephemeral key per message (and vice versa). -- They can sign messages with their long term signing key - -``` -ALICE (Initiator) BLOCKCHAIN BOB (Responder) - | | | - |----------------------------|----------------------------| - | PHASE 0: | - | Identity and Key Derivation | - |--------------------------->| | - | Generate identity keys | | - | Sign identity-binding msg | | - | Create IdentityProof | | - | |<---------------------------| - | | Generate identity keys | - | | Sign identity-binding msg | - | | Create IdentityProof | - | | | - | PHASE 1: Alice Initiates Handshake | - |--------------------------->| | - | Generate ephemeral keypair| | - | Prepare HandshakeContent | | - | Encode unified pubKeys | | - | initiateHandshake() |--------------------------->| - | | Emit Handshake event | - | |--------------------------->| - | | PHASE 2: Bob Receives | - | | Listen for event | - | | Parse unified pubKeys | - | | Extract IdentityProof | - | | Verify Alice's identity | - | | | - | | PHASE 3: Bob Responds | - | |--------------------------->| - | | If valid: | - | | - Generate ephemeral key | - | | - Prepare response | - | | - Encrypt w/ Alice's | - | | EPHEMERAL key | - | | respondToHandshake() | - | | Emit HandshakeResponse | - | |--------------------------->| - | | Else: reject handshake | - | | | - | PHASE 4: Alice Receives Response | - |<--------------------------| | - | Listen for HandshakeResponse event | - | Decrypt response w/ own ephemeral secret | - | Extract Bob's keys & proof | - | Verify Bob's identity | - | | - | PHASE 5: Secure Communication Established | - |--------------------------->| | - | Store Bob's keys | | - | Ongoing: | | - | - Generate fresh | | - | ephemeral keys | | - | - Encrypt w/ Bob's | | - | IDENTITY key + | | - | fresh ephemeral | | - | - Sign w/ Alice's key | | - | - sendMessage() |--------------------------->| - | | Message event received | - | | Decrypt w/ Bob's | - | | IDENTITY key + | - | | ephemeral from msg | - | | Verify signature | - | | Secure message delivered | - |----------------------------|----------------------------| - | | - -``` - -## Contract - -We include `sender` (= `msg.sender`) as an **indexed event field** to bind each log to the actual caller account (EOA or smart account) and make it "bloom-filterable". - -A transaction receipt does not expose the immediate caller of this contract โ€” it only contains the emitter address (this contract) and the topics/data โ€” so recovering `msg.sender` would require execution traces. - -Under ERC-4337 this becomes even trickier: the outer transaction targets the EntryPoint and tx.from is the bundler, not the smart account. Without including sender in the event, reliably linking a log to the originating account would require correlating EntryPoint internals or traces. +## How it works -### Deployed Addresses (base mainnet) +To start a conversation, Alice emits a `Handshake` event with her ephemeral keys and an identity proof. Bob sees it, verifies her, and replies with a `HandshakeResponse`. They combine X25519 and ML-KEM-768 secrets to derive a shared root key that's secure even against future quantum computers. -LogChainV1 (singleton) `0x41a3eaC0d858028E9228d1E2092e6178fc81c4f0` +From there it's just encrypted `MessageSent` events back and forth. A Double Ratchet keeps churning keys forward so old messages stay safe even if something leaks later. Topics rotate too, making it hard for observers to link conversations across time. More info [here](). -ERC1967Proxy `0x62720f39d5Ec6501508bDe4D152c1E13Fd2F6707` -## Features +### Deployed Addresses (base mainnet) -- Stateless encrypted messaging via logs -- Ephemeral keys & forward secrecy -- Handshake-based key exchange (no prior trust) -- Minimal metadata via `recipientHash` -- Fully on-chain: no servers, no relays -- Compatible with EOAs and smart contract accounts +LogChainV1 (singleton) `0x41a3eaC0d858028E9228d1E2092e6178fc81c4f0` -The SDK verifies handshakes logs using [viem.verifyMessage](https://viem.sh/docs/actions/public/verifyMessage). -It supports both EOAs and Smart Contract Accounts โ€” whether theyโ€™re already deployed or still counterfactual/pre-deployed โ€” by leveraging: +ERC1967Proxy `0x62720f39d5Ec6501508bDe4D152c1E13Fd2F6707` -- ERC-1271: for verifying signatures from smart contract wallets that are deployed. -- ERC-6492: a wrapper standard that lets smart contract accounts sign and be verified before deployment. ### Notes on the current model @@ -177,54 +56,4 @@ It supports both EOAs and Smart Contract Accounts โ€” whether theyโ€™re already **Identity key binding**: The message (es. โ€œVerbEth Key Binding v1\nAddress: โ€ฆ\nPkEd25519: โ€ฆ\nPkX25519: โ€ฆ\nContext: โ€ฆ\nVersion: โ€ฆโ€) is signed by the evm account directly binding its address to the long-term keys (i.e. preventing impersonation). -**Non-repudiation**: By default, confidentiality and integrity are guaranteed by AEAD with NaCl box. Additionally, the sender can attach a detached Ed25519 signature over using the Ed25519 key bound in the handshake. This effectively provides per-message origin authentication that is verifiable: a recipient (or any third party) can prove the message was produced by the holder of that specific Ed25519 key. Otherwise, attribution relies on context, making sender spoofing at the application layer harder to detect. - -**Forward secrecy**: Each message uses a fresh sender ephemeral key. This provides sender-side forward secrecy for sent messages: once the sender deletes the ephemeral secret, a future compromise of their long-term keys does not expose past ciphertexts. Handshake responses also use ephemeralโ†”ephemeral, enjoying the same property. However, if a recipientโ€™s long-term X25519 key is compromised, all past messages addressed to them remain decryptable. A double-ratchet (or ephemeralโ†”ephemeral messaging) can extend forward secrecy to the recipient side (see [here](#improvement-ideas)). - -**Handshake linkability:** -Each handshake relies on a diffieโ€“hellman exchange between the initiatorโ€™s handshake ephemeral key and the responderโ€™s tag ephemeral R. The resulting tag is an opaque pointer that hides who the initiator is. Reusing only the responderโ€™s R lets observers group his responses that reused the same tag key, but it does not reveal which initiator each response targets. Reusing only initiator's ephemeral pubkey lets observers group her handshakes (which already show sender in this design, but breaking unlinkability if hidden behind a relay). The tag repeats only if both ephemerals are reused together. The real issue is a lack of forward secrecy during handshaking: if either handshake-ephemeral secret is later compromised and had been reused, an attacker could retroactively derive all matching tags and link multiple past handshakes between the same parties. In practice, both sides should generate fresh ephemerals per handshake and securely erase them after use. - -**Communication channels linkability**: Current version has duplex topics by default: one topic per direction, obtained with HKDF. So, each side writes on its own secret topic and we donโ€™t get the โ€œtwo accounts posting on the same topic, hence theyโ€™re chattingโ€ giveaway. Also, the topic is optionally bound to each message by covering it in the detached Ed25519 signature (topic || epk || nonce || ciphertext), which kills cross-topic replays. At the application level, each client queries only its inbound topics so the RPC endpoint never learns both sides of a duplex pair. Note: timing during the handshake phase (and general traffic analysis) can still reveal communication patterns. - -## Example Usage (WIP) - -```ts -import { - decryptLog, - initiateHandshake, - sendEncryptedMessage, - deriveIdentityKeyPairWithProof, -} from "@verbeth/sdk"; - -// 1. Generate or load your long-term identity keypair -const { publicKey, secretKey } = await deriveIdentityKeyPairWithProof( - walletClient -); - -// 2. Receive and decrypt a message from an on-chain log event -const decrypted = decryptLog(eventLog, secretKey); - -// 3. Start a handshake with another user -await initiateHandshake({ - contract, // LogChainV1 - recipientAddress: "0xBob...", - ephemeralPubKey: ephemeralKey.publicKey, - plaintextPayload: "Hi Bob, ping from Alice", // (optional) plaintext handshake message -}); - -// 4. Send an encrypted message (after handshake is established) -await sendEncryptedMessage({ - contract, - recipientAddress: "0xBob...", - message: "Hello again, Bob!", - senderEphemeralKeyPair: ephemeralKey, // ephemeral keypair used for forward secrecy - recipientPublicKey, -}); -``` - -## Improvement ideas - -| Title | Description | Refs | -| -------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| Bidirectional Forward Secrecy (session ratchet) | Achieve **end-to-end, bilateral FS** even if the **recipientโ€™s long-term X25519** is later compromised. Two options: (1) switch messaging to **ephemeralโ†”ephemeral** (derive per-message DH and discard secrets), or (2) derive a **symmetric session ratchet** from the handshake (e.g., **Double Ratchet** for 1:1; **MLS** for 1\:many) so every message advances sending/receiving chains and old keys are irrecoverable. | Signal **Double Ratchet** spec (post-X3DH): [https://signal.org/docs/specifications/doubleratchet/](https://signal.org/docs/specifications/doubleratchet/) ; **MLS** (RFC 9420): [https://www.rfc-editor.org/rfc/rfc9420](https://www.rfc-editor.org/rfc/rfc9420) ; Matrix **Olm/Megolm** (Double Ratchet for 1:1 / group): [https://gitlab.matrix.org/matrix-org/olm](https://gitlab.matrix.org/matrix-org/olm) ; **Status/Waku** Double Ratchet transport: [https://specs.status.im/spec/5](https://specs.status.im/spec/5) and Waku X3DH/DR notes: [https://rfc.vac.dev/waku/standards/application/53/x3dh/](https://rfc.vac.dev/waku/standards/application/53/x3dh/) ; **XMTP** (MLS-based): [https://docs.xmtp.org/protocol/overview](https://docs.xmtp.org/protocol/overview) | -| Passkeys & WebAuthn PRF for encryption of messages | Let smart accounts encrypt messages with the same passkey used for UserOps. Use the WebAuthn **PRF** extension to derive an AEAD key at auth time (plus per-message salt/nonce) so users only manage the passkeyโ€”gaining stronger security (hardware/biometric protection) and portability/recovery (OS-synced passkeys or hardware keys). | [Corbado: Passkeys & PRF](https://www.corbado.com/blog/passkeys-prf-webauthn), [W3C WebAuthn L3: PRF extension](https://www.w3.org/TR/webauthn-3/), [Chrome: Intent to Ship (PRF)](https://groups.google.com/a/chromium.org/g/blink-dev/c/iTNOgLwD2bI), [SimpleWebAuthn: PRF docs](https://simplewebauthn.dev/docs/advanced/prf) | +**Non-repudiation**: By default, confidentiality and integrity are guaranteed by AEAD with NaCl box. Additionally, the sender can attach a detached Ed25519 signature over using the Ed25519 key bound in the handshake. This effectively provides per-message origin authentication that is verifiable: a recipient (or any third party) can prove the message was produced by the holder of that specific Ed25519 key. Otherwise, attribution relies on context, making sender spoofing at the application layer harder to detect. | diff --git a/packages/sdk/README.md b/packages/sdk/README.md index 801562e..907e744 100644 --- a/packages/sdk/README.md +++ b/packages/sdk/README.md @@ -3,17 +3,38 @@ End-to-end encrypted messaging over public EVM blockchains. ### Install +```bash npm install @verbeth/sdk +``` -### Minimal example +### Quickstart ```ts -const client = await createVerbethClient(...) -await client.send("hello") +import { createVerbethClient, deriveIdentityKeyPairWithProof, ExecutorFactory } from '@verbeth/sdk'; +import { ethers } from 'ethers'; + +const LOGCHAIN = '0x62720f39d5Ec6501508bDe4D152c1E13Fd2F6707'; + +const provider = new ethers.BrowserProvider(window.ethereum); +const signer = await provider.getSigner(); +const address = await signer.getAddress(); + +const { identityKeyPair, identityProof } = await deriveIdentityKeyPairWithProof(signer, address); + +const contract = new ethers.Contract(LOGCHAIN, LogChainABI, signer); +const client = createVerbethClient({ + address, + signer, + identityKeyPair, + identityProof, + executor: ExecutorFactory.createEOA(contract), +}); + +await client.sendMessage(conversationId, 'Hello, encrypted world!'); ``` ## Documentation -For detailed protocol documentation, security analysis, and improvement proposals, see the [main repository](https://github.com/okrame/verbeth-sdk). +For detailed protocol documentation, see [docs.verbeth.xyz](https://docs.verbeth.xyz). ## License From ae788efae133a0b8f0f33b0654e82ff33591f8af Mon Sep 17 00:00:00 2001 From: Marco Esposito Date: Thu, 29 Jan 2026 17:48:38 +0100 Subject: [PATCH 27/51] release: @verbeth/sdk v0.1.5 --- .claude/skills/frontend/SKILL.md | 41 -------------------------------- .gitignore | 2 +- packages/sdk/package.json | 2 +- 3 files changed, 2 insertions(+), 43 deletions(-) delete mode 100644 .claude/skills/frontend/SKILL.md diff --git a/.claude/skills/frontend/SKILL.md b/.claude/skills/frontend/SKILL.md deleted file mode 100644 index 2d36e82..0000000 --- a/.claude/skills/frontend/SKILL.md +++ /dev/null @@ -1,41 +0,0 @@ ---- -name: frontend -description: Create distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics. ---- - -This skill guides creation of distinctive, production-grade frontend interfaces that avoid generic "AI slop" aesthetics. Implement real working code with exceptional attention to aesthetic details and creative choices. - -The user provides frontend requirements: a component, page, application, or interface to build. They may include context about the purpose, audience, or technical constraints. - -## Design Thinking - -Before coding, understand the context and commit to a BOLD aesthetic direction: -- **Purpose**: What problem does this interface solve? Who uses it? -- **Tone**: Pick an extreme: brutally minimal, maximalist chaos, retro-futuristic, organic/natural, luxury/refined, playful/toy-like, editorial/magazine, brutalist/raw, art deco/geometric, soft/pastel, industrial/utilitarian, etc. There are so many flavors to choose from. Use these for inspiration but design one that is true to the aesthetic direction. -- **Constraints**: Technical requirements (framework, performance, accessibility). -- **Differentiation**: What makes this UNFORGETTABLE? What's the one thing someone will remember? - -**CRITICAL**: Choose a clear conceptual direction and execute it with precision. Bold maximalism and refined minimalism both work - the key is intentionality, not intensity. - -Then implement working code (HTML/CSS/JS, React, Vue, etc.) that is: -- Production-grade and functional -- Visually striking and memorable -- Cohesive with a clear aesthetic point-of-view -- Meticulously refined in every detail - -## Frontend Aesthetics Guidelines - -Focus on: -- **Typography**: Choose fonts that are beautiful, unique, and interesting. Avoid generic fonts like Arial and Inter; opt instead for distinctive choices that elevate the frontend's aesthetics; unexpected, characterful font choices. Pair a distinctive display font with a refined body font. -- **Color & Theme**: Commit to a cohesive aesthetic. Use CSS variables for consistency. Dominant colors with sharp accents outperform timid, evenly-distributed palettes. -- **Motion**: Use animations for effects and micro-interactions. Prioritize CSS-only solutions for HTML. Use Motion library for React when available. Focus on high-impact moments: one well-orchestrated page load with staggered reveals (animation-delay) creates more delight than scattered micro-interactions. Use scroll-triggering and hover states that surprise. -- **Spatial Composition**: Unexpected layouts. Asymmetry. Overlap. Diagonal flow. Grid-breaking elements. Generous negative space OR controlled density. -- **Backgrounds & Visual Details**: Create atmosphere and depth rather than defaulting to solid colors. Add contextual effects and textures that match the overall aesthetic. Apply creative forms like gradient meshes, noise textures, geometric patterns, layered transparencies, dramatic shadows, decorative borders, custom cursors, and grain overlays. - -NEVER use generic AI-generated aesthetics like overused font families (Inter, Roboto, Arial, system fonts), cliched color schemes (particularly purple gradients on white backgrounds), predictable layouts and component patterns, and cookie-cutter design that lacks context-specific character. - -Interpret creatively and make unexpected choices that feel genuinely designed for the context. No design should be the same. Vary between light and dark themes, different fonts, different aesthetics. NEVER converge on common choices (Space Grotesk, for example) across generations. - -**IMPORTANT**: Match implementation complexity to the aesthetic vision. Maximalist designs need elaborate code with extensive animations and effects. Minimalist or refined designs need restraint, precision, and careful attention to spacing, typography, and subtle details. Elegance comes from executing the vision well. - -Remember: Claude is capable of extraordinary creative work. Don't hold back, show what can truly be created when thinking outside the box and committing fully to a distinctive vision. \ No newline at end of file diff --git a/.gitignore b/.gitignore index 957d489..6cd36d4 100644 --- a/.gitignore +++ b/.gitignore @@ -25,6 +25,6 @@ ignition/deployments/chain-84532 *apps/notes/ .claudeignore +*.claude/ CLAUDE.md - old-plan-docs.md \ No newline at end of file diff --git a/packages/sdk/package.json b/packages/sdk/package.json index 971288e..a74c10c 100644 --- a/packages/sdk/package.json +++ b/packages/sdk/package.json @@ -1,6 +1,6 @@ { "name": "@verbeth/sdk", - "version": "0.1.4", + "version": "0.1.5", "private": false, "main": "dist/src/index.js", "module": "dist/esm/src/index.js", From d2691c56f30a85d68b39721f2cdf10ba979bf6f1 Mon Sep 17 00:00:00 2001 From: Marco Esposito Date: Sun, 1 Feb 2026 17:59:50 +0100 Subject: [PATCH 28/51] rename contract to verbeth --- README.md | 4 +- apps/demo/src/App.tsx | 4 +- .../src/components/SessionSetupPrompt.tsx | 6 +- apps/demo/src/hooks/useInitIdentity.ts | 16 +- apps/demo/src/hooks/useMessageListener.ts | 10 +- apps/demo/src/hooks/useSessionSetup.ts | 8 +- apps/demo/src/services/safeAccount.ts | 4 +- apps/demo/src/types.ts | 4 +- apps/docs/docs/concepts/how-it-works.md | 6 +- apps/docs/docs/quick-start.md | 8 +- apps/docs/docusaurus.config.ts | 2 +- packages/contracts/contracts/LogChainV1.sol | 142 ---------- packages/contracts/contracts/VerbethV1.sol | 138 ++++++++++ .../contracts/ignition/modules/LogChain.ts | 16 -- .../contracts/ignition/modules/Verbeth.ts | 16 ++ packages/contracts/package.json | 8 +- packages/contracts/test/upgrade.test.ts | 242 +++++++++++++++--- .../{logchain.test.ts => verbeth.test.ts} | 28 +- packages/sdk/README.md | 4 +- packages/sdk/src/executor.ts | 104 ++++---- packages/sdk/src/utils/safeSessionSigner.ts | 12 +- packages/sdk/test/executor.test.ts | 18 +- packages/sdk/test/utils.test.ts | 2 +- tests/e2e.test.ts | 52 ++-- tests/handshaking.test.ts | 70 ++--- 25 files changed, 548 insertions(+), 376 deletions(-) delete mode 100644 packages/contracts/contracts/LogChainV1.sol create mode 100644 packages/contracts/contracts/VerbethV1.sol delete mode 100644 packages/contracts/ignition/modules/LogChain.ts create mode 100644 packages/contracts/ignition/modules/Verbeth.ts rename packages/contracts/test/{logchain.test.ts => verbeth.test.ts} (76%) diff --git a/README.md b/README.md index 1f21d92..ea19ca0 100644 --- a/README.md +++ b/README.md @@ -45,9 +45,9 @@ From there it's just encrypted `MessageSent` events back and forth. A Double Rat ### Deployed Addresses (base mainnet) -LogChainV1 (singleton) `0x41a3eaC0d858028E9228d1E2092e6178fc81c4f0` +VerbethV1 (singleton) `0x51670aB6eDE1d1B11C654CCA53b7D42080802326` -ERC1967Proxy `0x62720f39d5Ec6501508bDe4D152c1E13Fd2F6707` +ERC1967Proxy `0x82C9c5475D63e4C9e959280e9066aBb24973a663` ### Notes on the current model diff --git a/apps/demo/src/App.tsx b/apps/demo/src/App.tsx index 7637ec9..a41c3c1 100644 --- a/apps/demo/src/App.tsx +++ b/apps/demo/src/App.tsx @@ -10,7 +10,7 @@ import { import { useMessageListener } from './hooks/useMessageListener.js'; import { useMessageProcessor } from './hooks/useMessageProcessor.js'; import { - LOGCHAIN_SINGLETON_ADDR, + VERBETH_SINGLETON_ADDR, CONTRACT_CREATION_BLOCK, Contact, Message, @@ -682,7 +682,7 @@ export default function App() { {!isActivityLogOpen && (
-

Contract: {LOGCHAIN_SINGLETON_ADDR}

+

Contract: {VERBETH_SINGLETON_ADDR}

Network: Base (Chain ID: {chainId})

Contract creation block: {CONTRACT_CREATION_BLOCK}

Status: {ready ? '๐ŸŸข Ready' : '๐Ÿ”ด Not Ready'} {(isInitialLoading || isLoadingMore) ? 'โณ Loading' : ''}

diff --git a/apps/demo/src/components/SessionSetupPrompt.tsx b/apps/demo/src/components/SessionSetupPrompt.tsx index 1a44152..2ba5784 100644 --- a/apps/demo/src/components/SessionSetupPrompt.tsx +++ b/apps/demo/src/components/SessionSetupPrompt.tsx @@ -51,7 +51,7 @@ export function SessionSetupPrompt({ steps: [ "Deploy your Safe smart wallet", "Enable session module", - "Register session signer + allow LogChain target", + "Register session signer + allow Verbeth target", ], }; } else if (!isModuleEnabled) { @@ -62,7 +62,7 @@ export function SessionSetupPrompt({ description: "Enable the session module on your existing Safe and authorize gasless messaging.", steps: [ "Enable session module on Safe", - "Register session signer + allow LogChain target", + "Register session signer + allow Verbeth target", ], }; } else { @@ -72,7 +72,7 @@ export function SessionSetupPrompt({ title: "Authorize Session", description: "One-time setup: authorize your session wallet to send messages without popups.", steps: [ - "Register session signer + allow LogChain target", + "Register session signer + allow Verbeth target", ], }; } diff --git a/apps/demo/src/hooks/useInitIdentity.ts b/apps/demo/src/hooks/useInitIdentity.ts index c152657..2d62180 100644 --- a/apps/demo/src/hooks/useInitIdentity.ts +++ b/apps/demo/src/hooks/useInitIdentity.ts @@ -2,8 +2,8 @@ import { useState, useEffect, useCallback, useMemo } from 'react'; import { BrowserProvider, Wallet } from 'ethers'; import { - LogChainV1__factory, - type LogChainV1, + VerbethV1__factory, + type VerbethV1, } from '@verbeth/contracts/typechain-types/index.js'; import { IExecutor, @@ -22,7 +22,7 @@ import { isHelperAvailable, } from '../services/safeAccount.js'; import { - LOGCHAIN_SINGLETON_ADDR, + VERBETH_SINGLETON_ADDR, SAFE_MODULE_ADDRESS, StoredIdentity, ExecutionMode, @@ -52,7 +52,7 @@ export function useInitIdentity({ const [identityKeyPair, setIdentityKeyPair] = useState(null); const [identityProof, setIdentityProof] = useState(null); const [executor, setExecutor] = useState(null); - const [contract, setContract] = useState(null); + const [contract, setContract] = useState(null); const [identitySigner, setIdentitySigner] = useState(null); const [txSigner, setTxSigner] = useState(null); const [safeAddr, setSafeAddr] = useState(null); @@ -158,7 +158,7 @@ export function useInitIdentity({ if (currentMode === 'classic') { addLog(`Classic mode: using EOA executor`); - const contractInstance = LogChainV1__factory.connect(LOGCHAIN_SINGLETON_ADDR, ethersSigner as any); + const contractInstance = VerbethV1__factory.connect(VERBETH_SINGLETON_ADDR, ethersSigner as any); const executorInstance = ExecutorFactory.createEOA(contractInstance); setExecutor(executorInstance); @@ -185,7 +185,7 @@ export function useInitIdentity({ deployIfMissing: false, sessionConfig: { sessionSigner: sessionAddr, - target: LOGCHAIN_SINGLETON_ADDR, + target: VERBETH_SINGLETON_ADDR, }, // Never use API for fast mode useApiLookup: false, @@ -217,7 +217,7 @@ export function useInitIdentity({ provider: readProvider, safeAddress, moduleAddress: SAFE_MODULE_ADDRESS, - logChainAddress: LOGCHAIN_SINGLETON_ADDR, + verbEthAddress: VERBETH_SINGLETON_ADDR, sessionSigner: sessionWallet, }); setTxSigner(safeSessionSigner); @@ -236,7 +236,7 @@ export function useInitIdentity({ console.log(`=====================================================\n`); - const contractInstance = LogChainV1__factory.connect(LOGCHAIN_SINGLETON_ADDR, safeSessionSigner as any); + const contractInstance = VerbethV1__factory.connect(VERBETH_SINGLETON_ADDR, safeSessionSigner as any); const executorInstance = ExecutorFactory.createEOA(contractInstance); setExecutor(executorInstance); diff --git a/apps/demo/src/hooks/useMessageListener.ts b/apps/demo/src/hooks/useMessageListener.ts index 301a2a2..f16d779 100644 --- a/apps/demo/src/hooks/useMessageListener.ts +++ b/apps/demo/src/hooks/useMessageListener.ts @@ -5,7 +5,7 @@ import { keccak256, toUtf8Bytes, getBytes, AbiCoder } from "ethers"; import { matchHsrToContact, type PendingContactEntry } from "@verbeth/sdk"; import { dbService } from "../services/DbService.js"; import { - LOGCHAIN_SINGLETON_ADDR, + VERBETH_SINGLETON_ADDR, CONTRACT_CREATION_BLOCK, INITIAL_SCAN_BLOCKS, MAX_RETRIES, @@ -238,7 +238,7 @@ export const useMessageListener = ({ try { const handshakeFilter = { - address: LOGCHAIN_SINGLETON_ADDR, + address: VERBETH_SINGLETON_ADDR, topics: [EVENT_SIGNATURES.Handshake, userRecipientHash], }; const handshakeLogs = await safeGetLogs( @@ -268,7 +268,7 @@ export const useMessageListener = ({ if (pendingContacts.length > 0) { // Fetch ALL HSR events (no address filter - responder could be Safe or EOA) const responseFilter = { - address: LOGCHAIN_SINGLETON_ADDR, + address: VERBETH_SINGLETON_ADDR, topics: [EVENT_SIGNATURES.HandshakeResponse], }; const responseLogs = await safeGetLogs( @@ -308,7 +308,7 @@ export const useMessageListener = ({ if (activeTopics.length > 0) { // Query messages on all active topics const messageFilterIn = { - address: LOGCHAIN_SINGLETON_ADDR, + address: VERBETH_SINGLETON_ADDR, topics: [EVENT_SIGNATURES.MessageSent, null, activeTopics], }; const inboundLogs = await safeGetLogs( @@ -338,7 +338,7 @@ export const useMessageListener = ({ const senderTopic = "0x000000000000000000000000" + emitter.slice(2).toLowerCase(); const messageFilterOutConfirm = { - address: LOGCHAIN_SINGLETON_ADDR, + address: VERBETH_SINGLETON_ADDR, topics: [EVENT_SIGNATURES.MessageSent, senderTopic], }; const outLogs = await safeGetLogs( diff --git a/apps/demo/src/hooks/useSessionSetup.ts b/apps/demo/src/hooks/useSessionSetup.ts index b66b571..67778fa 100644 --- a/apps/demo/src/hooks/useSessionSetup.ts +++ b/apps/demo/src/hooks/useSessionSetup.ts @@ -5,7 +5,7 @@ import { getOrCreateSafeForOwner, ensureModuleEnabled, } from "../services/safeAccount.js"; -import { LOGCHAIN_SINGLETON_ADDR, SAFE_MODULE_ADDRESS, ExecutionMode } from "../types.js"; +import { VERBETH_SINGLETON_ADDR, SAFE_MODULE_ADDRESS, ExecutionMode } from "../types.js"; interface UseSessionSetupParams { walletClient: any; @@ -108,7 +108,7 @@ export function useSessionSetup({ deployIfMissing: true, sessionConfig: { sessionSigner: sessionSignerAddr, - target: LOGCHAIN_SINGLETON_ADDR, + target: VERBETH_SINGLETON_ADDR, }, useApiLookup: false, }); @@ -145,7 +145,7 @@ export function useSessionSetup({ deployIfMissing: false, sessionConfig: { sessionSigner: sessionSignerAddr, - target: LOGCHAIN_SINGLETON_ADDR, + target: VERBETH_SINGLETON_ADDR, }, useApiLookup: false, }); @@ -167,7 +167,7 @@ export function useSessionSetup({ safeAddr, sessionSignerAddr, BigInt("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"), - LOGCHAIN_SINGLETON_ADDR + VERBETH_SINGLETON_ADDR ); console.log(`TX: ${tx.hash}`); await tx.wait(); diff --git a/apps/demo/src/services/safeAccount.ts b/apps/demo/src/services/safeAccount.ts index 8bd935f..48ab73f 100644 --- a/apps/demo/src/services/safeAccount.ts +++ b/apps/demo/src/services/safeAccount.ts @@ -2,7 +2,7 @@ import SafeDefault from '@safe-global/protocol-kit' import SafeApiKitDefault from '@safe-global/api-kit' import { getAddress, Interface } from 'ethers' -import { SAFE_MODULE_ADDRESS, LOGCHAIN_SINGLETON_ADDR } from '../types.js' +import { SAFE_MODULE_ADDRESS, VERBETH_SINGLETON_ADDR } from '../types.js' // Handle ESM/CJS interop - safe libs export default differently const Safe = (SafeDefault as any).default ?? SafeDefault @@ -31,7 +31,7 @@ export async function predictVerbEthSafeAddress(params: { const sessionConfig: SessionConfig = { sessionSigner: sessionSignerAddr, - target: LOGCHAIN_SINGLETON_ADDR, + target: VERBETH_SINGLETON_ADDR, } const safeAccountConfig = buildSafeAccountConfig( diff --git a/apps/demo/src/types.ts b/apps/demo/src/types.ts index 5e1b86d..3c7bcc1 100644 --- a/apps/demo/src/types.ts +++ b/apps/demo/src/types.ts @@ -2,8 +2,8 @@ import type { IdentityKeyPair, IdentityProof, RatchetSession as SDKRatchetSessio import { keccak256, toUtf8Bytes, hexlify, getBytes } from 'ethers'; /* ------------------------------- CONSTANTS -------------------------------- */ -export const LOGCHAIN_SINGLETON_ADDR = - '0x41a3eaC0d858028E9228d1E2092e6178fc81c4f0'; +export const VERBETH_SINGLETON_ADDR = + '0x51670aB6eDE1d1B11C654CCA53b7D42080802326'; export const CONTRACT_CREATION_BLOCK = 36_053_269; export const INITIAL_SCAN_BLOCKS = 1_000; export const MAX_RETRIES = 3; diff --git a/apps/docs/docs/concepts/how-it-works.md b/apps/docs/docs/concepts/how-it-works.md index b17f599..aa6dca7 100644 --- a/apps/docs/docs/concepts/how-it-works.md +++ b/apps/docs/docs/concepts/how-it-works.md @@ -16,7 +16,7 @@ Instead of running servers or relay infrastructure, Verbeth stores encrypted mes - **Censorship resistance**: Anyone can read/write to the contract - **Global ordering**: Block timestamps provide message ordering -Messages are emitted as events from the LogChain contract. Clients query these events using standard RPC calls. +Messages are emitted as events from the Verbeth contract. Clients query these events using standard RPC calls. ## No Servers, No Relays @@ -69,7 +69,7 @@ Verbeth works with EOAs but is optimized for Safe accounts: โ”‚ @verbeth/sdk โ”‚ โ”‚ (ratchet, handshake, identity) โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค -โ”‚ LogChainV1 Contract โ”‚ +โ”‚ VerbethV1 Contract โ”‚ โ”‚ (Handshake, HandshakeResponse, โ”‚ โ”‚ MessageSent events) โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค @@ -80,7 +80,7 @@ Verbeth works with EOAs but is optimized for Safe accounts: ## On-Chain Data Model -The LogChain contract emits three event types: +The Verbeth contract emits three event types: | Event | Purpose | Indexed Fields | |-------|---------|----------------| diff --git a/apps/docs/docs/quick-start.md b/apps/docs/docs/quick-start.md index c50939a..b2de785 100644 --- a/apps/docs/docs/quick-start.md +++ b/apps/docs/docs/quick-start.md @@ -25,7 +25,7 @@ import { import { ethers } from 'ethers'; // Contract address (Base mainnet) -const LOGCHAIN_ADDRESS = '0x62720f39d5Ec6501508bDe4D152c1E13Fd2F6707'; +const VERBETH_ADDRESS = '0x51670aB6eDE1d1B11C654CCA53b7D42080802326'; // 1. Connect wallet const provider = new ethers.BrowserProvider(window.ethereum); @@ -39,7 +39,7 @@ const { identityKeyPair, identityProof } = await deriveIdentityKeyPairWithProof( ); // 3. Create executor for contract interactions -const contract = new ethers.Contract(LOGCHAIN_ADDRESS, LOGCHAIN_ABI, signer); +const contract = new ethers.Contract(VERBETH_ADDRESS, VERBETH_ABI, signer); const executor = ExecutorFactory.createEOA(contract); // 4. Create client @@ -163,7 +163,7 @@ import { } from '@verbeth/sdk'; import { ethers } from 'ethers'; -const LOGCHAIN_ADDRESS = '0x62720f39d5Ec6501508bDe4D152c1E13Fd2F6707'; +const VERBETH_ADDRESS = '0x51670aB6eDE1d1B11C654CCA53b7D42080802326'; async function initVerbeth() { const provider = new ethers.BrowserProvider(window.ethereum); @@ -175,7 +175,7 @@ async function initVerbeth() { address ); - const contract = new ethers.Contract(LOGCHAIN_ADDRESS, LOGCHAIN_ABI, signer); + const contract = new ethers.Contract(VERBETH_ADDRESS, VERBETH_ABI, signer); const executor = ExecutorFactory.createEOA(contract); const client = createVerbethClient({ diff --git a/apps/docs/docusaurus.config.ts b/apps/docs/docusaurus.config.ts index a31c571..3d597fb 100644 --- a/apps/docs/docusaurus.config.ts +++ b/apps/docs/docusaurus.config.ts @@ -11,7 +11,7 @@ const config: Config = { v4: true, }, - url: 'https://verbeth.dev', + url: 'https://docs.verbeth.xyz', baseUrl: '/', organizationName: 'okrame', diff --git a/packages/contracts/contracts/LogChainV1.sol b/packages/contracts/contracts/LogChainV1.sol deleted file mode 100644 index 4458fb5..0000000 --- a/packages/contracts/contracts/LogChainV1.sol +++ /dev/null @@ -1,142 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.24; - -import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; -import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol"; -import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; - -/** - * @title LogChainV1 - * @dev Contract for end-to-end encrypted messaging using Ethereum event logs as the sole transport layer. - * @author guefett0 - * @notice This contract enables secure, decentralized messaging without relying on off-chain infrastructure. - */ -contract LogChainV1 is Initializable, UUPSUpgradeable, OwnableUpgradeable { - - /** - * @dev Emitted when an encrypted message is sent - * @param sender The address of the message sender (EOA or smart account) - * @param ciphertext The encrypted message payload - * @param timestamp Unix timestamp when the message was sent - * @param topic Indexed topic/channel identifier for message filtering - * @param nonce Sequential number for message ordering and deduplication - */ - event MessageSent( - address indexed sender, - bytes ciphertext, - uint256 timestamp, - bytes32 indexed topic, - uint256 nonce - ); - - /** - * @dev Emitted when initiating a handshake with a recipient - * @param recipientHash Keccak256 hash of "contact:" + recipient's lowercase address - * @param sender The address initiating the handshake - * @param pubKeys The sender's long-term singing and identity pubkeys (32 bytes each) - * @param ephemeralPubKey Fresh public key generated for this specific handshake - * @param plaintextPayload Human-readable message or JSON with optional identity proof - */ - event Handshake( - bytes32 indexed recipientHash, - address indexed sender, - bytes pubKeys, - bytes ephemeralPubKey, - bytes plaintextPayload - ); - - /** - * @dev Emitted when responding to a handshake - * @param inResponseTo Response tag derived from ECDH(viewPubA, R) and HKDF. - * @param responder The address responding to the handshake - * @param responderEphemeralR Ephemeral public key R used to generate the response tag. - * @param ciphertext Encrypted response containing responder's public keys - */ - event HandshakeResponse( - bytes32 indexed inResponseTo, - address indexed responder, - bytes32 responderEphemeralR, - bytes ciphertext - ); - - /// @custom:oz-upgrades-unsafe-allow constructor - constructor() { - _disableInitializers(); - } - - /** - * @dev Initializes the contract using the proxy pattern - * @notice Should be called immediately after deployment via proxy - */ - function initialize() public initializer { - __Ownable_init(msg.sender); - __UUPSUpgradeable_init(); - } - - /** - * @dev Authorizes contract upgrades (restricted to owner) - * @param newImplementation Address of the new implementation contract - */ - function _authorizeUpgrade(address newImplementation) - internal - override - onlyOwner - {} - - /** - * @dev Sends an encrypted message to a recipient - * @param ciphertext The encrypted message payload (JSON-encoded EncryptedPayload) - * @param topic Channel or conversation identifier for message filtering - * @param timestamp Unix timestamp when the message was created - * @param nonce Sequential number for message ordering (not enforced on-chain) - * - * @notice Gas cost scales with message size. Consider message splitting for large payloads. - * @notice Nonce values are not validated on-chain - clients should handle replay protection. - */ - function sendMessage( - bytes calldata ciphertext, - bytes32 topic, - uint256 timestamp, - uint256 nonce - ) external { - emit MessageSent(msg.sender, ciphertext, timestamp, topic, nonce); - } - - /** - * @dev Initiates a secure handshake with a recipient - * @param recipientHash Keccak256("contact:" + recipient.toLowerCase()) - * @param pubKeys Sender's long-term X25519 public key (32 bytes) - * @param ephemeralPubKey Fresh X25519 public key for this handshake (32 bytes) - * @param plaintextPayload Human-readable greeting or JSON with identity proof - * - * @notice Recipients monitor for events where recipientHash matches their address hash - * @notice For smart accounts, plaintextPayload may include EIP-1271 signature proof - */ - function initiateHandshake( - bytes32 recipientHash, - bytes calldata pubKeys, - bytes calldata ephemeralPubKey, - bytes calldata plaintextPayload - ) external { - emit Handshake(recipientHash, msg.sender, pubKeys, ephemeralPubKey, plaintextPayload); - } - - /** - * @dev Responds to a handshake with encrypted public keys - * @param inResponseTo Reference tag for the handshake initiator - * @param responderEphemeralR Ephemeral public key R used to generate the response tag. - * @param ciphertext Encrypted payload containing responder's identity and ephemeral keys - * - * @notice The ciphertext should be encrypted to the initiator's ephemeral public key - */ - function respondToHandshake(bytes32 inResponseTo, bytes32 responderEphemeralR, bytes calldata ciphertext) external { - emit HandshakeResponse(inResponseTo, msg.sender, responderEphemeralR, ciphertext); - } - - /** - * @dev This empty reserved space allows future versions to add new variables - * without shifting down storage in the inheritance chain. - * @notice See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} \ No newline at end of file diff --git a/packages/contracts/contracts/VerbethV1.sol b/packages/contracts/contracts/VerbethV1.sol new file mode 100644 index 0000000..32d3601 --- /dev/null +++ b/packages/contracts/contracts/VerbethV1.sol @@ -0,0 +1,138 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.24; + +import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; +import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol"; +import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; + +/** + * @title Verbeth + * @dev Contract for messaging using event logs as the sole transport layer. + * @author okrame + */ +contract VerbethV1 is Initializable, UUPSUpgradeable, OwnableUpgradeable { + + uint256 public constant UPGRADE_DELAY = 2 days; + address public pendingImplementation; + uint256 public upgradeEligibleAt; + + event UpgradeProposed(address indexed newImplementation, uint256 eligibleAt); + event UpgradeCancelled(address indexed newImplementation); + + /** + * @dev Emitted when a message is sent + * @param sender The address of the message sender (EOA or contract) + * @param ciphertext The message payload + * @param timestamp Unix timestamp when the message was sent + * @param topic Indexed channel identifier for message filtering + * @param nonce Sequential number for message ordering and deduplication + */ + event MessageSent( + address indexed sender, + bytes ciphertext, + uint256 timestamp, + bytes32 indexed topic, + uint256 nonce + ); + + /** + * @dev Emitted when initiating a handshake with a recipient + * @param recipientHash e.g. Keccak256 hash of "contact:" + recipient's lowercase address + * @param sender The address initiating the handshake + * @param pubKeys The sender's long-term public keys + * @param ephemeralPubKey Ephemeral public key(s) for this handshake + * @param plaintextPayload Typically contains a message and identity proof + */ + event Handshake( + bytes32 indexed recipientHash, + address indexed sender, + bytes pubKeys, + bytes ephemeralPubKey, + bytes plaintextPayload + ); + + /** + * @dev Emitted when responding to a handshake + * @param inResponseTo Matching tag so the initiator can find this response + * @param responder The address responding to the handshake + * @param responderEphemeralR Ephemeral public key used to derive the response tag + * @param ciphertext Encrypted response payload with responder's keys + */ + event HandshakeResponse( + bytes32 indexed inResponseTo, + address indexed responder, + bytes32 responderEphemeralR, + bytes ciphertext + ); + + /// @custom:oz-upgrades-unsafe-allow constructor + constructor() { + _disableInitializers(); + } + + function initialize() public initializer { + __Ownable_init(msg.sender); + __UUPSUpgradeable_init(); + } + + + function proposeUpgrade(address newImplementation) external onlyOwner { + require(newImplementation != address(0), "Invalid implementation"); + pendingImplementation = newImplementation; + upgradeEligibleAt = block.timestamp + UPGRADE_DELAY; + emit UpgradeProposed(newImplementation, upgradeEligibleAt); + } + + + function cancelUpgrade() external onlyOwner { + require(pendingImplementation != address(0), "No pending upgrade"); + address cancelled = pendingImplementation; + pendingImplementation = address(0); + upgradeEligibleAt = 0; + emit UpgradeCancelled(cancelled); + } + + function _authorizeUpgrade(address newImplementation) + internal + override + onlyOwner + { + require(newImplementation == pendingImplementation, "Not proposed implementation"); + require(block.timestamp >= upgradeEligibleAt, "Timelock not expired"); + pendingImplementation = address(0); + upgradeEligibleAt = 0; + } + + + function sendMessage( + bytes calldata ciphertext, + bytes32 topic, + uint256 timestamp, + uint256 nonce + ) external { + emit MessageSent(msg.sender, ciphertext, timestamp, topic, nonce); + } + + + function initiateHandshake( + bytes32 recipientHash, + bytes calldata pubKeys, + bytes calldata ephemeralPubKey, + bytes calldata plaintextPayload + ) external { + emit Handshake(recipientHash, msg.sender, pubKeys, ephemeralPubKey, plaintextPayload); + } + + + function respondToHandshake(bytes32 inResponseTo, bytes32 responderEphemeralR, bytes calldata ciphertext) external { + emit HandshakeResponse(inResponseTo, msg.sender, responderEphemeralR, ciphertext); + } + + /** + * @dev This empty reserved space allows future versions to add new variables + * without shifting down storage in the inheritance chain. + * @notice See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps + * @notice Reduced from 50 to 48 to account for pendingImplementation and upgradeEligibleAt + */ + uint256[48] private __gap; +} \ No newline at end of file diff --git a/packages/contracts/ignition/modules/LogChain.ts b/packages/contracts/ignition/modules/LogChain.ts deleted file mode 100644 index bcb6d5a..0000000 --- a/packages/contracts/ignition/modules/LogChain.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { buildModule } from "@nomicfoundation/hardhat-ignition/modules"; - -const LogChainModule = buildModule("LogChainModule", (m) => { - const logChainV1 = m.contract("LogChainV1"); - - const initCall = m.encodeFunctionCall(logChainV1, "initialize", []); - - const proxy = m.contract("ERC1967Proxy", [ - logChainV1, - initCall - ]); - - return { logChain: proxy, logChainImplementation: logChainV1 }; -}); - -export default LogChainModule; \ No newline at end of file diff --git a/packages/contracts/ignition/modules/Verbeth.ts b/packages/contracts/ignition/modules/Verbeth.ts new file mode 100644 index 0000000..44d4618 --- /dev/null +++ b/packages/contracts/ignition/modules/Verbeth.ts @@ -0,0 +1,16 @@ +import { buildModule } from "@nomicfoundation/hardhat-ignition/modules"; + +const VerbethModule = buildModule("VerbethModule", (m) => { + const verbEthV1 = m.contract("VerbethV1"); + + const initCall = m.encodeFunctionCall(verbEthV1, "initialize", []); + + const proxy = m.contract("ERC1967Proxy", [ + verbEthV1, + initCall + ]); + + return { verbEth: proxy, verbEthImplementation: verbEthV1 }; +}); + +export default VerbethModule; \ No newline at end of file diff --git a/packages/contracts/package.json b/packages/contracts/package.json index 2686614..628e2a5 100644 --- a/packages/contracts/package.json +++ b/packages/contracts/package.json @@ -2,7 +2,7 @@ "name": "@verbeth/contracts", "version": "0.1.0", "private": false, - "main": "contracts/LogChainV1.sol", + "main": "contracts/VerbethV1.sol", "devDependencies": { "@account-abstraction/contracts": "^0.8.0", "@nomicfoundation/hardhat-ignition": "^0.15.10", @@ -26,9 +26,9 @@ "scripts": { "build": "hardhat compile", "test": "hardhat test", - "deploy:local": "hardhat ignition deploy ignition/modules/LogChain.ts --network localhost --strategy create2", - "deploy:testnet": "hardhat ignition deploy ignition/modules/LogChain.ts --network baseSepolia --strategy create2", - "deploy:mainnet": "hardhat ignition deploy ignition/modules/LogChain.ts --network base --strategy create2", + "deploy:local": "hardhat ignition deploy ignition/modules/Verbeth.ts --network localhost --strategy create2", + "deploy:testnet": "hardhat ignition deploy ignition/modules/Verbeth.ts --network baseSepolia --strategy create2", + "deploy:mainnet": "hardhat ignition deploy ignition/modules/Verbeth.ts --network base --strategy create2", "deploy:mainnet:validator": "hardhat ignition deploy ignition/modules/UniversalSigValidator.ts --network base --strategy create2", "deploy:mainnet:session": "hardhat ignition deploy ignition/modules/SessionModule.ts --network base --strategy create2", "deploy:testnet:session": "hardhat ignition deploy ignition/modules/SessionModule.ts --network baseSepolia --strategy create2" diff --git a/packages/contracts/test/upgrade.test.ts b/packages/contracts/test/upgrade.test.ts index daf28b8..e49cc25 100644 --- a/packages/contracts/test/upgrade.test.ts +++ b/packages/contracts/test/upgrade.test.ts @@ -1,59 +1,51 @@ import { expect } from "chai"; // @ts-ignore -import { ethers, upgrades } from "hardhat"; -import { LogChainV1 } from "../typechain-types"; +import { ethers, upgrades, network } from "hardhat"; +import { VerbethV1 } from "../typechain-types"; -describe("LogChainV1 โ€“ย Upgradeability (UUPS)", function () { - let logChain: LogChainV1; +const TWO_DAYS = 2 * 24 * 60 * 60; + +describe("VerbethV1 โ€“ Upgradeability (UUPS)", function () { + let verbEth: VerbethV1; let owner: any; let attacker: any; beforeEach(async () => { [owner, attacker] = await ethers.getSigners(); - const Factory = await ethers.getContractFactory("LogChainV1"); - logChain = (await upgrades.deployProxy(Factory, [], { + const Factory = await ethers.getContractFactory("VerbethV1"); + verbEth = (await upgrades.deployProxy(Factory, [], { kind: "uups", initializer: "initialize", - })) as unknown as LogChainV1; + })) as unknown as VerbethV1; }); + async function advanceTime(seconds: number) { + await network.provider.send("evm_increaseTime", [seconds]); + await network.provider.send("evm_mine"); + } + it("is initialized correctly", async () => { - expect(await logChain.owner()).to.equal(await owner.getAddress()); + expect(await verbEth.owner()).to.equal(await owner.getAddress()); }); it("prevents reโ€‘initialization", async () => { await expect( - logChain.initialize() + verbEth.initialize() // @ts-ignore - ).to.be.revertedWithCustomError(logChain, "InvalidInitialization"); - }); - - it("only owner can perform upgrade", async () => { - const NewImplFactory = await ethers.getContractFactory("LogChainV1"); - const newImpl = await NewImplFactory.deploy(); - - await expect( - (logChain as any) - .connect(attacker) - .upgradeToAndCall(await newImpl.getAddress(), "0x") - // @ts-ignore - ).to.be.revertedWithCustomError(logChain, "OwnableUnauthorizedAccount"); - - await expect( - (logChain as any) - .connect(owner) - .upgradeToAndCall(await newImpl.getAddress(), "0x") - // @ts-ignore - ).to.not.be.reverted; + ).to.be.revertedWithCustomError(verbEth, "InvalidInitialization"); }); it("storage gap is preserved after upgrade", async () => { - const ImplV2 = await ethers.getContractFactory("LogChainV1"); + const ImplV2 = await ethers.getContractFactory("VerbethV1"); const newImpl = await ImplV2.deploy(); + // Propose and wait for timelock + await verbEth.proposeUpgrade(await newImpl.getAddress()); + await advanceTime(TWO_DAYS); + // Perform upgrade via UUPS entry point - await (logChain as any).upgradeToAndCall(await newImpl.getAddress(), "0x"); + await (verbEth as any).upgradeToAndCall(await newImpl.getAddress(), "0x"); // Ensure it's still functional const msg = ethers.encodeBytes32String("hi"); @@ -62,8 +54,192 @@ describe("LogChainV1 โ€“ย Upgradeability (UUPS)", function () { const nonce = 1; await expect( - logChain.sendMessage(msg, topic, timestamp, nonce) + verbEth.sendMessage(msg, topic, timestamp, nonce) + // @ts-ignore + ).to.emit(verbEth, "MessageSent"); + }); + + describe("Upgrade Timelock", function () { + let newImpl: any; + + beforeEach(async () => { + const NewImplFactory = await ethers.getContractFactory("VerbethV1"); + newImpl = await NewImplFactory.deploy(); + }); + + it("UPGRADE_DELAY is 2 days", async () => { + expect(await verbEth.UPGRADE_DELAY()).to.equal(TWO_DAYS); + }); + + it("proposeUpgrade sets pending implementation and eligibleAt", async () => { + const implAddress = await newImpl.getAddress(); + const tx = await verbEth.proposeUpgrade(implAddress); + const receipt = await tx.wait(); + const block = await ethers.provider.getBlock(receipt!.blockNumber); + + expect(await verbEth.pendingImplementation()).to.equal(implAddress); + expect(await verbEth.upgradeEligibleAt()).to.equal( + block!.timestamp + TWO_DAYS + ); + }); + + it("proposeUpgrade emits UpgradeProposed event", async () => { + const implAddress = await newImpl.getAddress(); + await expect(verbEth.proposeUpgrade(implAddress)) + // @ts-ignore + .to.emit(verbEth, "UpgradeProposed") + .withArgs(implAddress, (value: any) => value > 0); + }); + + it("proposeUpgrade reverts for zero address", async () => { + await expect( + verbEth.proposeUpgrade(ethers.ZeroAddress) + // @ts-ignore + ).to.be.revertedWith("Invalid implementation"); + }); + + it("only owner can propose upgrade", async () => { + await expect( + verbEth.connect(attacker).proposeUpgrade(await newImpl.getAddress()) + // @ts-ignore + ).to.be.revertedWithCustomError(verbEth, "OwnableUnauthorizedAccount"); + }); + + it("cancelUpgrade clears pending implementation", async () => { + const implAddress = await newImpl.getAddress(); + await verbEth.proposeUpgrade(implAddress); + + await expect(verbEth.cancelUpgrade()) + // @ts-ignore + .to.emit(verbEth, "UpgradeCancelled") + .withArgs(implAddress); + + expect(await verbEth.pendingImplementation()).to.equal(ethers.ZeroAddress); + expect(await verbEth.upgradeEligibleAt()).to.equal(0); + }); + + it("cancelUpgrade reverts when no pending upgrade", async () => { // @ts-ignore - ).to.emit(logChain, "MessageSent"); + await expect(verbEth.cancelUpgrade()).to.be.revertedWith( + "No pending upgrade" + ); + }); + + it("only owner can cancel upgrade", async () => { + await verbEth.proposeUpgrade(await newImpl.getAddress()); + + await expect( + verbEth.connect(attacker).cancelUpgrade() + // @ts-ignore + ).to.be.revertedWithCustomError(verbEth, "OwnableUnauthorizedAccount"); + }); + + it("upgrade reverts before timelock expires", async () => { + const implAddress = await newImpl.getAddress(); + await verbEth.proposeUpgrade(implAddress); + + await expect( + (verbEth as any).upgradeToAndCall(implAddress, "0x") + // @ts-ignore + ).to.be.revertedWith("Timelock not expired"); + + // Advance time but not enough + await advanceTime(TWO_DAYS - 100); + + await expect( + (verbEth as any).upgradeToAndCall(implAddress, "0x") + // @ts-ignore + ).to.be.revertedWith("Timelock not expired"); + }); + + it("upgrade reverts for non-proposed implementation", async () => { + const implAddress = await newImpl.getAddress(); + await verbEth.proposeUpgrade(implAddress); + await advanceTime(TWO_DAYS); + + const OtherImplFactory = await ethers.getContractFactory("VerbethV1"); + const otherImpl = await OtherImplFactory.deploy(); + + await expect( + (verbEth as any).upgradeToAndCall(await otherImpl.getAddress(), "0x") + // @ts-ignore + ).to.be.revertedWith("Not proposed implementation"); + }); + + it("upgrade reverts when no upgrade is proposed", async () => { + await expect( + (verbEth as any).upgradeToAndCall(await newImpl.getAddress(), "0x") + // @ts-ignore + ).to.be.revertedWith("Not proposed implementation"); + }); + + it("upgrade succeeds after timelock expires", async () => { + const implAddress = await newImpl.getAddress(); + await verbEth.proposeUpgrade(implAddress); + + // Advance time past the timelock + await advanceTime(TWO_DAYS + 1); + + await expect( + (verbEth as any).upgradeToAndCall(implAddress, "0x") + // @ts-ignore + ).to.not.be.reverted; + + // Verify pending state is cleared + expect(await verbEth.pendingImplementation()).to.equal(ethers.ZeroAddress); + expect(await verbEth.upgradeEligibleAt()).to.equal(0); + }); + + it("only owner can perform upgrade", async () => { + const implAddress = await newImpl.getAddress(); + await verbEth.proposeUpgrade(implAddress); + await advanceTime(TWO_DAYS); + + await expect( + (verbEth as any).connect(attacker).upgradeToAndCall(implAddress, "0x") + // @ts-ignore + ).to.be.revertedWithCustomError(verbEth, "OwnableUnauthorizedAccount"); + }); + + it("can propose new upgrade after cancellation", async () => { + const implAddress = await newImpl.getAddress(); + await verbEth.proposeUpgrade(implAddress); + await verbEth.cancelUpgrade(); + + // Propose again + await expect(verbEth.proposeUpgrade(implAddress)) + // @ts-ignore + .to.emit(verbEth, "UpgradeProposed"); + + expect(await verbEth.pendingImplementation()).to.equal(implAddress); + }); + + it("can propose new upgrade replacing previous proposal", async () => { + const implAddress = await newImpl.getAddress(); + await verbEth.proposeUpgrade(implAddress); + + // Deploy another implementation + const OtherImplFactory = await ethers.getContractFactory("VerbethV1"); + const otherImpl = await OtherImplFactory.deploy(); + const otherAddress = await otherImpl.getAddress(); + + // Propose the new one (replaces the previous) + await verbEth.proposeUpgrade(otherAddress); + + expect(await verbEth.pendingImplementation()).to.equal(otherAddress); + + // Old implementation should not work even after timelock + await advanceTime(TWO_DAYS); + await expect( + (verbEth as any).upgradeToAndCall(implAddress, "0x") + // @ts-ignore + ).to.be.revertedWith("Not proposed implementation"); + + // New implementation should work + await expect( + (verbEth as any).upgradeToAndCall(otherAddress, "0x") + // @ts-ignore + ).to.not.be.reverted; + }); }); }); diff --git a/packages/contracts/test/logchain.test.ts b/packages/contracts/test/verbeth.test.ts similarity index 76% rename from packages/contracts/test/logchain.test.ts rename to packages/contracts/test/verbeth.test.ts index 8f7bb3f..6f791d1 100644 --- a/packages/contracts/test/logchain.test.ts +++ b/packages/contracts/test/verbeth.test.ts @@ -1,15 +1,15 @@ // @ts-ignore import { ethers } from "hardhat"; import { expect } from "chai"; -import { LogChainV1 } from "../typechain-types"; +import { VerbethV1 } from "../typechain-types"; -describe("LogChain", () => { - let logChain: LogChainV1; +describe("Verbeth", () => { + let verbEth: VerbethV1; beforeEach(async () => { - const factory = await ethers.getContractFactory("LogChainV1"); - logChain = (await factory.deploy()) as LogChainV1; - await logChain.waitForDeployment(); + const factory = await ethers.getContractFactory("VerbethV1"); + verbEth = (await factory.deploy()) as VerbethV1; + await verbEth.waitForDeployment(); }); it("should emit a MessageSent event", async () => { @@ -20,9 +20,9 @@ describe("LogChain", () => { const timestamp = Math.floor(Date.now() / 1000); const nonce = 1; - await expect(logChain.sendMessage(msg, topic, timestamp, nonce)) + await expect(verbEth.sendMessage(msg, topic, timestamp, nonce)) // @ts-ignore - .to.emit(logChain, "MessageSent") + .to.emit(verbEth, "MessageSent") .withArgs(await sender.getAddress(), msg, timestamp, topic, nonce); }); @@ -34,8 +34,8 @@ describe("LogChain", () => { const timestamp = Math.floor(Date.now() / 1000); const nonce = 42; - await logChain.sendMessage(msg, topic, timestamp, nonce); - await logChain.sendMessage(msg, topic, timestamp + 1, nonce); // re-use same nonce, no revert + await verbEth.sendMessage(msg, topic, timestamp, nonce); + await verbEth.sendMessage(msg, topic, timestamp + 1, nonce); // re-use same nonce, no revert }); it("should emit a Handshake event", async () => { @@ -50,7 +50,7 @@ describe("LogChain", () => { const plaintextPayload = ethers.toUtf8Bytes("Hi Bob, respond pls"); await expect( - logChain.initiateHandshake( + verbEth.initiateHandshake( recipientHash, unifiedPubKeys, ephemeralPubKey, @@ -58,7 +58,7 @@ describe("LogChain", () => { ) ) // @ts-ignore - .to.emit(logChain, "Handshake") + .to.emit(verbEth, "Handshake") .withArgs( recipientHash, recipient, @@ -78,14 +78,14 @@ describe("LogChain", () => { const responseCiphertext = ethers.hexlify(ethers.randomBytes(64)); await expect( - logChain.respondToHandshake( + verbEth.respondToHandshake( inResponseTo, responderEphemeralR, responseCiphertext ) ) // @ts-ignore - .to.emit(logChain, "HandshakeResponse") + .to.emit(verbEth, "HandshakeResponse") .withArgs( inResponseTo, await bob.getAddress(), diff --git a/packages/sdk/README.md b/packages/sdk/README.md index 907e744..92720a5 100644 --- a/packages/sdk/README.md +++ b/packages/sdk/README.md @@ -12,7 +12,7 @@ npm install @verbeth/sdk import { createVerbethClient, deriveIdentityKeyPairWithProof, ExecutorFactory } from '@verbeth/sdk'; import { ethers } from 'ethers'; -const LOGCHAIN = '0x62720f39d5Ec6501508bDe4D152c1E13Fd2F6707'; +const VERBETH = '0x51670aB6eDE1d1B11C654CCA53b7D42080802326'; const provider = new ethers.BrowserProvider(window.ethereum); const signer = await provider.getSigner(); @@ -20,7 +20,7 @@ const address = await signer.getAddress(); const { identityKeyPair, identityProof } = await deriveIdentityKeyPairWithProof(signer, address); -const contract = new ethers.Contract(LOGCHAIN, LogChainABI, signer); +const contract = new ethers.Contract(VERBETH, VerbethABI, signer); const client = createVerbethClient({ address, signer, diff --git a/packages/sdk/src/executor.ts b/packages/sdk/src/executor.ts index 737ce10..bba9ec0 100644 --- a/packages/sdk/src/executor.ts +++ b/packages/sdk/src/executor.ts @@ -14,7 +14,7 @@ import { UserOpV07, PackedUserOperation, } from "./types.js"; -import type { LogChainV1 } from "@verbeth/contracts/typechain-types"; +import type { VerbethV1 } from "@verbeth/contracts/typechain-types"; function pack128x128(high: bigint, low: bigint): bigint { return (high << 128n) | (low & ((1n << 128n) - 1n)); @@ -73,7 +73,7 @@ export interface IExecutor { // EOA Executor - Direct contract calls via wallet signer export class EOAExecutor implements IExecutor { - constructor(private contract: LogChainV1) {} + constructor(private contract: VerbethV1) {} async sendMessage( ciphertext: Uint8Array, @@ -109,17 +109,17 @@ export class EOAExecutor implements IExecutor { // Base Smart Account Executor - Uses wallet_sendCalls for sponsored transactions export class BaseSmartAccountExecutor implements IExecutor { - private logChainInterface: Interface; + private verbEthInterface: Interface; private chainId: string; constructor( private baseAccountProvider: any, - private logChainAddress: string, + private verbEthAddress: string, chainId = 8453, private paymasterServiceUrl?: string, private subAccountAddress?: string ) { - this.logChainInterface = new Interface([ + this.verbEthInterface = new Interface([ "function sendMessage(bytes calldata ciphertext, bytes32 topic, uint256 timestamp, uint256 nonce)", "function initiateHandshake(bytes32 recipientHash, bytes pubKeys, bytes ephemeralPubKey, bytes plaintextPayload)", "function respondToHandshake(bytes32 inResponseTo, bytes32 responderEphemeralR, bytes ciphertext)", @@ -139,7 +139,7 @@ export class BaseSmartAccountExecutor implements IExecutor { timestamp: number, nonce: bigint ): Promise { - const callData = this.logChainInterface.encodeFunctionData("sendMessage", [ + const callData = this.verbEthInterface.encodeFunctionData("sendMessage", [ ciphertext, topic, timestamp, @@ -148,7 +148,7 @@ export class BaseSmartAccountExecutor implements IExecutor { return this.executeCalls([ { - to: this.logChainAddress, + to: this.verbEthAddress, value: "0x0", data: callData, }, @@ -161,14 +161,14 @@ export class BaseSmartAccountExecutor implements IExecutor { ephemeralPubKey: string, plaintextPayload: Uint8Array ): Promise { - const callData = this.logChainInterface.encodeFunctionData( + const callData = this.verbEthInterface.encodeFunctionData( "initiateHandshake", [recipientHash, pubKeys, ephemeralPubKey, plaintextPayload] ); return this.executeCalls([ { - to: this.logChainAddress, + to: this.verbEthAddress, value: "0x0", data: callData, }, @@ -180,14 +180,14 @@ export class BaseSmartAccountExecutor implements IExecutor { responderEphemeralR: string, ciphertext: Uint8Array ): Promise { - const callData = this.logChainInterface.encodeFunctionData( + const callData = this.verbEthInterface.encodeFunctionData( "respondToHandshake", [inResponseTo, responderEphemeralR, ciphertext] ); return this.executeCalls([ { - to: this.logChainAddress, + to: this.verbEthAddress, value: "0x0", data: callData, }, @@ -241,16 +241,16 @@ export class BaseSmartAccountExecutor implements IExecutor { // UserOp Executor - Account Abstraction via bundler export class UserOpExecutor implements IExecutor { - private logChainInterface: Interface; + private verbEthInterface: Interface; private smartAccountInterface: Interface; constructor( private smartAccountAddress: string, - private logChainAddress: string, + private verbEthAddress: string, private bundlerClient: any, private smartAccountClient: any ) { - this.logChainInterface = new Interface([ + this.verbEthInterface = new Interface([ "function sendMessage(bytes calldata ciphertext, bytes32 topic, uint256 timestamp, uint256 nonce)", "function initiateHandshake(bytes32 recipientHash, bytes pubKeys, bytes ephemeralPubKey, bytes plaintextPayload)", "function respondToHandshake(bytes32 inResponseTo, bytes32 responderEphemeralR, bytes ciphertext)", @@ -267,7 +267,7 @@ export class UserOpExecutor implements IExecutor { timestamp: number, nonce: bigint ): Promise { - const logChainCallData = this.logChainInterface.encodeFunctionData( + const verbEthCallData = this.verbEthInterface.encodeFunctionData( "sendMessage", [ciphertext, topic, timestamp, nonce] ); @@ -275,9 +275,9 @@ export class UserOpExecutor implements IExecutor { const smartAccountCallData = this.smartAccountInterface.encodeFunctionData( "execute", [ - this.logChainAddress, + this.verbEthAddress, 0, - logChainCallData, + verbEthCallData, ] ); @@ -290,7 +290,7 @@ export class UserOpExecutor implements IExecutor { ephemeralPubKey: string, plaintextPayload: Uint8Array ): Promise { - const logChainCallData = this.logChainInterface.encodeFunctionData( + const verbEthCallData = this.verbEthInterface.encodeFunctionData( "initiateHandshake", [recipientHash, pubKeys, ephemeralPubKey, plaintextPayload] ); @@ -298,9 +298,9 @@ export class UserOpExecutor implements IExecutor { const smartAccountCallData = this.smartAccountInterface.encodeFunctionData( "execute", [ - this.logChainAddress, + this.verbEthAddress, 0, - logChainCallData, + verbEthCallData, ] ); @@ -312,7 +312,7 @@ export class UserOpExecutor implements IExecutor { responderEphemeralR: string, ciphertext: Uint8Array ): Promise { - const logChainCallData = this.logChainInterface.encodeFunctionData( + const verbEthCallData = this.verbEthInterface.encodeFunctionData( "respondToHandshake", [inResponseTo, responderEphemeralR, ciphertext] ); @@ -320,9 +320,9 @@ export class UserOpExecutor implements IExecutor { const smartAccountCallData = this.smartAccountInterface.encodeFunctionData( "execute", [ - this.logChainAddress, + this.verbEthAddress, 0, - logChainCallData, + verbEthCallData, ] ); @@ -363,7 +363,7 @@ export class UserOpExecutor implements IExecutor { // Direct EntryPoint Executor (bypasses bundler for local testing) export class DirectEntryPointExecutor implements IExecutor { - private logChainInterface: Interface; + private verbEthInterface: Interface; private smartAccountInterface: Interface; private entryPointContract: Contract; private spec: AASpecVersion; @@ -371,11 +371,11 @@ export class DirectEntryPointExecutor implements IExecutor { constructor( private smartAccountAddress: string, entryPointContract: Contract | BaseContract, - private logChainAddress: string, + private verbEthAddress: string, private smartAccountClient: any, private signer: Signer ) { - this.logChainInterface = new Interface([ + this.verbEthInterface = new Interface([ "function sendMessage(bytes calldata ciphertext, bytes32 topic, uint256 timestamp, uint256 nonce)", "function initiateHandshake(bytes32 recipientHash, bytes pubKeys, bytes ephemeralPubKey, bytes plaintextPayload)", "function respondToHandshake(bytes32 inResponseTo, bytes32 responderEphemeralR, bytes ciphertext)", @@ -395,7 +395,7 @@ export class DirectEntryPointExecutor implements IExecutor { timestamp: number, nonce: bigint ): Promise { - const logChainCallData = this.logChainInterface.encodeFunctionData( + const verbEthCallData = this.verbEthInterface.encodeFunctionData( "sendMessage", [ciphertext, topic, timestamp, nonce] ); @@ -403,9 +403,9 @@ export class DirectEntryPointExecutor implements IExecutor { const smartAccountCallData = this.smartAccountInterface.encodeFunctionData( "execute", [ - this.logChainAddress, + this.verbEthAddress, 0, // value - logChainCallData, + verbEthCallData, ] ); @@ -418,7 +418,7 @@ export class DirectEntryPointExecutor implements IExecutor { ephemeralPubKey: string, plaintextPayload: Uint8Array ): Promise { - const logChainCallData = this.logChainInterface.encodeFunctionData( + const verbEthCallData = this.verbEthInterface.encodeFunctionData( "initiateHandshake", [recipientHash, pubKeys, ephemeralPubKey, plaintextPayload] ); @@ -426,9 +426,9 @@ export class DirectEntryPointExecutor implements IExecutor { const smartAccountCallData = this.smartAccountInterface.encodeFunctionData( "execute", [ - this.logChainAddress, + this.verbEthAddress, 0, - logChainCallData, + verbEthCallData, ] ); @@ -440,7 +440,7 @@ export class DirectEntryPointExecutor implements IExecutor { responderEphemeralR: string, ciphertext: Uint8Array ): Promise { - const logChainCallData = this.logChainInterface.encodeFunctionData( + const verbEthCallData = this.verbEthInterface.encodeFunctionData( "respondToHandshake", [inResponseTo, responderEphemeralR, ciphertext] ); @@ -448,9 +448,9 @@ export class DirectEntryPointExecutor implements IExecutor { const smartAccountCallData = this.smartAccountInterface.encodeFunctionData( "execute", [ - this.logChainAddress, + this.verbEthAddress, 0, - logChainCallData, + verbEthCallData, ] ); @@ -509,20 +509,20 @@ export class DirectEntryPointExecutor implements IExecutor { } export class ExecutorFactory { - static createEOA(contract: LogChainV1): IExecutor { + static createEOA(contract: VerbethV1): IExecutor { return new EOAExecutor(contract); } static createBaseSmartAccount( baseAccountProvider: any, - logChainAddress: string, + verbEthAddress: string, chainId = 8453, paymasterServiceUrl?: string, subAccountAddress?: string ): IExecutor { return new BaseSmartAccountExecutor( baseAccountProvider, - logChainAddress, + verbEthAddress, chainId, paymasterServiceUrl, subAccountAddress @@ -532,13 +532,13 @@ export class ExecutorFactory { static createUserOp( smartAccountAddress: string, _entryPointAddress: string, - logChainAddress: string, + verbEthAddress: string, bundlerClient: any, smartAccountClient: any ): IExecutor { return new UserOpExecutor( smartAccountAddress, - logChainAddress, + verbEthAddress, bundlerClient, smartAccountClient ); @@ -547,14 +547,14 @@ export class ExecutorFactory { static createDirectEntryPoint( smartAccountAddress: string, entryPointContract: Contract | BaseContract, - logChainAddress: string, + verbEthAddress: string, smartAccountClient: any, signer: Signer ): IExecutor { return new DirectEntryPointExecutor( smartAccountAddress, entryPointContract, - logChainAddress, + verbEthAddress, smartAccountClient, signer ); @@ -563,21 +563,21 @@ export class ExecutorFactory { // Auto-detect executor based on environment and signer type static async createAuto( signerOrAccount: any, - contract: LogChainV1, + contract: VerbethV1, options?: { entryPointAddress?: string; entryPointContract?: Contract | BaseContract; - logChainAddress?: string; + verbEthAddress?: string; bundlerClient?: any; baseAccountProvider?: any; chainId?: number; isTestEnvironment?: boolean; } ): Promise { - if (options?.baseAccountProvider && options?.logChainAddress) { + if (options?.baseAccountProvider && options?.verbEthAddress) { return new BaseSmartAccountExecutor( options.baseAccountProvider, - options.logChainAddress, + options.verbEthAddress, options.chainId || 8453 ); } @@ -592,11 +592,11 @@ export class ExecutorFactory { }) .catch(() => null); - if (capabilities && options?.logChainAddress) { + if (capabilities && options?.verbEthAddress) { // if wallet supports capabilities, it's likely a Base Smart Account return new BaseSmartAccountExecutor( provider, - options.logChainAddress, + options.verbEthAddress, options.chainId || 8453 ); } @@ -610,12 +610,12 @@ export class ExecutorFactory { if ( options.isTestEnvironment && options.entryPointContract && - options.logChainAddress + options.verbEthAddress ) { return new DirectEntryPointExecutor( signerOrAccount.address, options.entryPointContract, - options.logChainAddress, + options.verbEthAddress, signerOrAccount, signerOrAccount.signer || signerOrAccount ); @@ -624,11 +624,11 @@ export class ExecutorFactory { if ( options.bundlerClient && options.entryPointAddress && - options.logChainAddress + options.verbEthAddress ) { return new UserOpExecutor( signerOrAccount.address, - options.logChainAddress, + options.verbEthAddress, options.bundlerClient, signerOrAccount ); diff --git a/packages/sdk/src/utils/safeSessionSigner.ts b/packages/sdk/src/utils/safeSessionSigner.ts index 25e461d..d2774fb 100644 --- a/packages/sdk/src/utils/safeSessionSigner.ts +++ b/packages/sdk/src/utils/safeSessionSigner.ts @@ -14,7 +14,7 @@ export interface SafeSessionSignerOptions { provider: Provider; safeAddress: string; moduleAddress: string; - logChainAddress: string; + verbEthAddress: string; sessionSigner: Signer; } @@ -60,7 +60,7 @@ export class SafeSessionSigner extends AbstractSigner { } async isTargetAllowed(): Promise { - return this.module.isAllowedTarget(this.opts.safeAddress, this.opts.logChainAddress); + return this.module.isAllowedTarget(this.opts.safeAddress, this.opts.verbEthAddress); } override async signMessage(message: string | Uint8Array): Promise { @@ -87,10 +87,10 @@ export class SafeSessionSigner extends AbstractSigner { if (!tx.to) throw new Error("SafeSessionSigner: tx.to required"); const to = String(tx.to).toLowerCase(); - const logChain = this.opts.logChainAddress.toLowerCase(); + const verbEth = this.opts.verbEthAddress.toLowerCase(); - if (to !== logChain) { - throw new Error(`SafeSessionSigner: only LogChain txs allowed. Got ${tx.to}`); + if (to !== verbEth) { + throw new Error(`SafeSessionSigner: only verbEth txs allowed. Got ${tx.to}`); } const data = tx.data ?? "0x"; @@ -98,7 +98,7 @@ export class SafeSessionSigner extends AbstractSigner { // execute(safe, to, value, data, operation) return this.module.execute( this.opts.safeAddress, - this.opts.logChainAddress, + this.opts.verbEthAddress, 0n, data, 0 diff --git a/packages/sdk/test/executor.test.ts b/packages/sdk/test/executor.test.ts index 420f98e..a753972 100644 --- a/packages/sdk/test/executor.test.ts +++ b/packages/sdk/test/executor.test.ts @@ -9,13 +9,13 @@ import { initiateHandshake, respondToHandshake, } from "../src/index.js"; -import type { LogChainV1 } from "@verbeth/contracts/typechain-types"; +import type { VerbethV1 } from "@verbeth/contracts/typechain-types"; import { IdentityKeyPair, IdentityProof } from "../src/types.js"; import { kem } from "../src/pq/kem.js"; const TEST_SMART_ACCOUNT_ADDRESS = "0x" + "12".repeat(20); const TEST_ENTRYPOINT_ADDRESS = "0x" + "45".repeat(20); -const TEST_LOGCHAIN_ADDRESS = "0x" + "78".repeat(20); +const TEST_VERBETH_ADDRESS = "0x" + "78".repeat(20); const mockSendMessage = vi.fn().mockResolvedValue("txHash"); const mockInitiateHandshake = vi.fn().mockResolvedValue("txHash"); @@ -25,7 +25,7 @@ const fakeContract = { sendMessage: mockSendMessage, initiateHandshake: mockInitiateHandshake, respondToHandshake: mockRespondToHandshake, -} as unknown as LogChainV1; +} as unknown as VerbethV1; const mockBundler = { sendUserOperation: vi.fn().mockResolvedValue("0x123"), @@ -81,7 +81,7 @@ describe("ExecutorFactory", () => { const executor = ExecutorFactory.createUserOp( TEST_SMART_ACCOUNT_ADDRESS, TEST_ENTRYPOINT_ADDRESS, - TEST_LOGCHAIN_ADDRESS, + TEST_VERBETH_ADDRESS, mockBundler, mockSmartAccount ); @@ -92,7 +92,7 @@ describe("ExecutorFactory", () => { const executor = ExecutorFactory.createDirectEntryPoint( TEST_SMART_ACCOUNT_ADDRESS, mockEntryPoint, - TEST_LOGCHAIN_ADDRESS, + TEST_VERBETH_ADDRESS, mockSmartAccount, mockSigner ); @@ -131,7 +131,7 @@ describe("initiateHandshake with Executors", () => { const executor = ExecutorFactory.createUserOp( TEST_SMART_ACCOUNT_ADDRESS, TEST_ENTRYPOINT_ADDRESS, - TEST_LOGCHAIN_ADDRESS, + TEST_VERBETH_ADDRESS, mockBundler, mockSmartAccount ); @@ -154,7 +154,7 @@ describe("initiateHandshake with Executors", () => { const executor = ExecutorFactory.createDirectEntryPoint( TEST_SMART_ACCOUNT_ADDRESS, mockEntryPoint, - TEST_LOGCHAIN_ADDRESS, + TEST_VERBETH_ADDRESS, mockSmartAccount, mockSigner ); @@ -208,7 +208,7 @@ describe("respondToHandshake with Executors", () => { const executor = ExecutorFactory.createUserOp( TEST_SMART_ACCOUNT_ADDRESS, TEST_ENTRYPOINT_ADDRESS, - TEST_LOGCHAIN_ADDRESS, + TEST_VERBETH_ADDRESS, mockBundler, mockSmartAccount ); @@ -231,7 +231,7 @@ describe("respondToHandshake with Executors", () => { const executor = ExecutorFactory.createDirectEntryPoint( TEST_SMART_ACCOUNT_ADDRESS, mockEntryPoint, - TEST_LOGCHAIN_ADDRESS, + TEST_VERBETH_ADDRESS, mockSmartAccount, mockSigner ); diff --git a/packages/sdk/test/utils.test.ts b/packages/sdk/test/utils.test.ts index 46e030f..0ad05c4 100644 --- a/packages/sdk/test/utils.test.ts +++ b/packages/sdk/test/utils.test.ts @@ -5,7 +5,7 @@ import { JsonRpcProvider } from "ethers"; import { convertPublicKeyToX25519 } from "../src/utils/x25519.js"; import { isSmartContract1271, parseBindingMessage } from "../src/utils.js"; import { ExecutorFactory } from "../src/index.js"; -import type { LogChainV1 } from "@verbeth/contracts/typechain-types"; +import type { VerbethV1 } from "@verbeth/contracts/typechain-types"; const fakeProvider = { async getCode(addr: string) { diff --git a/tests/e2e.test.ts b/tests/e2e.test.ts index 15302f0..c7da686 100644 --- a/tests/e2e.test.ts +++ b/tests/e2e.test.ts @@ -28,8 +28,8 @@ import { ERC1967Proxy__factory, EntryPoint__factory, type EntryPoint, - LogChainV1__factory, - type LogChainV1, + VerbethV1__factory, + type VerbethV1, TestSmartAccount__factory, type TestSmartAccount, } from "../packages/contracts/typechain-types/index.js"; @@ -67,7 +67,7 @@ describe("End-to-End Handshake and Messaging Tests", () => { let anvil: AnvilSetup; let provider: JsonRpcProvider; let entryPoint: EntryPoint; - let logChain: LogChainV1; + let VERBETH: VerbethV1; let smartAccount: TestSmartAccount; let deployer: Wallet; let smartAccountOwner: Wallet; @@ -109,25 +109,25 @@ describe("End-to-End Handshake and Messaging Tests", () => { entryPoint = EntryPoint__factory.connect(ENTRYPOINT_ADDR, provider); - const logChainFactory = new LogChainV1__factory(deployer); - const logChainImpl = await logChainFactory.deploy(); - await logChainImpl.deploymentTransaction()?.wait(); + const VERBETHFactory = new VerbethV1__factory(deployer); + const VERBETHImpl = await VERBETHFactory.deploy(); + await VERBETHImpl.deploymentTransaction()?.wait(); await new Promise((resolve) => setTimeout(resolve, 200)); - const initData = logChainFactory.interface.encodeFunctionData( + const initData = VERBETHFactory.interface.encodeFunctionData( "initialize", [] ); const proxyFactory = new ERC1967Proxy__factory(deployer); const proxy = await proxyFactory.deploy( - await logChainImpl.getAddress(), + await VERBETHImpl.getAddress(), initData ); await proxy.deploymentTransaction()?.wait(); - logChain = LogChainV1__factory.connect(await proxy.getAddress(), deployer); + VERBETH = VERBETHV1__factory.connect(await proxy.getAddress(), deployer); await new Promise((resolve) => setTimeout(resolve, 200)); @@ -206,17 +206,17 @@ describe("End-to-End Handshake and Messaging Tests", () => { smartAccountExecutor = ExecutorFactory.createDirectEntryPoint( await smartAccount.getAddress(), entryPoint.connect(bundler) as unknown as Contract, - await logChain.getAddress(), + await VERBETH.getAddress(), createMockSmartAccountClient(smartAccount, smartAccountOwner), bundler ) as DirectEntryPointExecutor; eoaAccount1Executor = ExecutorFactory.createEOA( - logChain.connect(eoaAccount1) + VERBETH.connect(eoaAccount1) ) as EOAExecutor; eoaAccount2Executor = ExecutorFactory.createEOA( - logChain.connect(eoaAccount2) + VERBETH.connect(eoaAccount2) ) as EOAExecutor; }); @@ -242,8 +242,8 @@ describe("End-to-End Handshake and Messaging Tests", () => { } // 2. Verify handshake identity - const handshakeFilter = logChain.filters.Handshake(); - const handshakeEvents = await logChain.queryFilter( + const handshakeFilter = VERBETH.filters.Handshake(); + const handshakeEvents = await VERBETH.queryFilter( handshakeFilter, initiateReceipt.blockNumber, initiateReceipt.blockNumber @@ -285,8 +285,8 @@ describe("End-to-End Handshake and Messaging Tests", () => { } // 4. Verify handshake response identity - const responseFilter = logChain.filters.HandshakeResponse(); - const responseEvents = await logChain.queryFilter( + const responseFilter = VERBETH.filters.HandshakeResponse(); + const responseEvents = await VERBETH.queryFilter( responseFilter, respondReceipt.blockNumber, respondReceipt.blockNumber @@ -363,15 +363,15 @@ describe("End-to-End Handshake and Messaging Tests", () => { } // 7. Verify both messages can be decrypted - const messageFilter = logChain.filters.MessageSent(); + const messageFilter = VERBETH.filters.MessageSent(); - const saMessageEvents = await logChain.queryFilter( + const saMessageEvents = await VERBETH.queryFilter( messageFilter, sendReceipt1.blockNumber, sendReceipt1.blockNumber ); - const eoaMessageEvents = await logChain.queryFilter( + const eoaMessageEvents = await VERBETH.queryFilter( messageFilter, sendReceipt2.blockNumber, sendReceipt2.blockNumber @@ -454,8 +454,8 @@ describe("End-to-End Handshake and Messaging Tests", () => { } // 2. Verify handshake identity - const handshakeFilter = logChain.filters.Handshake(); - const handshakeEvents = await logChain.queryFilter( + const handshakeFilter = VERBETH.filters.Handshake(); + const handshakeEvents = await VERBETH.queryFilter( handshakeFilter, initiateReceipt.blockNumber, initiateReceipt.blockNumber @@ -497,8 +497,8 @@ describe("End-to-End Handshake and Messaging Tests", () => { } // 4. Verify handshake response identity - const responseFilter = logChain.filters.HandshakeResponse(); - const responseEvents = await logChain.queryFilter( + const responseFilter = VERBETH.filters.HandshakeResponse(); + const responseEvents = await VERBETH.queryFilter( responseFilter, respondReceipt.blockNumber, respondReceipt.blockNumber @@ -575,15 +575,15 @@ describe("End-to-End Handshake and Messaging Tests", () => { } // 7. Verify both messages can be decrypted - const messageFilter = logChain.filters.MessageSent(); + const messageFilter = VERBETH.filters.MessageSent(); - const eoaMessageEvents = await logChain.queryFilter( + const eoaMessageEvents = await VERBETH.queryFilter( messageFilter, sendReceipt1.blockNumber, sendReceipt1.blockNumber ); - const saMessageEvents = await logChain.queryFilter( + const saMessageEvents = await VERBETH.queryFilter( messageFilter, sendReceipt2.blockNumber, sendReceipt2.blockNumber diff --git a/tests/handshaking.test.ts b/tests/handshaking.test.ts index a57af33..bb1855a 100644 --- a/tests/handshaking.test.ts +++ b/tests/handshaking.test.ts @@ -27,8 +27,8 @@ import { ERC1967Proxy__factory, EntryPoint__factory, type EntryPoint, - LogChainV1__factory, - type LogChainV1, + VerbethV1__factory, + type VerbethV1, TestSmartAccount__factory, type TestSmartAccount, } from "../packages/contracts/typechain-types/index.js"; @@ -41,7 +41,7 @@ describe("Smart Account Handshake Response via Direct EntryPoint", () => { let anvil: AnvilSetup; let provider: JsonRpcProvider; let entryPoint: EntryPoint; - let logChain: LogChainV1; + let verbEth: VerbethV1; let testSmartAccount: TestSmartAccount; let responderSmartAccount: TestSmartAccount; let executor: DirectEntryPointExecutor; @@ -88,24 +88,24 @@ describe("Smart Account Handshake Response via Direct EntryPoint", () => { entryPoint = EntryPoint__factory.connect(ENTRYPOINT_ADDR, provider); - const logChainFactory = new LogChainV1__factory(deployer); - const logChainImpl = await logChainFactory.deploy(); - await logChainImpl.deploymentTransaction()?.wait(); + const verbEthFactory = new VerbethV1__factory(deployer); + const verbEthImpl = await verbEthFactory.deploy(); + await verbEthImpl.deploymentTransaction()?.wait(); await new Promise((resolve) => setTimeout(resolve, 200)); - const initData = logChainFactory.interface.encodeFunctionData( + const initData = verbEthFactory.interface.encodeFunctionData( "initialize", [] ); const proxyFactory = new ERC1967Proxy__factory(deployer); const proxy = await proxyFactory.deploy( - await logChainImpl.getAddress(), + await verbEthImpl.getAddress(), initData ); await proxy.deploymentTransaction()?.wait(); - logChain = LogChainV1__factory.connect(await proxy.getAddress(), deployer); + verbEth = VerbethV1__factory.connect(await proxy.getAddress(), deployer); await new Promise((resolve) => setTimeout(resolve, 200)); @@ -195,7 +195,7 @@ describe("Smart Account Handshake Response via Direct EntryPoint", () => { executor = ExecutorFactory.createDirectEntryPoint( await testSmartAccount.getAddress(), entryPoint.connect(initiatorBundler) as unknown as Contract, - await logChain.getAddress(), + await verbEth.getAddress(), createMockSmartAccountClient(testSmartAccount, smartAccountOwner), initiatorBundler // Use initiatorBundler ) as DirectEntryPointExecutor; @@ -203,7 +203,7 @@ describe("Smart Account Handshake Response via Direct EntryPoint", () => { responderExecutor = ExecutorFactory.createDirectEntryPoint( await responderSmartAccount.getAddress(), entryPoint.connect(responderBundler) as unknown as Contract, - await logChain.getAddress(), + await verbEth.getAddress(), createMockSmartAccountClient(responderSmartAccount, responderOwner), responderBundler // Use responderBundler ) as DirectEntryPointExecutor; @@ -235,8 +235,8 @@ describe("Smart Account Handshake Response via Direct EntryPoint", () => { await waitForNonceSync(); - const handshakeFilter = logChain.filters.Handshake(); - const handshakeEvents = await logChain.queryFilter( + const handshakeFilter = verbEth.filters.Handshake(); + const handshakeEvents = await verbEth.queryFilter( handshakeFilter, initiateReceipt.blockNumber, initiateReceipt.blockNumber @@ -264,13 +264,13 @@ describe("Smart Account Handshake Response via Direct EntryPoint", () => { const respondReceipt = await respondTx.tx.wait(); expect(respondReceipt.status).toBe(1); - const responseFilter = logChain.filters.HandshakeResponse(); + const responseFilter = verbEth.filters.HandshakeResponse(); while ((await provider.getBlockNumber()) < respondReceipt.blockNumber) { await new Promise((r) => setTimeout(r, 10)); } - const responseEvents = await logChain.queryFilter( + const responseEvents = await verbEth.queryFilter( responseFilter, respondReceipt.blockNumber, respondReceipt.blockNumber @@ -331,8 +331,8 @@ describe("Smart Account Handshake Response via Direct EntryPoint", () => { // Now respond to each handshake ONE AT A TIME const responseReceipts: any[] = []; for (let i = 0; i < handshakeData.length; i++) { - const handshakeFilter = logChain.filters.Handshake(); - const handshakeEventsForItem = await logChain.queryFilter( + const handshakeFilter = verbEth.filters.Handshake(); + const handshakeEventsForItem = await verbEth.queryFilter( handshakeFilter, handshakeData[i].initiateReceipt.blockNumber, handshakeData[i].initiateReceipt.blockNumber @@ -370,7 +370,7 @@ describe("Smart Account Handshake Response via Direct EntryPoint", () => { responseReceipts.push(respondReceipt); } - const responseFilter = logChain.filters.HandshakeResponse(); + const responseFilter = verbEth.filters.HandshakeResponse(); const fromBlock = responseReceipts[0].blockNumber; const toBlock = responseReceipts[responseReceipts.length - 1].blockNumber; @@ -378,7 +378,7 @@ describe("Smart Account Handshake Response via Direct EntryPoint", () => { await new Promise((r) => setTimeout(r, 10)); } - const responseEvents = await logChain.queryFilter( + const responseEvents = await verbEth.queryFilter( responseFilter, fromBlock, toBlock @@ -416,8 +416,8 @@ describe("Smart Account Handshake Response via Direct EntryPoint", () => { const respondReceipt = await respondTx.tx.wait(); expect(respondReceipt.status).toBe(1); - const responseFilter = logChain.filters.HandshakeResponse(); - const responseEvents = await logChain.queryFilter( + const responseFilter = verbEth.filters.HandshakeResponse(); + const responseEvents = await verbEth.queryFilter( responseFilter, respondReceipt.blockNumber, respondReceipt.blockNumber @@ -462,8 +462,8 @@ describe("Smart Account Handshake Response via Direct EntryPoint", () => { } await new Promise((resolve) => setTimeout(resolve, 200)); - const handshakeFilter = logChain.filters.Handshake(); - const events = await logChain.queryFilter( + const handshakeFilter = verbEth.filters.Handshake(); + const events = await verbEth.queryFilter( handshakeFilter, initiateReceipt.blockNumber, initiateReceipt.blockNumber @@ -521,8 +521,8 @@ describe("Smart Account Handshake Response via Direct EntryPoint", () => { const initiateReceipt = await initiateHandshakeTx.wait(); expect(initiateReceipt.status).toBe(1); - const handshakeFilter = logChain.filters.Handshake(); - const handshakeEvents = await logChain.queryFilter( + const handshakeFilter = verbEth.filters.Handshake(); + const handshakeEvents = await verbEth.queryFilter( handshakeFilter, initiateReceipt.blockNumber, initiateReceipt.blockNumber @@ -562,8 +562,8 @@ describe("Smart Account Handshake Response via Direct EntryPoint", () => { const initiateReceipt = await initiateHandshakeTx.wait(); - const handshakeFilter = logChain.filters.Handshake(); - const handshakeEvents = await logChain.queryFilter( + const handshakeFilter = verbEth.filters.Handshake(); + const handshakeEvents = await verbEth.queryFilter( handshakeFilter, initiateReceipt.blockNumber, initiateReceipt.blockNumber @@ -593,8 +593,8 @@ describe("Smart Account Handshake Response via Direct EntryPoint", () => { await new Promise((r) => setTimeout(r, 10)); } - const responseFilter = logChain.filters.HandshakeResponse(); - const responseEvents = await logChain.queryFilter( + const responseFilter = verbEth.filters.HandshakeResponse(); + const responseEvents = await verbEth.queryFilter( responseFilter, respondReceipt.blockNumber, respondReceipt.blockNumber @@ -649,8 +649,8 @@ describe("Smart Account Handshake Response via Direct EntryPoint", () => { const initiateReceipt = await initiateHandshakeTx.wait(); expect(initiateReceipt.status).toBe(1); - const handshakeFilter = logChain.filters.Handshake(); - const handshakeEvents = await logChain.queryFilter( + const handshakeFilter = verbEth.filters.Handshake(); + const handshakeEvents = await verbEth.queryFilter( handshakeFilter, initiateReceipt.blockNumber, initiateReceipt.blockNumber @@ -704,8 +704,8 @@ describe("Smart Account Handshake Response via Direct EntryPoint", () => { } await new Promise((resolve) => setTimeout(resolve, 200)); - const handshakeFilter = logChain.filters.Handshake(); - const handshakeEvents = await logChain.queryFilter( + const handshakeFilter = verbEth.filters.Handshake(); + const handshakeEvents = await verbEth.queryFilter( handshakeFilter, initiateReceipt.blockNumber, initiateReceipt.blockNumber @@ -745,8 +745,8 @@ describe("Smart Account Handshake Response via Direct EntryPoint", () => { } await new Promise((resolve) => setTimeout(resolve, 200)); - const responseFilter = logChain.filters.HandshakeResponse(); - const responseEvents = await logChain.queryFilter( + const responseFilter = verbEth.filters.HandshakeResponse(); + const responseEvents = await verbEth.queryFilter( responseFilter, respondReceipt.blockNumber, respondReceipt.blockNumber From 20c354827b9d9066b1dc05b4085a6abf0107ca10 Mon Sep 17 00:00:00 2001 From: Marco Esposito Date: Sun, 1 Feb 2026 18:21:07 +0100 Subject: [PATCH 29/51] add address in the sdk as the single source of truth --- apps/demo/src/services/safeAccount.ts | 15 ++++----- apps/demo/src/types.ts | 13 +++----- apps/docs/docs/quick-start.md | 15 ++++----- packages/sdk/README.md | 11 ++++--- packages/sdk/src/addresses.ts | 47 +++++++++++++++++++++++++++ packages/sdk/src/index.ts | 4 ++- 6 files changed, 74 insertions(+), 31 deletions(-) create mode 100644 packages/sdk/src/addresses.ts diff --git a/apps/demo/src/services/safeAccount.ts b/apps/demo/src/services/safeAccount.ts index 48ab73f..26b0add 100644 --- a/apps/demo/src/services/safeAccount.ts +++ b/apps/demo/src/services/safeAccount.ts @@ -2,18 +2,15 @@ import SafeDefault from '@safe-global/protocol-kit' import SafeApiKitDefault from '@safe-global/api-kit' import { getAddress, Interface } from 'ethers' -import { SAFE_MODULE_ADDRESS, VERBETH_SINGLETON_ADDR } from '../types.js' +import { getModuleSetupHelper, getVerbethAddress } from '@verbeth/sdk' +import { SAFE_MODULE_ADDRESS } from '../types.js' // Handle ESM/CJS interop - safe libs export default differently const Safe = (SafeDefault as any).default ?? SafeDefault const SafeApiKit = (SafeApiKitDefault as any).default ?? SafeApiKitDefault const SAFE_API_KEY = import.meta.env.VITE_SAFE_API_KEY as string - -const MODULE_SETUP_HELPER_ADDRESS: Record = { - 84532: '0xbd59Fea46D308eDF3b75C22a6f64AC68feFc731A', - 8453: '0xc022F74924BDB4b62D830234d89b066359bF67c0', -} +const VERBETH_SINGLETON_ADDR = getVerbethAddress() export interface SessionConfig { sessionSigner: string @@ -205,7 +202,7 @@ export async function getOrCreateSafeForOwner(params: { console.log(`โœ… VerbEth Safe deployed at ${verbEthSafeAddress}`) - const helperAddress = MODULE_SETUP_HELPER_ADDRESS[chainId] + const helperAddress = getModuleSetupHelper(chainId) if (helperAddress && sessionConfig) { console.log(` Module enabled: true (via helper)`) console.log(` Session configured: true (via helper)`) @@ -255,7 +252,7 @@ function buildSafeAccountConfig( threshold: 1, } - const helperAddress = MODULE_SETUP_HELPER_ADDRESS[chainId] + const helperAddress = getModuleSetupHelper(chainId) if (!helperAddress) { console.warn(`โš ๏ธ ModuleSetupHelper not deployed on chain ${chainId}, using base config`) return baseConfig @@ -283,7 +280,7 @@ function buildSafeAccountConfig( } export function isHelperAvailable(chainId: number): boolean { - return !!MODULE_SETUP_HELPER_ADDRESS[chainId] + return !!getModuleSetupHelper(chainId) } /** diff --git a/apps/demo/src/types.ts b/apps/demo/src/types.ts index 3c7bcc1..c8d996e 100644 --- a/apps/demo/src/types.ts +++ b/apps/demo/src/types.ts @@ -1,15 +1,12 @@ import type { IdentityKeyPair, IdentityProof, RatchetSession as SDKRatchetSession, } from '@verbeth/sdk'; +import { getVerbethAddress, getCreationBlock, SCAN_DEFAULTS } from '@verbeth/sdk'; import { keccak256, toUtf8Bytes, hexlify, getBytes } from 'ethers'; /* ------------------------------- CONSTANTS -------------------------------- */ -export const VERBETH_SINGLETON_ADDR = - '0x51670aB6eDE1d1B11C654CCA53b7D42080802326'; -export const CONTRACT_CREATION_BLOCK = 36_053_269; -export const INITIAL_SCAN_BLOCKS = 1_000; -export const MAX_RETRIES = 3; -export const MAX_RANGE_PROVIDER = 2_000; -export const CHUNK_SIZE = 2_000; -export const REAL_TIME_BUFFER = 3; +// Re-export from SDK for backward compatibility +export const VERBETH_SINGLETON_ADDR = getVerbethAddress(); +export const CONTRACT_CREATION_BLOCK = getCreationBlock(); +export const { INITIAL_SCAN_BLOCKS, MAX_RETRIES, MAX_RANGE_PROVIDER, CHUNK_SIZE, REAL_TIME_BUFFER } = SCAN_DEFAULTS; export const SAFE_MODULE_ADDRESS = import.meta.env.VITE_SAFE_SESSION_MODULE as `0x${string}` diff --git a/apps/docs/docs/quick-start.md b/apps/docs/docs/quick-start.md index b2de785..614a2d2 100644 --- a/apps/docs/docs/quick-start.md +++ b/apps/docs/docs/quick-start.md @@ -20,13 +20,11 @@ npm install @verbeth/sdk ethers import { createVerbethClient, deriveIdentityKeyPairWithProof, - ExecutorFactory + ExecutorFactory, + getVerbethAddress } from '@verbeth/sdk'; import { ethers } from 'ethers'; -// Contract address (Base mainnet) -const VERBETH_ADDRESS = '0x51670aB6eDE1d1B11C654CCA53b7D42080802326'; - // 1. Connect wallet const provider = new ethers.BrowserProvider(window.ethereum); const signer = await provider.getSigner(); @@ -39,7 +37,7 @@ const { identityKeyPair, identityProof } = await deriveIdentityKeyPairWithProof( ); // 3. Create executor for contract interactions -const contract = new ethers.Contract(VERBETH_ADDRESS, VERBETH_ABI, signer); +const contract = new ethers.Contract(getVerbethAddress(), VERBETH_ABI, signer); const executor = ExecutorFactory.createEOA(contract); // 4. Create client @@ -159,12 +157,11 @@ if (decrypted) { import { createVerbethClient, deriveIdentityKeyPairWithProof, - ExecutorFactory + ExecutorFactory, + getVerbethAddress } from '@verbeth/sdk'; import { ethers } from 'ethers'; -const VERBETH_ADDRESS = '0x51670aB6eDE1d1B11C654CCA53b7D42080802326'; - async function initVerbeth() { const provider = new ethers.BrowserProvider(window.ethereum); const signer = await provider.getSigner(); @@ -175,7 +172,7 @@ async function initVerbeth() { address ); - const contract = new ethers.Contract(VERBETH_ADDRESS, VERBETH_ABI, signer); + const contract = new ethers.Contract(getVerbethAddress(), VERBETH_ABI, signer); const executor = ExecutorFactory.createEOA(contract); const client = createVerbethClient({ diff --git a/packages/sdk/README.md b/packages/sdk/README.md index 92720a5..f16876c 100644 --- a/packages/sdk/README.md +++ b/packages/sdk/README.md @@ -9,18 +9,21 @@ npm install @verbeth/sdk ### Quickstart ```ts -import { createVerbethClient, deriveIdentityKeyPairWithProof, ExecutorFactory } from '@verbeth/sdk'; +import { + createVerbethClient, + deriveIdentityKeyPairWithProof, + ExecutorFactory, + getVerbethAddress +} from '@verbeth/sdk'; import { ethers } from 'ethers'; -const VERBETH = '0x51670aB6eDE1d1B11C654CCA53b7D42080802326'; - const provider = new ethers.BrowserProvider(window.ethereum); const signer = await provider.getSigner(); const address = await signer.getAddress(); const { identityKeyPair, identityProof } = await deriveIdentityKeyPairWithProof(signer, address); -const contract = new ethers.Contract(VERBETH, VerbethABI, signer); +const contract = new ethers.Contract(getVerbethAddress(), VerbethABI, signer); const client = createVerbethClient({ address, signer, diff --git a/packages/sdk/src/addresses.ts b/packages/sdk/src/addresses.ts new file mode 100644 index 0000000..fe3cbbd --- /dev/null +++ b/packages/sdk/src/addresses.ts @@ -0,0 +1,47 @@ +// packages/sdk/src/addresses.ts + +export interface ChainConfig { + verbethProxy: `0x${string}`; + verbethImpl: `0x${string}`; + creationBlock: number; + moduleSetupHelper?: `0x${string}`; +} + +// Deterministic deployment +export const VERBETH_CONFIG: ChainConfig = { + verbethProxy: '0x82C9c5475D63e4C9e959280e9066aBb24973a663', + verbethImpl: '0x51670aB6eDE1d1B11C654CCA53b7D42080802326', + creationBlock: 37_097_547, // *** only base sepolia for now +} as const; + +// helpers for Safe session module +export const MODULE_SETUP_HELPERS: Record = { + 8453: '0xc022F74924BDB4b62D830234d89b066359bF67c0', + 84532: '0xbd59Fea46D308eDF3b75C22a6f64AC68feFc731A', +} as const; + + +export function getVerbethAddress(): `0x${string}` { + return VERBETH_CONFIG.verbethProxy; +} + +export function getCreationBlock(): number { + return VERBETH_CONFIG.creationBlock; +} + +export function getModuleSetupHelper(chainId: number): `0x${string}` | undefined { + return MODULE_SETUP_HELPERS[chainId]; +} + +export function isModuleSetupSupported(chainId: number): boolean { + return chainId in MODULE_SETUP_HELPERS; +} + +// Scanning defaults (chain-agnostic) +export const SCAN_DEFAULTS = { + INITIAL_SCAN_BLOCKS: 1_000, + MAX_RETRIES: 3, + MAX_RANGE_PROVIDER: 2_000, + CHUNK_SIZE: 2_000, + REAL_TIME_BUFFER: 3, +} as const; diff --git a/packages/sdk/src/index.ts b/packages/sdk/src/index.ts index badd24f..d028e1d 100644 --- a/packages/sdk/src/index.ts +++ b/packages/sdk/src/index.ts @@ -81,4 +81,6 @@ export type { export * from './ratchet/index.js'; export { dh, deriveTopic, hybridInitialSecret } from './ratchet/kdf.js'; -export { kem } from './pq/kem.js'; \ No newline at end of file +export { kem } from './pq/kem.js'; + +export * from './addresses.js'; \ No newline at end of file From fe4f592058d9eaefdc6e7c7a67c9a4f100387083 Mon Sep 17 00:00:00 2001 From: Marco Esposito Date: Sun, 1 Feb 2026 18:28:52 +0100 Subject: [PATCH 30/51] chore(release): v0.1.6 --- packages/sdk/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/sdk/package.json b/packages/sdk/package.json index a74c10c..68be1dd 100644 --- a/packages/sdk/package.json +++ b/packages/sdk/package.json @@ -1,6 +1,6 @@ { "name": "@verbeth/sdk", - "version": "0.1.5", + "version": "0.1.6", "private": false, "main": "dist/src/index.js", "module": "dist/esm/src/index.js", From f9f383330017ca14a20b6210ebcb34ec65004ba9 Mon Sep 17 00:00:00 2001 From: Marco Esposito Date: Thu, 5 Feb 2026 10:18:34 +0100 Subject: [PATCH 31/51] indexer wip --- apps/verbeth-indexer/Cargo.lock | 4337 ++++++++ apps/verbeth-indexer/Cargo.toml | 37 + apps/verbeth-indexer/Dockerfile | 12 + apps/verbeth-indexer/README.md | 82 + apps/verbeth-indexer/fly.toml | 27 + apps/verbeth-indexer/indexer.log | 8913 +++++++++++++++++ apps/verbeth-indexer/src/api/health.rs | 48 + apps/verbeth-indexer/src/api/mod.rs | 21 + apps/verbeth-indexer/src/api/state.rs | 26 + apps/verbeth-indexer/src/config.rs | 74 + apps/verbeth-indexer/src/db/mod.rs | 31 + apps/verbeth-indexer/src/db/models.rs | 40 + apps/verbeth-indexer/src/db/queries.rs | 128 + apps/verbeth-indexer/src/db/schema.rs | 81 + apps/verbeth-indexer/src/error.rs | 28 + apps/verbeth-indexer/src/indexer/backfill.rs | 218 + apps/verbeth-indexer/src/indexer/events.rs | 26 + apps/verbeth-indexer/src/indexer/mod.rs | 4 + apps/verbeth-indexer/src/indexer/processor.rs | 176 + .../verbeth-indexer/src/indexer/subscriber.rs | 145 + apps/verbeth-indexer/src/main.rs | 150 + 21 files changed, 14604 insertions(+) create mode 100644 apps/verbeth-indexer/Cargo.lock create mode 100644 apps/verbeth-indexer/Cargo.toml create mode 100644 apps/verbeth-indexer/Dockerfile create mode 100644 apps/verbeth-indexer/README.md create mode 100644 apps/verbeth-indexer/fly.toml create mode 100644 apps/verbeth-indexer/indexer.log create mode 100644 apps/verbeth-indexer/src/api/health.rs create mode 100644 apps/verbeth-indexer/src/api/mod.rs create mode 100644 apps/verbeth-indexer/src/api/state.rs create mode 100644 apps/verbeth-indexer/src/config.rs create mode 100644 apps/verbeth-indexer/src/db/mod.rs create mode 100644 apps/verbeth-indexer/src/db/models.rs create mode 100644 apps/verbeth-indexer/src/db/queries.rs create mode 100644 apps/verbeth-indexer/src/db/schema.rs create mode 100644 apps/verbeth-indexer/src/error.rs create mode 100644 apps/verbeth-indexer/src/indexer/backfill.rs create mode 100644 apps/verbeth-indexer/src/indexer/events.rs create mode 100644 apps/verbeth-indexer/src/indexer/mod.rs create mode 100644 apps/verbeth-indexer/src/indexer/processor.rs create mode 100644 apps/verbeth-indexer/src/indexer/subscriber.rs create mode 100644 apps/verbeth-indexer/src/main.rs diff --git a/apps/verbeth-indexer/Cargo.lock b/apps/verbeth-indexer/Cargo.lock new file mode 100644 index 0000000..e25aa47 --- /dev/null +++ b/apps/verbeth-indexer/Cargo.lock @@ -0,0 +1,4337 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "ahash" +version = "0.8.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" +dependencies = [ + "cfg-if", + "getrandom 0.3.4", + "once_cell", + "version_check", + "zerocopy", +] + +[[package]] +name = "aho-corasick" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" +dependencies = [ + "memchr", +] + +[[package]] +name = "allocator-api2" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" + +[[package]] +name = "alloy" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02b0561294ccedc6181e5528b850b4579e3fbde696507baa00109bfd9054c5bb" +dependencies = [ + "alloy-consensus", + "alloy-contract", + "alloy-core", + "alloy-eips", + "alloy-genesis", + "alloy-network", + "alloy-provider", + "alloy-pubsub", + "alloy-rpc-client", + "alloy-rpc-types", + "alloy-serde", + "alloy-transport", + "alloy-transport-http", + "alloy-transport-ws", +] + +[[package]] +name = "alloy-chains" +version = "0.1.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28e2652684758b0d9b389d248b209ed9fd9989ef489a550265fe4bb8454fe7eb" +dependencies = [ + "alloy-primitives", + "num_enum", + "strum", +] + +[[package]] +name = "alloy-consensus" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a101d4d016f47f13890a74290fdd17b05dd175191d9337bc600791fb96e4dea8" +dependencies = [ + "alloy-eips", + "alloy-primitives", + "alloy-rlp", + "alloy-serde", + "alloy-trie", + "auto_impl", + "c-kzg", + "derive_more 1.0.0", + "serde", +] + +[[package]] +name = "alloy-consensus-any" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa60357dda9a3d0f738f18844bd6d0f4a5924cc5cf00bfad2ff1369897966123" +dependencies = [ + "alloy-consensus", + "alloy-eips", + "alloy-primitives", + "alloy-rlp", + "alloy-serde", + "serde", +] + +[[package]] +name = "alloy-contract" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2869e4fb31331d3b8c58c7db567d1e4e4e94ef64640beda3b6dd9b7045690941" +dependencies = [ + "alloy-dyn-abi", + "alloy-json-abi", + "alloy-network", + "alloy-network-primitives", + "alloy-primitives", + "alloy-provider", + "alloy-pubsub", + "alloy-rpc-types-eth", + "alloy-sol-types", + "alloy-transport", + "futures", + "futures-util", + "thiserror 2.0.18", +] + +[[package]] +name = "alloy-core" +version = "0.8.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f1ab91967646311bb7dd32db4fee380c69fe624319dcd176b89fb2a420c6b5" +dependencies = [ + "alloy-dyn-abi", + "alloy-json-abi", + "alloy-primitives", + "alloy-rlp", + "alloy-sol-types", +] + +[[package]] +name = "alloy-dyn-abi" +version = "0.8.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf69d3061e2e908a4370bda5d8d6529d5080232776975489eec0b49ce971027e" +dependencies = [ + "alloy-json-abi", + "alloy-primitives", + "alloy-sol-type-parser", + "alloy-sol-types", + "const-hex", + "itoa", + "serde", + "serde_json", + "winnow", +] + +[[package]] +name = "alloy-eip2930" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0069cf0642457f87a01a014f6dc29d5d893cd4fd8fddf0c3cdfad1bb3ebafc41" +dependencies = [ + "alloy-primitives", + "alloy-rlp", + "serde", +] + +[[package]] +name = "alloy-eip7702" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c986539255fb839d1533c128e190e557e52ff652c9ef62939e233a81dd93f7e" +dependencies = [ + "alloy-primitives", + "alloy-rlp", + "derive_more 1.0.0", + "serde", +] + +[[package]] +name = "alloy-eips" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b6755b093afef5925f25079dd5a7c8d096398b804ba60cb5275397b06b31689" +dependencies = [ + "alloy-eip2930", + "alloy-eip7702", + "alloy-primitives", + "alloy-rlp", + "alloy-serde", + "c-kzg", + "derive_more 1.0.0", + "once_cell", + "serde", + "sha2", +] + +[[package]] +name = "alloy-genesis" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aeec8e6eab6e52b7c9f918748c9b811e87dbef7312a2e3a2ca1729a92966a6af" +dependencies = [ + "alloy-primitives", + "alloy-serde", + "alloy-trie", + "serde", +] + +[[package]] +name = "alloy-json-abi" +version = "0.8.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4584e3641181ff073e9d5bec5b3b8f78f9749d9fb108a1cfbc4399a4a139c72a" +dependencies = [ + "alloy-primitives", + "alloy-sol-type-parser", + "serde", + "serde_json", +] + +[[package]] +name = "alloy-json-rpc" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fa077efe0b834bcd89ff4ba547f48fb081e4fdc3673dd7da1b295a2cf2bb7b7" +dependencies = [ + "alloy-primitives", + "alloy-sol-types", + "serde", + "serde_json", + "thiserror 2.0.18", + "tracing", +] + +[[package]] +name = "alloy-network" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "209a1882a08e21aca4aac6e2a674dc6fcf614058ef8cb02947d63782b1899552" +dependencies = [ + "alloy-consensus", + "alloy-consensus-any", + "alloy-eips", + "alloy-json-rpc", + "alloy-network-primitives", + "alloy-primitives", + "alloy-rpc-types-any", + "alloy-rpc-types-eth", + "alloy-serde", + "alloy-signer", + "alloy-sol-types", + "async-trait", + "auto_impl", + "futures-utils-wasm", + "serde", + "serde_json", + "thiserror 2.0.18", +] + +[[package]] +name = "alloy-network-primitives" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c20219d1ad261da7a6331c16367214ee7ded41d001fabbbd656fbf71898b2773" +dependencies = [ + "alloy-consensus", + "alloy-eips", + "alloy-primitives", + "alloy-serde", + "serde", +] + +[[package]] +name = "alloy-primitives" +version = "0.8.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "777d58b30eb9a4db0e5f59bc30e8c2caef877fee7dc8734cf242a51a60f22e05" +dependencies = [ + "alloy-rlp", + "bytes", + "cfg-if", + "const-hex", + "derive_more 2.1.1", + "foldhash", + "hashbrown 0.15.5", + "indexmap", + "itoa", + "k256", + "keccak-asm", + "paste", + "proptest", + "rand 0.8.5", + "ruint", + "rustc-hash", + "serde", + "sha3", + "tiny-keccak", +] + +[[package]] +name = "alloy-provider" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9eefa6f4c798ad01f9b4202d02cea75f5ec11fa180502f4701e2b47965a8c0bb" +dependencies = [ + "alloy-chains", + "alloy-consensus", + "alloy-eips", + "alloy-json-rpc", + "alloy-network", + "alloy-network-primitives", + "alloy-primitives", + "alloy-pubsub", + "alloy-rpc-client", + "alloy-rpc-types-eth", + "alloy-transport", + "alloy-transport-http", + "alloy-transport-ws", + "async-stream", + "async-trait", + "auto_impl", + "dashmap", + "futures", + "futures-utils-wasm", + "lru", + "parking_lot", + "pin-project", + "reqwest", + "schnellru", + "serde", + "serde_json", + "thiserror 2.0.18", + "tokio", + "tracing", + "url", + "wasmtimer", +] + +[[package]] +name = "alloy-pubsub" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aac9a7210e0812b1d814118f426f57eb7fc260a419224dd1c76d169879c06907" +dependencies = [ + "alloy-json-rpc", + "alloy-primitives", + "alloy-transport", + "bimap", + "futures", + "serde", + "serde_json", + "tokio", + "tokio-stream", + "tower", + "tracing", +] + +[[package]] +name = "alloy-rlp" +version = "0.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e93e50f64a77ad9c5470bf2ad0ca02f228da70c792a8f06634801e202579f35e" +dependencies = [ + "alloy-rlp-derive", + "arrayvec", + "bytes", +] + +[[package]] +name = "alloy-rlp-derive" +version = "0.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce8849c74c9ca0f5a03da1c865e3eb6f768df816e67dd3721a398a8a7e398011" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "alloy-rpc-client" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed30bf1041e84cabc5900f52978ca345dd9969f2194a945e6fdec25b0620705c" +dependencies = [ + "alloy-json-rpc", + "alloy-primitives", + "alloy-pubsub", + "alloy-transport", + "alloy-transport-http", + "alloy-transport-ws", + "futures", + "pin-project", + "reqwest", + "serde", + "serde_json", + "tokio", + "tokio-stream", + "tower", + "tracing", + "url", + "wasmtimer", +] + +[[package]] +name = "alloy-rpc-types" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ab686b0fa475d2a4f5916c5f07797734a691ec58e44f0f55d4746ea39cbcefb" +dependencies = [ + "alloy-primitives", + "alloy-rpc-types-eth", + "alloy-serde", + "serde", +] + +[[package]] +name = "alloy-rpc-types-any" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "200661999b6e235d9840be5d60a6e8ae2f0af9eb2a256dd378786744660e36ec" +dependencies = [ + "alloy-consensus-any", + "alloy-rpc-types-eth", + "alloy-serde", +] + +[[package]] +name = "alloy-rpc-types-eth" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0600b8b5e2dc0cab12cbf91b5a885c35871789fb7b3a57b434bd4fced5b7a8b" +dependencies = [ + "alloy-consensus", + "alloy-consensus-any", + "alloy-eips", + "alloy-network-primitives", + "alloy-primitives", + "alloy-rlp", + "alloy-serde", + "alloy-sol-types", + "derive_more 1.0.0", + "itertools 0.13.0", + "serde", + "serde_json", +] + +[[package]] +name = "alloy-serde" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9afa753a97002a33b2ccb707d9f15f31c81b8c1b786c95b73cc62bb1d1fd0c3f" +dependencies = [ + "alloy-primitives", + "serde", + "serde_json", +] + +[[package]] +name = "alloy-signer" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b2cbff01a673936c2efd7e00d4c0e9a4dbbd6d600e2ce298078d33efbb19cd7" +dependencies = [ + "alloy-primitives", + "async-trait", + "auto_impl", + "elliptic-curve", + "k256", + "thiserror 2.0.18", +] + +[[package]] +name = "alloy-sol-macro" +version = "0.8.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e68b32b6fa0d09bb74b4cefe35ccc8269d711c26629bc7cd98a47eeb12fe353f" +dependencies = [ + "alloy-sol-macro-expander", + "alloy-sol-macro-input", + "proc-macro-error2", + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "alloy-sol-macro-expander" +version = "0.8.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2afe6879ac373e58fd53581636f2cce843998ae0b058ebe1e4f649195e2bd23c" +dependencies = [ + "alloy-sol-macro-input", + "const-hex", + "heck", + "indexmap", + "proc-macro-error2", + "proc-macro2", + "quote", + "syn 2.0.114", + "syn-solidity", + "tiny-keccak", +] + +[[package]] +name = "alloy-sol-macro-input" +version = "0.8.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3ba01aee235a8c699d07e5be97ba215607564e71be72f433665329bec307d28" +dependencies = [ + "const-hex", + "dunce", + "heck", + "macro-string", + "proc-macro2", + "quote", + "syn 2.0.114", + "syn-solidity", +] + +[[package]] +name = "alloy-sol-type-parser" +version = "0.8.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c13fc168b97411e04465f03e632f31ef94cad1c7c8951bf799237fd7870d535" +dependencies = [ + "serde", + "winnow", +] + +[[package]] +name = "alloy-sol-types" +version = "0.8.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e960c4b52508ef2ae1e37cae5058e905e9ae099b107900067a503f8c454036f" +dependencies = [ + "alloy-json-abi", + "alloy-primitives", + "alloy-sol-macro", + "const-hex", + "serde", +] + +[[package]] +name = "alloy-transport" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d69d36982b9e46075ae6b792b0f84208c6c2c15ad49f6c500304616ef67b70e0" +dependencies = [ + "alloy-json-rpc", + "base64", + "futures-util", + "futures-utils-wasm", + "serde", + "serde_json", + "thiserror 2.0.18", + "tokio", + "tower", + "tracing", + "url", + "wasmtimer", +] + +[[package]] +name = "alloy-transport-http" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e02ffd5d93ffc51d72786e607c97de3b60736ca3e636ead0ec1f7dce68ea3fd" +dependencies = [ + "alloy-json-rpc", + "alloy-transport", + "reqwest", + "serde_json", + "tower", + "tracing", + "url", +] + +[[package]] +name = "alloy-transport-ws" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c085c4e1e7680b723ffc558f61a22c061ed3f70eb3436f93f3936779c59cec1" +dependencies = [ + "alloy-pubsub", + "alloy-transport", + "futures", + "http", + "rustls", + "serde_json", + "tokio", + "tokio-tungstenite", + "tracing", + "ws_stream_wasm", +] + +[[package]] +name = "alloy-trie" +version = "0.7.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d95a94854e420f07e962f7807485856cde359ab99ab6413883e15235ad996e8b" +dependencies = [ + "alloy-primitives", + "alloy-rlp", + "arrayvec", + "derive_more 1.0.0", + "nybbles", + "serde", + "smallvec", + "tracing", +] + +[[package]] +name = "ark-ff" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b3235cc41ee7a12aaaf2c575a2ad7b46713a8a50bda2fc3b003a04845c05dd6" +dependencies = [ + "ark-ff-asm 0.3.0", + "ark-ff-macros 0.3.0", + "ark-serialize 0.3.0", + "ark-std 0.3.0", + "derivative", + "num-bigint", + "num-traits", + "paste", + "rustc_version 0.3.3", + "zeroize", +] + +[[package]] +name = "ark-ff" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec847af850f44ad29048935519032c33da8aa03340876d351dfab5660d2966ba" +dependencies = [ + "ark-ff-asm 0.4.2", + "ark-ff-macros 0.4.2", + "ark-serialize 0.4.2", + "ark-std 0.4.0", + "derivative", + "digest 0.10.7", + "itertools 0.10.5", + "num-bigint", + "num-traits", + "paste", + "rustc_version 0.4.1", + "zeroize", +] + +[[package]] +name = "ark-ff" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a177aba0ed1e0fbb62aa9f6d0502e9b46dad8c2eab04c14258a1212d2557ea70" +dependencies = [ + "ark-ff-asm 0.5.0", + "ark-ff-macros 0.5.0", + "ark-serialize 0.5.0", + "ark-std 0.5.0", + "arrayvec", + "digest 0.10.7", + "educe", + "itertools 0.13.0", + "num-bigint", + "num-traits", + "paste", + "zeroize", +] + +[[package]] +name = "ark-ff-asm" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db02d390bf6643fb404d3d22d31aee1c4bc4459600aef9113833d17e786c6e44" +dependencies = [ + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-ff-asm" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ed4aa4fe255d0bc6d79373f7e31d2ea147bcf486cba1be5ba7ea85abdb92348" +dependencies = [ + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-ff-asm" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62945a2f7e6de02a31fe400aa489f0e0f5b2502e69f95f853adb82a96c7a6b60" +dependencies = [ + "quote", + "syn 2.0.114", +] + +[[package]] +name = "ark-ff-macros" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db2fd794a08ccb318058009eefdf15bcaaaaf6f8161eb3345f907222bac38b20" +dependencies = [ + "num-bigint", + "num-traits", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-ff-macros" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7abe79b0e4288889c4574159ab790824d0033b9fdcb2a112a3182fac2e514565" +dependencies = [ + "num-bigint", + "num-traits", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-ff-macros" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09be120733ee33f7693ceaa202ca41accd5653b779563608f1234f78ae07c4b3" +dependencies = [ + "num-bigint", + "num-traits", + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "ark-serialize" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d6c2b318ee6e10f8c2853e73a83adc0ccb88995aa978d8a3408d492ab2ee671" +dependencies = [ + "ark-std 0.3.0", + "digest 0.9.0", +] + +[[package]] +name = "ark-serialize" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adb7b85a02b83d2f22f89bd5cac66c9c89474240cb6207cb1efc16d098e822a5" +dependencies = [ + "ark-std 0.4.0", + "digest 0.10.7", + "num-bigint", +] + +[[package]] +name = "ark-serialize" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f4d068aaf107ebcd7dfb52bc748f8030e0fc930ac8e360146ca54c1203088f7" +dependencies = [ + "ark-std 0.5.0", + "arrayvec", + "digest 0.10.7", + "num-bigint", +] + +[[package]] +name = "ark-std" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1df2c09229cbc5a028b1d70e00fdb2acee28b1055dfb5ca73eea49c5a25c4e7c" +dependencies = [ + "num-traits", + "rand 0.8.5", +] + +[[package]] +name = "ark-std" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94893f1e0c6eeab764ade8dc4c0db24caf4fe7cbbaafc0eba0a9030f447b5185" +dependencies = [ + "num-traits", + "rand 0.8.5", +] + +[[package]] +name = "ark-std" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "246a225cc6131e9ee4f24619af0f19d67761fff15d7ccc22e42b80846e69449a" +dependencies = [ + "num-traits", + "rand 0.8.5", +] + +[[package]] +name = "arrayvec" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" +dependencies = [ + "serde", +] + +[[package]] +name = "async-stream" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b5a71a6f37880a80d1d7f19efd781e4b5de42c88f0722cc13bcb6cc2cfe8476" +dependencies = [ + "async-stream-impl", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-stream-impl" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "async-trait" +version = "0.1.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "async_io_stream" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6d7b9decdf35d8908a7e3ef02f64c5e9b1695e230154c0e8de3969142d9b94c" +dependencies = [ + "futures", + "pharos", + "rustc_version 0.4.1", +] + +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + +[[package]] +name = "auto_impl" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffdcb70bdbc4d478427380519163274ac86e52916e10f0a8889adf0f96d3fee7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "autocfg" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" + +[[package]] +name = "axum" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b52af3cb4058c895d37317bb27508dccc8e5f2d39454016b297bf4a400597b8" +dependencies = [ + "axum-core", + "axum-macros", + "bytes", + "form_urlencoded", + "futures-util", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-util", + "itoa", + "matchit", + "memchr", + "mime", + "percent-encoding", + "pin-project-lite", + "serde_core", + "serde_json", + "serde_path_to_error", + "serde_urlencoded", + "sync_wrapper", + "tokio", + "tower", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "axum-core" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08c78f31d7b1291f7ee735c1c6780ccde7785daae9a9206026862dab7d8792d1" +dependencies = [ + "bytes", + "futures-core", + "http", + "http-body", + "http-body-util", + "mime", + "pin-project-lite", + "sync_wrapper", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "axum-macros" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "604fde5e028fea851ce1d8570bbdc034bec850d157f7569d10f347d06808c05c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "base16ct" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" + +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + +[[package]] +name = "base64ct" +version = "1.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2af50177e190e07a26ab74f8b1efbfe2ef87da2116221318cb1c2e82baf7de06" + +[[package]] +name = "bimap" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "230c5f1ca6a325a32553f8640d31ac9b49f2411e901e427570154868b46da4f7" + +[[package]] +name = "bit-set" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08807e080ed7f9d5433fa9b275196cfc35414f66a0c79d864dc51a0d825231a3" +dependencies = [ + "bit-vec", +] + +[[package]] +name = "bit-vec" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7" + +[[package]] +name = "bitflags" +version = "2.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" + +[[package]] +name = "bitvec" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" +dependencies = [ + "funty", + "radium", + "tap", + "wyz", +] + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "blst" +version = "0.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcdb4c7013139a150f9fc55d123186dbfaba0d912817466282c73ac49e71fb45" +dependencies = [ + "cc", + "glob", + "threadpool", + "zeroize", +] + +[[package]] +name = "bumpalo" +version = "3.19.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dd9dc738b7a8311c7ade152424974d8115f2cdad61e8dab8dac9f2362298510" + +[[package]] +name = "byte-slice-cast" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7575182f7272186991736b70173b0ea045398f984bf5ebbb3804736ce1330c9d" + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "bytes" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33" +dependencies = [ + "serde", +] + +[[package]] +name = "c-kzg" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0307f72feab3300336fb803a57134159f6e20139af1357f36c54cb90d8e8928" +dependencies = [ + "blst", + "cc", + "glob", + "hex", + "libc", + "once_cell", + "serde", +] + +[[package]] +name = "cc" +version = "1.2.55" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47b26a0954ae34af09b50f0de26458fa95369a0d478d8236d3f93082b219bd29" +dependencies = [ + "find-msvc-tools", + "shlex", +] + +[[package]] +name = "cfg-if" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" + +[[package]] +name = "const-hex" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3bb320cac8a0750d7f25280aa97b09c26edfe161164238ecbbb31092b079e735" +dependencies = [ + "cfg-if", + "cpufeatures", + "proptest", + "serde_core", +] + +[[package]] +name = "const-oid" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" + +[[package]] +name = "const_format" +version = "0.2.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7faa7469a93a566e9ccc1c73fe783b4a65c274c5ace346038dca9c39fe0030ad" +dependencies = [ + "const_format_proc_macros", +] + +[[package]] +name = "const_format_proc_macros" +version = "0.2.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d57c2eccfb16dbac1f4e61e206105db5820c9d26c3c472bc17c774259ef7744" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + +[[package]] +name = "convert_case" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "633458d4ef8c78b72454de2d54fd6ab2e60f9e02be22f3c6104cdc8a4e0fceb9" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "core-foundation" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" + +[[package]] +name = "cpufeatures" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" +dependencies = [ + "libc", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" + +[[package]] +name = "crunchy" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" + +[[package]] +name = "crypto-bigint" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" +dependencies = [ + "generic-array", + "rand_core 0.6.4", + "subtle", + "zeroize", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "dashmap" +version = "6.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5041cc499144891f3790297212f32a74fb938e5136a14943f338ef9e0ae276cf" +dependencies = [ + "cfg-if", + "crossbeam-utils", + "hashbrown 0.14.5", + "lock_api", + "once_cell", + "parking_lot_core", +] + +[[package]] +name = "data-encoding" +version = "2.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7a1e2f27636f116493b8b860f5546edb47c8d8f8ea73e1d2a20be88e28d1fea" + +[[package]] +name = "der" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb" +dependencies = [ + "const-oid", + "zeroize", +] + +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "derive_more" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a9b99b9cbbe49445b21764dc0625032a89b145a2642e67603e1c936f5458d05" +dependencies = [ + "derive_more-impl 1.0.0", +] + +[[package]] +name = "derive_more" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d751e9e49156b02b44f9c1815bcb94b984cdcc4396ecc32521c739452808b134" +dependencies = [ + "derive_more-impl 2.1.1", +] + +[[package]] +name = "derive_more-impl" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb7330aeadfbe296029522e6c40f315320aba36fc43a5b3632f3795348f3bd22" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", + "unicode-xid", +] + +[[package]] +name = "derive_more-impl" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "799a97264921d8623a957f6c3b9011f3b5492f557bbb7a5a19b7fa6d06ba8dcb" +dependencies = [ + "convert_case", + "proc-macro2", + "quote", + "rustc_version 0.4.1", + "syn 2.0.114", + "unicode-xid", +] + +[[package]] +name = "digest" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +dependencies = [ + "generic-array", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "const-oid", + "crypto-common", + "subtle", +] + +[[package]] +name = "displaydoc" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "dotenvy" +version = "0.15.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" + +[[package]] +name = "dunce" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" + +[[package]] +name = "ecdsa" +version = "0.16.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" +dependencies = [ + "der", + "digest 0.10.7", + "elliptic-curve", + "rfc6979", + "signature", + "spki", +] + +[[package]] +name = "educe" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d7bc049e1bd8cdeb31b68bbd586a9464ecf9f3944af3958a7a9d0f8b9799417" +dependencies = [ + "enum-ordinalize", + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "either" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" + +[[package]] +name = "elliptic-curve" +version = "0.13.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" +dependencies = [ + "base16ct", + "crypto-bigint", + "digest 0.10.7", + "ff", + "generic-array", + "group", + "pkcs8", + "rand_core 0.6.4", + "sec1", + "subtle", + "zeroize", +] + +[[package]] +name = "enum-ordinalize" +version = "4.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a1091a7bb1f8f2c4b28f1fe2cef4980ca2d410a3d727d67ecc3178c9b0800f0" +dependencies = [ + "enum-ordinalize-derive", +] + +[[package]] +name = "enum-ordinalize-derive" +version = "4.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ca9601fb2d62598ee17836250842873a413586e5d7ed88b356e38ddbb0ec631" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + +[[package]] +name = "errno" +version = "0.3.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" +dependencies = [ + "libc", + "windows-sys 0.61.2", +] + +[[package]] +name = "fallible-iterator" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649" + +[[package]] +name = "fallible-streaming-iterator" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a" + +[[package]] +name = "fastrand" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" + +[[package]] +name = "fastrlp" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "139834ddba373bbdd213dffe02c8d110508dcf1726c2be27e8d1f7d7e1856418" +dependencies = [ + "arrayvec", + "auto_impl", + "bytes", +] + +[[package]] +name = "fastrlp" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce8dba4714ef14b8274c371879b175aa55b16b30f269663f19d576f380018dc4" +dependencies = [ + "arrayvec", + "auto_impl", + "bytes", +] + +[[package]] +name = "ff" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0b50bfb653653f9ca9095b427bed08ab8d75a137839d9ad64eb11810d5b6393" +dependencies = [ + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "find-msvc-tools" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" + +[[package]] +name = "fixed-hash" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "835c052cb0c08c1acf6ffd71c022172e18723949c8282f2b9f27efbc51e64534" +dependencies = [ + "byteorder", + "rand 0.8.5", + "rustc-hex", + "static_assertions", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "foldhash" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" + +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + +[[package]] +name = "form_urlencoded" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "funty" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" + +[[package]] +name = "futures" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" + +[[package]] +name = "futures-executor" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" + +[[package]] +name = "futures-lite" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f78e10609fe0e0b3f4157ffab1876319b5b0db102a2c60dc4626306dc46b44ad" +dependencies = [ + "fastrand", + "futures-core", + "futures-io", + "parking", + "pin-project-lite", +] + +[[package]] +name = "futures-macro" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "futures-sink" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" + +[[package]] +name = "futures-task" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" + +[[package]] +name = "futures-timer" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24" + +[[package]] +name = "futures-util" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "futures-utils-wasm" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42012b0f064e01aa58b545fe3727f90f7dd4020f4a3ea735b50344965f5a57e9" + +[[package]] +name = "generic-array" +version = "0.14.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bb6743198531e02858aeaea5398fcc883e71851fcbcb5a2f773e2fb6cb1edf2" +dependencies = [ + "typenum", + "version_check", + "zeroize", +] + +[[package]] +name = "getrandom" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "getrandom" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "r-efi", + "wasip2", + "wasm-bindgen", +] + +[[package]] +name = "glob" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" + +[[package]] +name = "governor" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be93b4ec2e4710b04d9264c0c7350cdd62a8c20e5e4ac732552ebb8f0debe8eb" +dependencies = [ + "cfg-if", + "dashmap", + "futures-sink", + "futures-timer", + "futures-util", + "getrandom 0.3.4", + "no-std-compat", + "nonzero_ext", + "parking_lot", + "portable-atomic", + "quanta", + "rand 0.9.2", + "smallvec", + "spinning_top", + "web-time", +] + +[[package]] +name = "group" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +dependencies = [ + "ff", + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "hashbrown" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" + +[[package]] +name = "hashbrown" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" +dependencies = [ + "ahash", +] + +[[package]] +name = "hashbrown" +version = "0.15.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" +dependencies = [ + "allocator-api2", + "equivalent", + "foldhash", + "serde", +] + +[[package]] +name = "hashbrown" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" + +[[package]] +name = "hashlink" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ba4ff7128dee98c7dc9794b6a411377e1404dba1c97deb8d1a55297bd25d8af" +dependencies = [ + "hashbrown 0.14.5", +] + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "hermit-abi" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest 0.10.7", +] + +[[package]] +name = "http" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3ba2a386d7f85a81f119ad7498ebe444d2e22c2af0b86b069416ace48b3311a" +dependencies = [ + "bytes", + "itoa", +] + +[[package]] +name = "http-body" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" +dependencies = [ + "bytes", + "http", +] + +[[package]] +name = "http-body-util" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" +dependencies = [ + "bytes", + "futures-core", + "http", + "http-body", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" + +[[package]] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + +[[package]] +name = "hyper" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ab2d4f250c3d7b1c9fcdff1cece94ea4e2dfbec68614f7b87cb205f24ca9d11" +dependencies = [ + "atomic-waker", + "bytes", + "futures-channel", + "futures-core", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "pin-utils", + "smallvec", + "tokio", + "want", +] + +[[package]] +name = "hyper-tls" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" +dependencies = [ + "bytes", + "http-body-util", + "hyper", + "hyper-util", + "native-tls", + "tokio", + "tokio-native-tls", + "tower-service", +] + +[[package]] +name = "hyper-util" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96547c2556ec9d12fb1578c4eaf448b04993e7fb79cbaad930a656880a6bdfa0" +dependencies = [ + "base64", + "bytes", + "futures-channel", + "futures-util", + "http", + "http-body", + "hyper", + "ipnet", + "libc", + "percent-encoding", + "pin-project-lite", + "socket2", + "tokio", + "tower-service", + "tracing", +] + +[[package]] +name = "icu_collections" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c6b649701667bbe825c3b7e6388cb521c23d88644678e83c0c4d0a621a34b43" +dependencies = [ + "displaydoc", + "potential_utf", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locale_core" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edba7861004dd3714265b4db54a3c390e880ab658fec5f7db895fae2046b5bb6" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_normalizer" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f6c8828b67bf8908d82127b2054ea1b4427ff0230ee9141c54251934ab1b599" +dependencies = [ + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7aedcccd01fc5fe81e6b489c15b247b8b0690feb23304303a9e560f37efc560a" + +[[package]] +name = "icu_properties" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "020bfc02fe870ec3a66d93e677ccca0562506e5872c650f893269e08615d74ec" +dependencies = [ + "icu_collections", + "icu_locale_core", + "icu_properties_data", + "icu_provider", + "zerotrie", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "616c294cf8d725c6afcd8f55abc17c56464ef6211f9ed59cccffe534129c77af" + +[[package]] +name = "icu_provider" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85962cf0ce02e1e0a629cc34e7ca3e373ce20dda4c4d7294bbd0bf1fdb59e614" +dependencies = [ + "displaydoc", + "icu_locale_core", + "writeable", + "yoke", + "zerofrom", + "zerotrie", + "zerovec", +] + +[[package]] +name = "idna" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" +dependencies = [ + "idna_adapter", + "smallvec", + "utf8_iter", +] + +[[package]] +name = "idna_adapter" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" +dependencies = [ + "icu_normalizer", + "icu_properties", +] + +[[package]] +name = "impl-codec" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba6a270039626615617f3f36d15fc827041df3b78c439da2cadfa47455a77f2f" +dependencies = [ + "parity-scale-codec", +] + +[[package]] +name = "impl-trait-for-tuples" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0eb5a3343abf848c0984fe4604b2b105da9539376e24fc0a3b0007411ae4fd9" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "indexmap" +version = "2.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017" +dependencies = [ + "equivalent", + "hashbrown 0.16.1", + "serde", + "serde_core", +] + +[[package]] +name = "ipnet" +version = "2.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" + +[[package]] +name = "iri-string" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c91338f0783edbd6195decb37bae672fd3b165faffb89bf7b9e6942f8b1a731a" +dependencies = [ + "memchr", + "serde", +] + +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + +[[package]] +name = "itertools" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2" + +[[package]] +name = "js-sys" +version = "0.3.85" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c942ebf8e95485ca0d52d97da7c5a2c387d0e7f0ba4c35e93bfcaee045955b3" +dependencies = [ + "once_cell", + "wasm-bindgen", +] + +[[package]] +name = "k256" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6e3919bbaa2945715f0bb6d3934a173d1e9a59ac23767fbaaef277265a7411b" +dependencies = [ + "cfg-if", + "ecdsa", + "elliptic-curve", + "once_cell", + "sha2", +] + +[[package]] +name = "keccak" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" +dependencies = [ + "cpufeatures", +] + +[[package]] +name = "keccak-asm" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b646a74e746cd25045aa0fd42f4f7f78aa6d119380182c7e63a5593c4ab8df6f" +dependencies = [ + "digest 0.10.7", + "sha3-asm", +] + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + +[[package]] +name = "libc" +version = "0.2.180" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bcc35a38544a891a5f7c865aca548a982ccb3b8650a5b06d0fd33a10283c56fc" + +[[package]] +name = "libm" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981" + +[[package]] +name = "libsqlite3-sys" +version = "0.30.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e99fb7a497b1e3339bc746195567ed8d3e24945ecd636e3619d20b9de9e9149" +dependencies = [ + "cc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "linux-raw-sys" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" + +[[package]] +name = "litemap" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6373607a59f0be73a39b6fe456b8192fcc3585f602af20751600e974dd455e77" + +[[package]] +name = "lock_api" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" +dependencies = [ + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" + +[[package]] +name = "lru" +version = "0.12.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "234cf4f4a04dc1f57e24b96cc0cd600cf2af460d4161ac5ecdd0af8e1f3b2a38" +dependencies = [ + "hashbrown 0.15.5", +] + +[[package]] +name = "macro-string" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b27834086c65ec3f9387b096d66e99f221cf081c2b738042aa252bcd41204e3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "matchers" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1525a2a28c7f4fa0fc98bb91ae755d1e2d1505079e05539e35bc876b5d65ae9" +dependencies = [ + "regex-automata", +] + +[[package]] +name = "matchit" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47e1ffaa40ddd1f3ed91f717a33c8c0ee23fff369e3aa8772b9605cc1d22f4c3" + +[[package]] +name = "memchr" +version = "2.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" + +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "mio" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a69bcab0ad47271a0234d9422b131806bf3968021e5dc9328caf2d4cd58557fc" +dependencies = [ + "libc", + "wasi", + "windows-sys 0.61.2", +] + +[[package]] +name = "native-tls" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87de3442987e9dbec73158d5c715e7ad9072fda936bb03d19d7fa10e00520f0e" +dependencies = [ + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", +] + +[[package]] +name = "no-std-compat" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b93853da6d84c2e3c7d730d6473e8817692dd89be387eb01b94d7f108ecb5b8c" + +[[package]] +name = "nonzero_ext" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38bf9645c8b145698bb0b18a4637dcacbc421ea49bef2317e4fd8065a387cf21" + +[[package]] +name = "nu-ansi-term" +version = "0.50.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" +dependencies = [ + "windows-sys 0.61.2", +] + +[[package]] +name = "num-bigint" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" +dependencies = [ + "num-integer", + "num-traits", +] + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", + "libm", +] + +[[package]] +name = "num_cpus" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91df4bbde75afed763b708b7eee1e8e7651e02d97f6d5dd763e89367e957b23b" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "num_enum" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1207a7e20ad57b847bbddc6776b968420d38292bbfe2089accff5e19e82454c" +dependencies = [ + "num_enum_derive", + "rustversion", +] + +[[package]] +name = "num_enum_derive" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff32365de1b6743cb203b710788263c44a03de03802daf96092f2da4fe6ba4d7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "nybbles" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8983bb634df7248924ee0c4c3a749609b5abcb082c28fffe3254b3eb3602b307" +dependencies = [ + "alloy-rlp", + "const-hex", + "proptest", + "serde", + "smallvec", +] + +[[package]] +name = "once_cell" +version = "1.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" + +[[package]] +name = "openssl" +version = "0.10.75" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08838db121398ad17ab8531ce9de97b244589089e290a384c900cb9ff7434328" +dependencies = [ + "bitflags", + "cfg-if", + "foreign-types", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "openssl-probe" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" + +[[package]] +name = "openssl-sys" +version = "0.9.111" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82cab2d520aa75e3c58898289429321eb788c3106963d0dc886ec7a5f4adc321" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "parity-scale-codec" +version = "3.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "799781ae679d79a948e13d4824a40970bfa500058d245760dd857301059810fa" +dependencies = [ + "arrayvec", + "bitvec", + "byte-slice-cast", + "const_format", + "impl-trait-for-tuples", + "parity-scale-codec-derive", + "rustversion", + "serde", +] + +[[package]] +name = "parity-scale-codec-derive" +version = "3.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34b4653168b563151153c9e4c08ebed57fb8262bebfa79711552fa983c623e7a" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "parking" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" + +[[package]] +name = "parking_lot" +version = "0.12.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-link", +] + +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + +[[package]] +name = "percent-encoding" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" + +[[package]] +name = "pest" +version = "2.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c9eb05c21a464ea704b53158d358a31e6425db2f63a1a7312268b05fe2b75f7" +dependencies = [ + "memchr", + "ucd-trie", +] + +[[package]] +name = "pharos" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9567389417feee6ce15dd6527a8a1ecac205ef62c2932bcf3d9f6fc5b78b414" +dependencies = [ + "futures", + "rustc_version 0.4.1", +] + +[[package]] +name = "pin-project" +version = "1.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677f1add503faace112b9f1373e43e9e054bfdd22ff1a63c1bc485eaec6a6a8a" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der", + "spki", +] + +[[package]] +name = "pkg-config" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" + +[[package]] +name = "portable-atomic" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49" + +[[package]] +name = "potential_utf" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b73949432f5e2a09657003c25bca5e19a0e9c84f8058ca374f49e0ebe605af77" +dependencies = [ + "zerovec", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" +dependencies = [ + "zerocopy", +] + +[[package]] +name = "primitive-types" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b34d9fd68ae0b74a41b21c03c2f62847aa0ffea044eee893b4c140b37e244e2" +dependencies = [ + "fixed-hash", + "impl-codec", + "uint", +] + +[[package]] +name = "proc-macro-crate" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "219cb19e96be00ab2e37d6e299658a0cfa83e52429179969b0f0121b4ac46983" +dependencies = [ + "toml_edit", +] + +[[package]] +name = "proc-macro-error-attr2" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96de42df36bb9bba5542fe9f1a054b8cc87e172759a1868aa05c1f3acc89dfc5" +dependencies = [ + "proc-macro2", + "quote", +] + +[[package]] +name = "proc-macro-error2" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11ec05c52be0a07b08061f7dd003e7d7092e0472bc731b4af7bb1ef876109802" +dependencies = [ + "proc-macro-error-attr2", + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "proc-macro2" +version = "1.0.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "proptest" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bee689443a2bd0a16ab0348b52ee43e3b2d1b1f931c8aa5c9f8de4c86fbe8c40" +dependencies = [ + "bit-set", + "bit-vec", + "bitflags", + "num-traits", + "rand 0.9.2", + "rand_chacha 0.9.0", + "rand_xorshift", + "regex-syntax", + "rusty-fork", + "tempfile", + "unarray", +] + +[[package]] +name = "quanta" +version = "0.12.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3ab5a9d756f0d97bdc89019bd2e4ea098cf9cde50ee7564dde6b81ccc8f06c7" +dependencies = [ + "crossbeam-utils", + "libc", + "once_cell", + "raw-cpuid", + "wasi", + "web-sys", + "winapi", +] + +[[package]] +name = "quick-error" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" + +[[package]] +name = "quote" +version = "1.0.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21b2ebcf727b7760c461f091f9f0f539b77b8e87f2fd88131e7f1b433b3cece4" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "r-efi" +version = "5.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" + +[[package]] +name = "r2d2" +version = "0.8.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51de85fb3fb6524929c8a2eb85e6b6d363de4e8c48f9e2c2eac4944abc181c93" +dependencies = [ + "log", + "parking_lot", + "scheduled-thread-pool", +] + +[[package]] +name = "r2d2_sqlite" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb14dba8247a6a15b7fdbc7d389e2e6f03ee9f184f87117706d509c092dfe846" +dependencies = [ + "r2d2", + "rusqlite", + "uuid", +] + +[[package]] +name = "radium" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.4", + "serde", +] + +[[package]] +name = "rand" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" +dependencies = [ + "rand_chacha 0.9.0", + "rand_core 0.9.5", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" +dependencies = [ + "ppv-lite86", + "rand_core 0.9.5", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom 0.2.17", +] + +[[package]] +name = "rand_core" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c" +dependencies = [ + "getrandom 0.3.4", +] + +[[package]] +name = "rand_xorshift" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "513962919efc330f829edb2535844d1b912b0fbe2ca165d613e4e8788bb05a5a" +dependencies = [ + "rand_core 0.9.5", +] + +[[package]] +name = "raw-cpuid" +version = "11.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "498cd0dc59d73224351ee52a95fee0f1a617a2eae0e7d9d720cc622c73a54186" +dependencies = [ + "bitflags", +] + +[[package]] +name = "redox_syscall" +version = "0.5.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" +dependencies = [ + "bitflags", +] + +[[package]] +name = "regex-automata" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a96887878f22d7bad8a3b6dc5b7440e0ada9a245242924394987b21cf2210a4c" + +[[package]] +name = "reqwest" +version = "0.12.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eddd3ca559203180a307f12d114c268abf583f59b03cb906fd0b3ff8646c1147" +dependencies = [ + "base64", + "bytes", + "futures-core", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-tls", + "hyper-util", + "js-sys", + "log", + "native-tls", + "percent-encoding", + "pin-project-lite", + "rustls-pki-types", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper", + "tokio", + "tokio-native-tls", + "tower", + "tower-http", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "rfc6979" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" +dependencies = [ + "hmac", + "subtle", +] + +[[package]] +name = "ring" +version = "0.17.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" +dependencies = [ + "cc", + "cfg-if", + "getrandom 0.2.17", + "libc", + "untrusted", + "windows-sys 0.52.0", +] + +[[package]] +name = "rlp" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb919243f34364b6bd2fc10ef797edbfa75f33c252e7998527479c6d6b47e1ec" +dependencies = [ + "bytes", + "rustc-hex", +] + +[[package]] +name = "ruint" +version = "1.17.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c141e807189ad38a07276942c6623032d3753c8859c146104ac2e4d68865945a" +dependencies = [ + "alloy-rlp", + "ark-ff 0.3.0", + "ark-ff 0.4.2", + "ark-ff 0.5.0", + "bytes", + "fastrlp 0.3.1", + "fastrlp 0.4.0", + "num-bigint", + "num-integer", + "num-traits", + "parity-scale-codec", + "primitive-types", + "proptest", + "rand 0.8.5", + "rand 0.9.2", + "rlp", + "ruint-macro", + "serde_core", + "valuable", + "zeroize", +] + +[[package]] +name = "ruint-macro" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48fd7bd8a6377e15ad9d42a8ec25371b94ddc67abe7c8b9127bec79bebaaae18" + +[[package]] +name = "rusqlite" +version = "0.32.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7753b721174eb8ff87a9a0e799e2d7bc3749323e773db92e0984debb00019d6e" +dependencies = [ + "bitflags", + "fallible-iterator", + "fallible-streaming-iterator", + "hashlink", + "libsqlite3-sys", + "smallvec", +] + +[[package]] +name = "rustc-hash" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" + +[[package]] +name = "rustc-hex" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6" + +[[package]] +name = "rustc_version" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0dfe2087c51c460008730de8b57e6a320782fbfb312e1f4d520e6c6fae155ee" +dependencies = [ + "semver 0.11.0", +] + +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver 1.0.27", +] + +[[package]] +name = "rustix" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "146c9e247ccc180c1f61615433868c99f3de3ae256a30a43b49f67c2d9171f34" +dependencies = [ + "bitflags", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.61.2", +] + +[[package]] +name = "rustls" +version = "0.23.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c665f33d38cea657d9614f766881e4d510e0eda4239891eea56b4cadcf01801b" +dependencies = [ + "once_cell", + "ring", + "rustls-pki-types", + "rustls-webpki", + "subtle", + "zeroize", +] + +[[package]] +name = "rustls-pki-types" +version = "1.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be040f8b0a225e40375822a563fa9524378b9d63112f53e19ffff34df5d33fdd" +dependencies = [ + "zeroize", +] + +[[package]] +name = "rustls-webpki" +version = "0.103.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7df23109aa6c1567d1c575b9952556388da57401e4ace1d15f79eedad0d8f53" +dependencies = [ + "ring", + "rustls-pki-types", + "untrusted", +] + +[[package]] +name = "rustversion" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" + +[[package]] +name = "rusty-fork" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc6bf79ff24e648f6da1f8d1f011e9cac26491b619e6b9280f2b47f1774e6ee2" +dependencies = [ + "fnv", + "quick-error", + "tempfile", + "wait-timeout", +] + +[[package]] +name = "ryu" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a50f4cf475b65d88e057964e0e9bb1f0aa9bbb2036dc65c64596b42932536984" + +[[package]] +name = "schannel" +version = "0.1.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "891d81b926048e76efe18581bf793546b4c0eaf8448d72be8de2bbee5fd166e1" +dependencies = [ + "windows-sys 0.61.2", +] + +[[package]] +name = "scheduled-thread-pool" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3cbc66816425a074528352f5789333ecff06ca41b36b0b0efdfbb29edc391a19" +dependencies = [ + "parking_lot", +] + +[[package]] +name = "schnellru" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "356285bbf17bea63d9e52e96bd18f039672ac92b55b8cb997d6162a2a37d1649" +dependencies = [ + "ahash", + "cfg-if", + "hashbrown 0.13.2", +] + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "sec1" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" +dependencies = [ + "base16ct", + "der", + "generic-array", + "pkcs8", + "subtle", + "zeroize", +] + +[[package]] +name = "security-framework" +version = "2.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" +dependencies = [ + "bitflags", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc1f0cbffaac4852523ce30d8bd3c5cdc873501d96ff467ca09b6767bb8cd5c0" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "semver" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6" +dependencies = [ + "semver-parser", +] + +[[package]] +name = "semver" +version = "1.0.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" + +[[package]] +name = "semver-parser" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9900206b54a3527fdc7b8a938bffd94a568bac4f4aa8113b209df75a09c0dec2" +dependencies = [ + "pest", +] + +[[package]] +name = "send_wrapper" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd0b0ec5f1c1ca621c432a25813d8d60c88abe6d3e08a3eb9cf37d97a0fe3d73" + +[[package]] +name = "serde" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde_core" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "serde_json" +version = "1.0.149" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" +dependencies = [ + "itoa", + "memchr", + "serde", + "serde_core", + "zmij", +] + +[[package]] +name = "serde_path_to_error" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10a9ff822e371bb5403e391ecd83e182e0e77ba7f6fe0160b795797109d1b457" +dependencies = [ + "itoa", + "serde", + "serde_core", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "sha1" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest 0.10.7", +] + +[[package]] +name = "sha2" +version = "0.10.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest 0.10.7", +] + +[[package]] +name = "sha3" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" +dependencies = [ + "digest 0.10.7", + "keccak", +] + +[[package]] +name = "sha3-asm" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b31139435f327c93c6038ed350ae4588e2c70a13d50599509fee6349967ba35a" +dependencies = [ + "cc", + "cfg-if", +] + +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "signal-hook-registry" +version = "1.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4db69cba1110affc0e9f7bcd48bbf87b3f4fc7c61fc9155afd4c469eb3d6c1b" +dependencies = [ + "errno", + "libc", +] + +[[package]] +name = "signature" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +dependencies = [ + "digest 0.10.7", + "rand_core 0.6.4", +] + +[[package]] +name = "slab" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" + +[[package]] +name = "smallvec" +version = "1.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" +dependencies = [ + "serde", +] + +[[package]] +name = "socket2" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86f4aa3ad99f2088c990dfa82d367e19cb29268ed67c574d10d0a4bfe71f07e0" +dependencies = [ + "libc", + "windows-sys 0.60.2", +] + +[[package]] +name = "spinning_top" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d96d2d1d716fb500937168cc09353ffdc7a012be8475ac7308e1bdf0e3923300" +dependencies = [ + "lock_api", +] + +[[package]] +name = "spki" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +dependencies = [ + "base64ct", + "der", +] + +[[package]] +name = "stable_deref_trait" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "strum" +version = "0.27.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af23d6f6c1a224baef9d3f61e287d2761385a5b88fdab4eb4c6f11aeb54c4bcf" +dependencies = [ + "strum_macros", +] + +[[package]] +name = "strum_macros" +version = "0.27.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7695ce3845ea4b33927c055a39dc438a45b059f7c1b3d91d38d10355fb8cbca7" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.114" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4d107df263a3013ef9b1879b0df87d706ff80f65a86ea879bd9c31f9b307c2a" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn-solidity" +version = "0.8.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab4e6eed052a117409a1a744c8bda9c3ea6934597cf7419f791cb7d590871c4c" +dependencies = [ + "paste", + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "sync_wrapper" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" +dependencies = [ + "futures-core", +] + +[[package]] +name = "synstructure" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + +[[package]] +name = "tempfile" +version = "3.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "655da9c7eb6305c55742045d5a8d2037996d61d8de95806335c7c86ce0f82e9c" +dependencies = [ + "fastrand", + "getrandom 0.3.4", + "once_cell", + "rustix", + "windows-sys 0.61.2", +] + +[[package]] +name = "thiserror" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" +dependencies = [ + "thiserror-impl 1.0.69", +] + +[[package]] +name = "thiserror" +version = "2.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" +dependencies = [ + "thiserror-impl 2.0.18", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "thread_local" +version = "1.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "threadpool" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d050e60b33d41c19108b32cea32164033a9013fe3b46cbd4457559bfbf77afaa" +dependencies = [ + "num_cpus", +] + +[[package]] +name = "tiny-keccak" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" +dependencies = [ + "crunchy", +] + +[[package]] +name = "tinystr" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42d3e9c45c09de15d06dd8acf5f4e0e399e85927b7f00711024eb7ae10fa4869" +dependencies = [ + "displaydoc", + "zerovec", +] + +[[package]] +name = "tokio" +version = "1.49.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72a2903cd7736441aac9df9d7688bd0ce48edccaadf181c3b90be801e81d3d86" +dependencies = [ + "bytes", + "libc", + "mio", + "parking_lot", + "pin-project-lite", + "signal-hook-registry", + "socket2", + "tokio-macros", + "windows-sys 0.61.2", +] + +[[package]] +name = "tokio-macros" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "tokio-native-tls" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" +dependencies = [ + "native-tls", + "tokio", +] + +[[package]] +name = "tokio-rustls" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61" +dependencies = [ + "rustls", + "tokio", +] + +[[package]] +name = "tokio-stream" +version = "0.1.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32da49809aab5c3bc678af03902d4ccddea2a87d028d86392a4b1560c6906c70" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", + "tokio-util", +] + +[[package]] +name = "tokio-tungstenite" +version = "0.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edc5f74e248dc973e0dbb7b74c7e0d6fcc301c694ff50049504004ef4d0cdcd9" +dependencies = [ + "futures-util", + "log", + "rustls", + "rustls-pki-types", + "tokio", + "tokio-rustls", + "tungstenite", + "webpki-roots 0.26.11", +] + +[[package]] +name = "tokio-util" +version = "0.7.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ae9cec805b01e8fc3fd2fe289f89149a9b66dd16786abd8b19cfa7b48cb0098" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "toml_datetime" +version = "0.7.5+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92e1cfed4a3038bc5a127e35a2d360f145e1f4b971b551a2ba5fd7aedf7e1347" +dependencies = [ + "serde_core", +] + +[[package]] +name = "toml_edit" +version = "0.23.10+spec-1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84c8b9f757e028cee9fa244aea147aab2a9ec09d5325a9b01e0a49730c2b5269" +dependencies = [ + "indexmap", + "toml_datetime", + "toml_parser", + "winnow", +] + +[[package]] +name = "toml_parser" +version = "1.0.6+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3198b4b0a8e11f09dd03e133c0280504d0801269e9afa46362ffde1cbeebf44" +dependencies = [ + "winnow", +] + +[[package]] +name = "tower" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebe5ef63511595f1344e2d5cfa636d973292adc0eec1f0ad45fae9f0851ab1d4" +dependencies = [ + "futures-core", + "futures-util", + "pin-project-lite", + "sync_wrapper", + "tokio", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower-http" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4e6559d53cc268e5031cd8429d05415bc4cb4aefc4aa5d6cc35fbf5b924a1f8" +dependencies = [ + "bitflags", + "bytes", + "futures-util", + "http", + "http-body", + "iri-string", + "pin-project-lite", + "tower", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower-layer" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" + +[[package]] +name = "tower-service" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" + +[[package]] +name = "tracing" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" +dependencies = [ + "log", + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "tracing-core" +version = "0.1.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "tracing-log" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f30143827ddab0d256fd843b7a66d164e9f271cfa0dde49142c5ca0ca291f1e" +dependencies = [ + "matchers", + "nu-ansi-term", + "once_cell", + "regex-automata", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", +] + +[[package]] +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + +[[package]] +name = "tungstenite" +version = "0.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18e5b8366ee7a95b16d32197d0b2604b43a0be89dc5fac9f8e96ccafbaedda8a" +dependencies = [ + "byteorder", + "bytes", + "data-encoding", + "http", + "httparse", + "log", + "rand 0.8.5", + "rustls", + "rustls-pki-types", + "sha1", + "thiserror 1.0.69", + "utf-8", +] + +[[package]] +name = "typenum" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" + +[[package]] +name = "ucd-trie" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971" + +[[package]] +name = "uint" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76f64bba2c53b04fcab63c01a7d7427eadc821e3bc48c34dc9ba29c501164b52" +dependencies = [ + "byteorder", + "crunchy", + "hex", + "static_assertions", +] + +[[package]] +name = "unarray" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94" + +[[package]] +name = "unicode-ident" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" + +[[package]] +name = "unicode-segmentation" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" + +[[package]] +name = "unicode-xid" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" + +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + +[[package]] +name = "url" +version = "2.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff67a8a4397373c3ef660812acab3268222035010ab8680ec4215f38ba3d0eed" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", + "serde", +] + +[[package]] +name = "utf-8" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" + +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + +[[package]] +name = "uuid" +version = "1.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee48d38b119b0cd71fe4141b30f5ba9c7c5d9f4e7a3a8b4a674e4b6ef789976f" +dependencies = [ + "getrandom 0.3.4", + "js-sys", + "rand 0.9.2", + "wasm-bindgen", +] + +[[package]] +name = "valuable" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" + +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + +[[package]] +name = "verbeth-indexer" +version = "0.1.0" +dependencies = [ + "alloy", + "axum", + "dotenvy", + "futures-lite", + "governor", + "hex", + "nonzero_ext", + "r2d2", + "r2d2_sqlite", + "rusqlite", + "serde", + "serde_json", + "thiserror 2.0.18", + "tokio", + "tower-http", + "tracing", + "tracing-subscriber", +] + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "wait-timeout" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ac3b126d3914f9849036f826e054cbabdc8519970b8998ddaf3b5bd3c65f11" +dependencies = [ + "libc", +] + +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + +[[package]] +name = "wasi" +version = "0.11.1+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" + +[[package]] +name = "wasip2" +version = "1.0.2+wasi-0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9517f9239f02c069db75e65f174b3da828fe5f5b945c4dd26bd25d89c03ebcf5" +dependencies = [ + "wit-bindgen", +] + +[[package]] +name = "wasm-bindgen" +version = "0.2.108" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64024a30ec1e37399cf85a7ffefebdb72205ca1c972291c51512360d90bd8566" +dependencies = [ + "cfg-if", + "once_cell", + "rustversion", + "wasm-bindgen-macro", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.58" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70a6e77fd0ae8029c9ea0063f87c46fde723e7d887703d74ad2616d792e51e6f" +dependencies = [ + "cfg-if", + "futures-util", + "js-sys", + "once_cell", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.108" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "008b239d9c740232e71bd39e8ef6429d27097518b6b30bdf9086833bd5b6d608" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.108" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5256bae2d58f54820e6490f9839c49780dff84c65aeab9e772f15d5f0e913a55" +dependencies = [ + "bumpalo", + "proc-macro2", + "quote", + "syn 2.0.114", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.108" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f01b580c9ac74c8d8f0c0e4afb04eeef2acf145458e52c03845ee9cd23e3d12" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "wasmtimer" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c598d6b99ea013e35844697fc4670d08339d5cda15588f193c6beedd12f644b" +dependencies = [ + "futures", + "js-sys", + "parking_lot", + "pin-utils", + "slab", + "wasm-bindgen", +] + +[[package]] +name = "web-sys" +version = "0.3.85" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "312e32e551d92129218ea9a2452120f4aabc03529ef03e4d0d82fb2780608598" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "web-time" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "webpki-roots" +version = "0.26.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "521bc38abb08001b01866da9f51eb7c5d647a19260e00054a8c7fd5f9e57f7a9" +dependencies = [ + "webpki-roots 1.0.6", +] + +[[package]] +name = "webpki-roots" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22cfaf3c063993ff62e73cb4311efde4db1efb31ab78a3e5c457939ad5cc0bed" +dependencies = [ + "rustls-pki-types", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" +dependencies = [ + "windows-targets 0.53.5", +] + +[[package]] +name = "windows-sys" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm 0.52.6", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", +] + +[[package]] +name = "windows-targets" +version = "0.53.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" +dependencies = [ + "windows-link", + "windows_aarch64_gnullvm 0.53.1", + "windows_aarch64_msvc 0.53.1", + "windows_i686_gnu 0.53.1", + "windows_i686_gnullvm 0.53.1", + "windows_i686_msvc 0.53.1", + "windows_x86_64_gnu 0.53.1", + "windows_x86_64_gnullvm 0.53.1", + "windows_x86_64_msvc 0.53.1", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnu" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_i686_msvc" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" + +[[package]] +name = "winnow" +version = "0.7.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a5364e9d77fcdeeaa6062ced926ee3381faa2ee02d3eb83a5c27a8825540829" +dependencies = [ + "memchr", +] + +[[package]] +name = "wit-bindgen" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5" + +[[package]] +name = "writeable" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9edde0db4769d2dc68579893f2306b26c6ecfbe0ef499b013d731b7b9247e0b9" + +[[package]] +name = "ws_stream_wasm" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c173014acad22e83f16403ee360115b38846fe754e735c5d9d3803fe70c6abc" +dependencies = [ + "async_io_stream", + "futures", + "js-sys", + "log", + "pharos", + "rustc_version 0.4.1", + "send_wrapper", + "thiserror 2.0.18", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "wyz" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" +dependencies = [ + "tap", +] + +[[package]] +name = "yoke" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72d6e5c6afb84d73944e5cedb052c4680d5657337201555f9f2a16b7406d4954" +dependencies = [ + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", + "synstructure", +] + +[[package]] +name = "zerocopy" +version = "0.8.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57cf3aa6855b23711ee9852dfc97dfaa51c45feaba5b645d0c777414d494a961" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a616990af1a287837c4fe6596ad77ef57948f787e46ce28e166facc0cc1cb75" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "zerofrom" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", + "synstructure", +] + +[[package]] +name = "zeroize" +version = "1.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85a5b4158499876c763cb03bc4e49185d3cccbabb15b33c627f7884f43db852e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "zerotrie" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a59c17a5562d507e4b54960e8569ebee33bee890c70aa3fe7b97e85a9fd7851" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", +] + +[[package]] +name = "zerovec" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c28719294829477f525be0186d13efa9a3c602f7ec202ca9e353d310fb9a002" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "zmij" +version = "1.0.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ff05f8caa9038894637571ae6b9e29466c1f4f829d26c9b28f869a29cbe3445" diff --git a/apps/verbeth-indexer/Cargo.toml b/apps/verbeth-indexer/Cargo.toml new file mode 100644 index 0000000..4aa5566 --- /dev/null +++ b/apps/verbeth-indexer/Cargo.toml @@ -0,0 +1,37 @@ +[package] +name = "verbeth-indexer" +version = "0.1.0" +edition = "2021" +rust-version = "1.84" +default-run = "verbeth-indexer" + +[dependencies] +tokio = { version = "1.43", features = ["full", "signal"] } +axum = { version = "0.8", features = ["macros"] } +tower-http = { version = "0.6", features = ["cors", "trace"] } + +alloy = { version = "0.7", features = [ + "provider-ws", + "provider-http", + "rpc-types-eth", + "sol-types", +]} + +rusqlite = { version = "0.32", features = ["bundled"] } +r2d2 = "0.8" +r2d2_sqlite = "0.25" + +serde = { version = "1.0", features = ["derive"] } +serde_json = "1.0" +dotenvy = "0.15" +tracing = "0.1" +tracing-subscriber = { version = "0.3", features = ["env-filter"] } +thiserror = "2.0" +hex = "0.4" +governor = "0.8" +nonzero_ext = "0.3" +futures-lite = "2.5" + +[profile.release] +lto = true +codegen-units = 1 diff --git a/apps/verbeth-indexer/Dockerfile b/apps/verbeth-indexer/Dockerfile new file mode 100644 index 0000000..39e3798 --- /dev/null +++ b/apps/verbeth-indexer/Dockerfile @@ -0,0 +1,12 @@ +FROM rust:1.84-bookworm AS builder +WORKDIR /app +COPY . . +RUN cargo build --release + +FROM debian:bookworm-slim +RUN apt-get update && apt-get install -y ca-certificates && rm -rf /var/lib/apt/lists/* +COPY --from=builder /app/target/release/verbeth-indexer /usr/local/bin/ +ENV DATABASE_PATH=/data/indexer.db +VOLUME ["/data"] +EXPOSE 3000 +CMD ["verbeth-indexer"] diff --git a/apps/verbeth-indexer/README.md b/apps/verbeth-indexer/README.md new file mode 100644 index 0000000..8c958d5 --- /dev/null +++ b/apps/verbeth-indexer/README.md @@ -0,0 +1,82 @@ +# Verbeth Indexer + +Rust-based event indexer for Verbeth protocol. Listens to on-chain events via WebSocket and persists them in SQLite with stable sequence counters for APSI integration. + +## Features + +- WebSocket subscription to Verbeth contract events +- Historical backfill on startup +- SQLite persistence with WAL mode +- Atomic sequence counters per topic/recipient +- Health endpoint for monitoring +- Graceful shutdown + +## Quick Start + +```bash +cp .env.example .env + +vim .env + +cargo run +``` + +## Environment Variables + +| Variable | Required | Default | Description | +|----------|----------|---------|-------------| +| `RPC_WS_URL` | Yes | - | WebSocket RPC endpoint | +| `RPC_HTTP_URL` | No | derived from WS | HTTP RPC for backfill | +| `CONTRACT_ADDRESS` | No | Verbeth proxy | Contract to index | +| `CREATION_BLOCK` | No | 37097547 | Block to start backfill from | +| `DATABASE_PATH` | No | ./data/indexer.db | SQLite file location | +| `SERVER_PORT` | No | 3000 | HTTP server port | +| `BACKFILL_DAYS` | No | 7 | Days to backfill on empty DB | +| `RUST_LOG` | No | info | Log level | + +## API Endpoints + +### GET /health + +Returns indexer status: + +```json +{ + "status": "ok", + "last_block": 12345678, + "uptime_seconds": 3600, + "counts": { + "messages": 150, + "handshakes": 42, + "handshake_responses": 38 + } +} +``` + +## Deployment + +### Docker + +```bash +docker build -t verbeth-indexer . +docker run -v indexer-data:/data -e RPC_WS_URL=wss://... verbeth-indexer +``` + +### Fly.io + +```bash +fly launch --no-deploy +fly secrets set RPC_WS_URL=wss://... +fly volume create indexer_data --size 1 +fly deploy +``` + +## Database Schema + +Events are stored with stable `seq` counters: + +- `messages(topic, seq)` - MessageSent events +- `handshakes(recipient_hash, seq)` - Handshake events +- `handshake_responses(global_seq)` - HandshakeResponse events + +These counters enable deterministic item identifiers for APSI queries. diff --git a/apps/verbeth-indexer/fly.toml b/apps/verbeth-indexer/fly.toml new file mode 100644 index 0000000..a2d284e --- /dev/null +++ b/apps/verbeth-indexer/fly.toml @@ -0,0 +1,27 @@ +app = "verbeth-indexer" +primary_region = "iad" + +[env] + RUST_LOG = "info" + SERVER_PORT = "3000" + CONTRACT_ADDRESS = "0x82C9c5475D63e4C9e959280e9066aBb24973a663" + CREATION_BLOCK = "37097547" + +[http_service] + internal_port = 3000 + force_https = true + min_machines_running = 1 + +[[http_service.checks]] + path = "/health" + interval = "30s" + timeout = "10s" + +[[mounts]] + source = "indexer_data" + destination = "/data" + +[[vm]] + memory = "512mb" + cpu_kind = "shared" + cpus = 1 diff --git a/apps/verbeth-indexer/indexer.log b/apps/verbeth-indexer/indexer.log new file mode 100644 index 0000000..ff11519 --- /dev/null +++ b/apps/verbeth-indexer/indexer.log @@ -0,0 +1,8913 @@ + Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.51s + Running `target/debug/verbeth-indexer` +2026-02-04T18:52:38.494620Z  INFO verbeth_indexer: Starting Verbeth Indexer v0.1.0 +2026-02-04T18:52:38.494856Z  INFO verbeth_indexer: Contract: 0x82C9c5475D63e4C9e959280e9066aBb24973a663 +2026-02-04T18:52:38.495084Z  INFO verbeth_indexer: Database: ./data/indexer.db +2026-02-04T18:52:38.495172Z  INFO verbeth_indexer: RPC chunk size: 10 blocks +2026-02-04T18:52:38.502462Z  INFO verbeth_indexer::db::schema: Database initialized schema_version=1 +2026-02-04T18:52:38.719450Z  INFO verbeth_indexer: Chain head: 37231435 +2026-02-04T18:52:38.719597Z  INFO verbeth_indexer: Running backfill from block 37097547 to 37231435 +2026-02-04T18:52:38.719771Z  INFO verbeth_indexer::indexer::backfill: Starting backfill from block 37097547 to 37231435 +2026-02-04T18:52:39.054284Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10/133889 blocks (0.0%), 0 events +2026-02-04T18:52:39.087314Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20/133889 blocks (0.0%), 0 events +2026-02-04T18:52:39.131361Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30/133889 blocks (0.0%), 0 events +2026-02-04T18:52:39.168315Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40/133889 blocks (0.0%), 0 events +2026-02-04T18:52:39.204444Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50/133889 blocks (0.0%), 0 events +2026-02-04T18:52:39.246517Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60/133889 blocks (0.0%), 0 events +2026-02-04T18:52:39.488322Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70/133889 blocks (0.1%), 0 events +2026-02-04T18:52:39.644941Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80/133889 blocks (0.1%), 0 events +2026-02-04T18:52:39.784651Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 90/133889 blocks (0.1%), 0 events +2026-02-04T18:52:40.023135Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 100/133889 blocks (0.1%), 0 events +2026-02-04T18:52:40.168610Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 110/133889 blocks (0.1%), 0 events +2026-02-04T18:52:40.503949Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 120/133889 blocks (0.1%), 0 events +2026-02-04T18:52:40.619123Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 130/133889 blocks (0.1%), 0 events +2026-02-04T18:52:40.822565Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 140/133889 blocks (0.1%), 0 events +2026-02-04T18:52:41.063307Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 150/133889 blocks (0.1%), 0 events +2026-02-04T18:52:41.254385Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 160/133889 blocks (0.1%), 0 events +2026-02-04T18:52:41.406927Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 170/133889 blocks (0.1%), 0 events +2026-02-04T18:52:41.646892Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 180/133889 blocks (0.1%), 0 events +2026-02-04T18:52:41.785200Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 190/133889 blocks (0.1%), 0 events +2026-02-04T18:52:42.076797Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 200/133889 blocks (0.1%), 0 events +2026-02-04T18:52:42.239479Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 210/133889 blocks (0.2%), 0 events +2026-02-04T18:52:42.420883Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 220/133889 blocks (0.2%), 0 events +2026-02-04T18:52:42.635744Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 230/133889 blocks (0.2%), 0 events +2026-02-04T18:52:42.830690Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 240/133889 blocks (0.2%), 0 events +2026-02-04T18:52:43.124144Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 250/133889 blocks (0.2%), 0 events +2026-02-04T18:52:43.161223Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 260/133889 blocks (0.2%), 0 events +2026-02-04T18:52:43.461322Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 270/133889 blocks (0.2%), 0 events +2026-02-04T18:52:43.682448Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 280/133889 blocks (0.2%), 0 events +2026-02-04T18:52:43.837930Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 290/133889 blocks (0.2%), 0 events +2026-02-04T18:52:44.038073Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 300/133889 blocks (0.2%), 0 events +2026-02-04T18:52:44.206240Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 310/133889 blocks (0.2%), 0 events +2026-02-04T18:52:44.389362Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 320/133889 blocks (0.2%), 0 events +2026-02-04T18:52:44.588226Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 330/133889 blocks (0.2%), 0 events +2026-02-04T18:52:44.824309Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 340/133889 blocks (0.3%), 0 events +2026-02-04T18:52:45.004511Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 350/133889 blocks (0.3%), 0 events +2026-02-04T18:52:45.253963Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 360/133889 blocks (0.3%), 0 events +2026-02-04T18:52:45.430725Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 370/133889 blocks (0.3%), 0 events +2026-02-04T18:52:45.609726Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 380/133889 blocks (0.3%), 0 events +2026-02-04T18:52:45.806604Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 390/133889 blocks (0.3%), 0 events +2026-02-04T18:52:45.998085Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 400/133889 blocks (0.3%), 0 events +2026-02-04T18:52:46.306013Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 410/133889 blocks (0.3%), 0 events +2026-02-04T18:52:46.441328Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 420/133889 blocks (0.3%), 0 events +2026-02-04T18:52:46.665448Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 430/133889 blocks (0.3%), 0 events +2026-02-04T18:52:46.829507Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 440/133889 blocks (0.3%), 0 events +2026-02-04T18:52:47.030167Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 450/133889 blocks (0.3%), 0 events +2026-02-04T18:52:47.318407Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 460/133889 blocks (0.3%), 0 events +2026-02-04T18:52:47.365813Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 470/133889 blocks (0.4%), 0 events +2026-02-04T18:52:47.640943Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 480/133889 blocks (0.4%), 0 events +2026-02-04T18:52:47.877701Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 490/133889 blocks (0.4%), 0 events +2026-02-04T18:52:48.004951Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 500/133889 blocks (0.4%), 0 events +2026-02-04T18:52:48.179122Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 510/133889 blocks (0.4%), 0 events +2026-02-04T18:52:48.404445Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 520/133889 blocks (0.4%), 0 events +2026-02-04T18:52:48.614726Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 530/133889 blocks (0.4%), 0 events +2026-02-04T18:52:48.892021Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 540/133889 blocks (0.4%), 0 events +2026-02-04T18:52:48.981123Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 550/133889 blocks (0.4%), 0 events +2026-02-04T18:52:49.197623Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 560/133889 blocks (0.4%), 0 events +2026-02-04T18:52:49.452059Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 570/133889 blocks (0.4%), 0 events +2026-02-04T18:52:49.658403Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 580/133889 blocks (0.4%), 0 events +2026-02-04T18:52:49.831494Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 590/133889 blocks (0.4%), 0 events +2026-02-04T18:52:50.049561Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 600/133889 blocks (0.4%), 0 events +2026-02-04T18:52:50.175958Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 610/133889 blocks (0.5%), 0 events +2026-02-04T18:52:50.467497Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 620/133889 blocks (0.5%), 0 events +2026-02-04T18:52:50.603203Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 630/133889 blocks (0.5%), 0 events +2026-02-04T18:52:50.805706Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 640/133889 blocks (0.5%), 0 events +2026-02-04T18:52:51.044774Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 650/133889 blocks (0.5%), 0 events +2026-02-04T18:52:51.173995Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 660/133889 blocks (0.5%), 0 events +2026-02-04T18:52:51.555857Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 670/133889 blocks (0.5%), 0 events +2026-02-04T18:52:51.603404Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 680/133889 blocks (0.5%), 0 events +2026-02-04T18:52:52.063305Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 690/133889 blocks (0.5%), 0 events +2026-02-04T18:52:52.101310Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 700/133889 blocks (0.5%), 0 events +2026-02-04T18:52:52.217515Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 710/133889 blocks (0.5%), 0 events +2026-02-04T18:52:52.416191Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 720/133889 blocks (0.5%), 0 events +2026-02-04T18:52:52.659263Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 730/133889 blocks (0.5%), 0 events +2026-02-04T18:52:52.859538Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 740/133889 blocks (0.6%), 0 events +2026-02-04T18:52:52.987370Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 750/133889 blocks (0.6%), 0 events +2026-02-04T18:52:53.202767Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 760/133889 blocks (0.6%), 0 events +2026-02-04T18:52:53.440239Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 770/133889 blocks (0.6%), 0 events +2026-02-04T18:52:53.646816Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 780/133889 blocks (0.6%), 0 events +2026-02-04T18:52:53.860619Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 790/133889 blocks (0.6%), 0 events +2026-02-04T18:52:54.002684Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 800/133889 blocks (0.6%), 0 events +2026-02-04T18:52:54.232065Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 810/133889 blocks (0.6%), 0 events +2026-02-04T18:52:54.443239Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 820/133889 blocks (0.6%), 0 events +2026-02-04T18:52:54.563914Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 830/133889 blocks (0.6%), 0 events +2026-02-04T18:52:54.833722Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 840/133889 blocks (0.6%), 0 events +2026-02-04T18:52:54.986852Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 850/133889 blocks (0.6%), 0 events +2026-02-04T18:52:55.223132Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 860/133889 blocks (0.6%), 0 events +2026-02-04T18:52:55.376580Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 870/133889 blocks (0.6%), 0 events +2026-02-04T18:52:55.592883Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 880/133889 blocks (0.7%), 0 events +2026-02-04T18:52:55.834398Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 890/133889 blocks (0.7%), 0 events +2026-02-04T18:52:55.976505Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 900/133889 blocks (0.7%), 0 events +2026-02-04T18:52:56.267905Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 910/133889 blocks (0.7%), 0 events +2026-02-04T18:52:56.461471Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 920/133889 blocks (0.7%), 0 events +2026-02-04T18:52:56.618550Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 930/133889 blocks (0.7%), 0 events +2026-02-04T18:52:56.794627Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 940/133889 blocks (0.7%), 0 events +2026-02-04T18:52:57.001156Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 950/133889 blocks (0.7%), 0 events +2026-02-04T18:52:57.311914Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 960/133889 blocks (0.7%), 0 events +2026-02-04T18:52:57.366278Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 970/133889 blocks (0.7%), 0 events +2026-02-04T18:52:57.622584Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 980/133889 blocks (0.7%), 0 events +2026-02-04T18:52:57.834678Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 990/133889 blocks (0.7%), 0 events +2026-02-04T18:52:57.993174Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1000/133889 blocks (0.7%), 0 events +2026-02-04T18:52:58.329607Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1010/133889 blocks (0.8%), 0 events +2026-02-04T18:52:58.367058Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1020/133889 blocks (0.8%), 0 events +2026-02-04T18:52:58.603991Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1030/133889 blocks (0.8%), 0 events +2026-02-04T18:52:58.887833Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1040/133889 blocks (0.8%), 0 events +2026-02-04T18:52:59.017829Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1050/133889 blocks (0.8%), 0 events +2026-02-04T18:52:59.256848Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1060/133889 blocks (0.8%), 0 events +2026-02-04T18:52:59.419868Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1070/133889 blocks (0.8%), 0 events +2026-02-04T18:52:59.586656Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1080/133889 blocks (0.8%), 0 events +2026-02-04T18:52:59.936797Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1090/133889 blocks (0.8%), 0 events +2026-02-04T18:52:59.978415Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1100/133889 blocks (0.8%), 0 events +2026-02-04T18:53:00.186088Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1110/133889 blocks (0.8%), 0 events +2026-02-04T18:53:00.461412Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1120/133889 blocks (0.8%), 0 events +2026-02-04T18:53:00.641531Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1130/133889 blocks (0.8%), 0 events +2026-02-04T18:53:00.779170Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1140/133889 blocks (0.9%), 0 events +2026-02-04T18:53:00.988576Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1150/133889 blocks (0.9%), 0 events +2026-02-04T18:53:01.253064Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1160/133889 blocks (0.9%), 0 events +2026-02-04T18:53:01.511461Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1170/133889 blocks (0.9%), 0 events +2026-02-04T18:53:01.590636Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1180/133889 blocks (0.9%), 0 events +2026-02-04T18:53:01.842590Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1190/133889 blocks (0.9%), 0 events +2026-02-04T18:53:02.245706Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1200/133889 blocks (0.9%), 0 events +2026-02-04T18:53:02.281232Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1210/133889 blocks (0.9%), 0 events +2026-02-04T18:53:02.524808Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1220/133889 blocks (0.9%), 0 events +2026-02-04T18:53:02.570713Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1230/133889 blocks (0.9%), 0 events +2026-02-04T18:53:02.820051Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1240/133889 blocks (0.9%), 0 events +2026-02-04T18:53:03.086574Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1250/133889 blocks (0.9%), 0 events +2026-02-04T18:53:03.246479Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1260/133889 blocks (0.9%), 0 events +2026-02-04T18:53:03.421777Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1270/133889 blocks (0.9%), 0 events +2026-02-04T18:53:03.645001Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1280/133889 blocks (1.0%), 0 events +2026-02-04T18:53:03.864911Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1290/133889 blocks (1.0%), 0 events +2026-02-04T18:53:04.097501Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1300/133889 blocks (1.0%), 0 events +2026-02-04T18:53:04.194317Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1310/133889 blocks (1.0%), 0 events +2026-02-04T18:53:04.457447Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1320/133889 blocks (1.0%), 0 events +2026-02-04T18:53:04.654563Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1330/133889 blocks (1.0%), 0 events +2026-02-04T18:53:04.836350Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1340/133889 blocks (1.0%), 0 events +2026-02-04T18:53:04.982072Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1350/133889 blocks (1.0%), 0 events +2026-02-04T18:53:05.208969Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1360/133889 blocks (1.0%), 0 events +2026-02-04T18:53:05.432316Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1370/133889 blocks (1.0%), 0 events +2026-02-04T18:53:05.700063Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1380/133889 blocks (1.0%), 0 events +2026-02-04T18:53:05.778023Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1390/133889 blocks (1.0%), 0 events +2026-02-04T18:53:06.012395Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1400/133889 blocks (1.0%), 0 events +2026-02-04T18:53:06.224673Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1410/133889 blocks (1.1%), 0 events +2026-02-04T18:53:06.464617Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1420/133889 blocks (1.1%), 0 events +2026-02-04T18:53:06.619303Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1430/133889 blocks (1.1%), 0 events +2026-02-04T18:53:06.792763Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1440/133889 blocks (1.1%), 0 events +2026-02-04T18:53:06.989679Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1450/133889 blocks (1.1%), 0 events +2026-02-04T18:53:07.283099Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1460/133889 blocks (1.1%), 0 events +2026-02-04T18:53:07.404276Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1470/133889 blocks (1.1%), 0 events +2026-02-04T18:53:07.619882Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1480/133889 blocks (1.1%), 0 events +2026-02-04T18:53:07.826134Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1490/133889 blocks (1.1%), 0 events +2026-02-04T18:53:08.043188Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1500/133889 blocks (1.1%), 0 events +2026-02-04T18:53:08.292477Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1510/133889 blocks (1.1%), 0 events +2026-02-04T18:53:08.398051Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1520/133889 blocks (1.1%), 0 events +2026-02-04T18:53:08.619177Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1530/133889 blocks (1.1%), 0 events +2026-02-04T18:53:08.850678Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1540/133889 blocks (1.1%), 0 events +2026-02-04T18:53:08.970665Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1550/133889 blocks (1.2%), 0 events +2026-02-04T18:53:09.243551Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1560/133889 blocks (1.2%), 0 events +2026-02-04T18:53:09.379191Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1570/133889 blocks (1.2%), 0 events +2026-02-04T18:53:09.627083Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1580/133889 blocks (1.2%), 0 events +2026-02-04T18:53:09.905482Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1590/133889 blocks (1.2%), 0 events +2026-02-04T18:53:10.054956Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1600/133889 blocks (1.2%), 0 events +2026-02-04T18:53:10.223432Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1610/133889 blocks (1.2%), 0 events +2026-02-04T18:53:10.418543Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1620/133889 blocks (1.2%), 0 events +2026-02-04T18:53:10.613487Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1630/133889 blocks (1.2%), 0 events +2026-02-04T18:53:10.945153Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1640/133889 blocks (1.2%), 0 events +2026-02-04T18:53:10.987052Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1650/133889 blocks (1.2%), 0 events +2026-02-04T18:53:11.241083Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1660/133889 blocks (1.2%), 0 events +2026-02-04T18:53:11.468529Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1670/133889 blocks (1.2%), 0 events +2026-02-04T18:53:11.606387Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1680/133889 blocks (1.3%), 0 events +2026-02-04T18:53:11.958729Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1690/133889 blocks (1.3%), 0 events +2026-02-04T18:53:11.994371Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1700/133889 blocks (1.3%), 0 events +2026-02-04T18:53:12.233484Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1710/133889 blocks (1.3%), 0 events +2026-02-04T18:53:12.385947Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1720/133889 blocks (1.3%), 0 events +2026-02-04T18:53:12.600202Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1730/133889 blocks (1.3%), 0 events +2026-02-04T18:53:12.798854Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1740/133889 blocks (1.3%), 0 events +2026-02-04T18:53:13.055165Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1750/133889 blocks (1.3%), 0 events +2026-02-04T18:53:13.190572Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1760/133889 blocks (1.3%), 0 events +2026-02-04T18:53:13.382594Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1770/133889 blocks (1.3%), 0 events +2026-02-04T18:53:13.613317Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1780/133889 blocks (1.3%), 0 events +2026-02-04T18:53:13.841637Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1790/133889 blocks (1.3%), 0 events +2026-02-04T18:53:14.057344Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1800/133889 blocks (1.3%), 0 events +2026-02-04T18:53:14.225781Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1810/133889 blocks (1.4%), 0 events +2026-02-04T18:53:14.390552Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1820/133889 blocks (1.4%), 0 events +2026-02-04T18:53:14.642769Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1830/133889 blocks (1.4%), 0 events +2026-02-04T18:53:14.827598Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1840/133889 blocks (1.4%), 0 events +2026-02-04T18:53:15.105147Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1850/133889 blocks (1.4%), 0 events +2026-02-04T18:53:15.180765Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1860/133889 blocks (1.4%), 0 events +2026-02-04T18:53:15.450652Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1870/133889 blocks (1.4%), 0 events +2026-02-04T18:53:15.668528Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1880/133889 blocks (1.4%), 0 events +2026-02-04T18:53:15.831030Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1890/133889 blocks (1.4%), 0 events +2026-02-04T18:53:16.014936Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1900/133889 blocks (1.4%), 0 events +2026-02-04T18:53:16.196942Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1910/133889 blocks (1.4%), 0 events +2026-02-04T18:53:16.378310Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1920/133889 blocks (1.4%), 0 events +2026-02-04T18:53:16.709662Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1930/133889 blocks (1.4%), 0 events +2026-02-04T18:53:16.793281Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1940/133889 blocks (1.4%), 0 events +2026-02-04T18:53:17.031304Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1950/133889 blocks (1.5%), 0 events +2026-02-04T18:53:17.234783Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1960/133889 blocks (1.5%), 0 events +2026-02-04T18:53:17.411886Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1970/133889 blocks (1.5%), 0 events +2026-02-04T18:53:17.625847Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1980/133889 blocks (1.5%), 0 events +2026-02-04T18:53:17.825852Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1990/133889 blocks (1.5%), 0 events +2026-02-04T18:53:17.986246Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2000/133889 blocks (1.5%), 0 events +2026-02-04T18:53:18.252303Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2010/133889 blocks (1.5%), 0 events +2026-02-04T18:53:18.426571Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2020/133889 blocks (1.5%), 0 events +2026-02-04T18:53:18.651551Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2030/133889 blocks (1.5%), 0 events +2026-02-04T18:53:18.842021Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2040/133889 blocks (1.5%), 0 events +2026-02-04T18:53:19.051604Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2050/133889 blocks (1.5%), 0 events +2026-02-04T18:53:19.199550Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2060/133889 blocks (1.5%), 0 events +2026-02-04T18:53:19.361725Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2070/133889 blocks (1.5%), 0 events +2026-02-04T18:53:19.599162Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2080/133889 blocks (1.6%), 0 events +2026-02-04T18:53:19.859318Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2090/133889 blocks (1.6%), 0 events +2026-02-04T18:53:20.057567Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2100/133889 blocks (1.6%), 0 events +2026-02-04T18:53:20.198978Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2110/133889 blocks (1.6%), 0 events +2026-02-04T18:53:20.428595Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2120/133889 blocks (1.6%), 0 events +2026-02-04T18:53:20.670568Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2130/133889 blocks (1.6%), 0 events +2026-02-04T18:53:20.903026Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2140/133889 blocks (1.6%), 0 events +2026-02-04T18:53:20.992191Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2150/133889 blocks (1.6%), 0 events +2026-02-04T18:53:21.179994Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2160/133889 blocks (1.6%), 0 events +2026-02-04T18:53:21.434889Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2170/133889 blocks (1.6%), 0 events +2026-02-04T18:53:21.616983Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2180/133889 blocks (1.6%), 0 events +2026-02-04T18:53:21.786710Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2190/133889 blocks (1.6%), 0 events +2026-02-04T18:53:22.029276Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2200/133889 blocks (1.6%), 0 events +2026-02-04T18:53:22.190847Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2210/133889 blocks (1.6%), 0 events +2026-02-04T18:53:22.444537Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2220/133889 blocks (1.7%), 0 events +2026-02-04T18:53:22.622999Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2230/133889 blocks (1.7%), 0 events +2026-02-04T18:53:22.849126Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2240/133889 blocks (1.7%), 0 events +2026-02-04T18:53:23.049312Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2250/133889 blocks (1.7%), 0 events +2026-02-04T18:53:23.257720Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2260/133889 blocks (1.7%), 0 events +2026-02-04T18:53:23.492181Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2270/133889 blocks (1.7%), 0 events +2026-02-04T18:53:23.658724Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2280/133889 blocks (1.7%), 0 events +2026-02-04T18:53:23.782160Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2290/133889 blocks (1.7%), 0 events +2026-02-04T18:53:24.054859Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2300/133889 blocks (1.7%), 0 events +2026-02-04T18:53:24.239975Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2310/133889 blocks (1.7%), 0 events +2026-02-04T18:53:24.430625Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2320/133889 blocks (1.7%), 0 events +2026-02-04T18:53:24.664503Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2330/133889 blocks (1.7%), 0 events +2026-02-04T18:53:24.840477Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2340/133889 blocks (1.7%), 0 events +2026-02-04T18:53:25.098686Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2350/133889 blocks (1.8%), 0 events +2026-02-04T18:53:25.224026Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2360/133889 blocks (1.8%), 0 events +2026-02-04T18:53:25.375654Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2370/133889 blocks (1.8%), 0 events +2026-02-04T18:53:25.624997Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2380/133889 blocks (1.8%), 0 events +2026-02-04T18:53:25.831336Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2390/133889 blocks (1.8%), 0 events +2026-02-04T18:53:25.999486Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2400/133889 blocks (1.8%), 0 events +2026-02-04T18:53:26.246152Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2410/133889 blocks (1.8%), 0 events +2026-02-04T18:53:26.447172Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2420/133889 blocks (1.8%), 0 events +2026-02-04T18:53:26.670862Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2430/133889 blocks (1.8%), 0 events +2026-02-04T18:53:26.866823Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2440/133889 blocks (1.8%), 0 events +2026-02-04T18:53:27.057005Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2450/133889 blocks (1.8%), 0 events +2026-02-04T18:53:27.225034Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2460/133889 blocks (1.8%), 0 events +2026-02-04T18:53:27.462127Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2470/133889 blocks (1.8%), 0 events +2026-02-04T18:53:27.733644Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2480/133889 blocks (1.9%), 0 events +2026-02-04T18:53:27.776561Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2490/133889 blocks (1.9%), 0 events +2026-02-04T18:53:27.980154Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2500/133889 blocks (1.9%), 0 events +2026-02-04T18:53:28.246779Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2510/133889 blocks (1.9%), 0 events +2026-02-04T18:53:28.414551Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2520/133889 blocks (1.9%), 0 events +2026-02-04T18:53:28.596686Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2530/133889 blocks (1.9%), 0 events +2026-02-04T18:53:28.779946Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2540/133889 blocks (1.9%), 0 events +2026-02-04T18:53:28.985737Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2550/133889 blocks (1.9%), 0 events +2026-02-04T18:53:29.261712Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2560/133889 blocks (1.9%), 0 events +2026-02-04T18:53:29.446534Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2570/133889 blocks (1.9%), 0 events +2026-02-04T18:53:29.593928Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2580/133889 blocks (1.9%), 0 events +2026-02-04T18:53:29.821545Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2590/133889 blocks (1.9%), 0 events +2026-02-04T18:53:30.009048Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2600/133889 blocks (1.9%), 0 events +2026-02-04T18:53:30.213169Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2610/133889 blocks (1.9%), 0 events +2026-02-04T18:53:30.462799Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2620/133889 blocks (2.0%), 0 events +2026-02-04T18:53:30.572113Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2630/133889 blocks (2.0%), 0 events +2026-02-04T18:53:30.868704Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2640/133889 blocks (2.0%), 0 events +2026-02-04T18:53:30.996920Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2650/133889 blocks (2.0%), 0 events +2026-02-04T18:53:31.245386Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2660/133889 blocks (2.0%), 0 events +2026-02-04T18:53:31.405591Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2670/133889 blocks (2.0%), 0 events +2026-02-04T18:53:31.649347Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2680/133889 blocks (2.0%), 0 events +2026-02-04T18:53:31.913307Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2690/133889 blocks (2.0%), 0 events +2026-02-04T18:53:32.005135Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2700/133889 blocks (2.0%), 0 events +2026-02-04T18:53:32.172928Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2710/133889 blocks (2.0%), 0 events +2026-02-04T18:53:32.441782Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2720/133889 blocks (2.0%), 0 events +2026-02-04T18:53:32.613095Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2730/133889 blocks (2.0%), 0 events +2026-02-04T18:53:32.815366Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2740/133889 blocks (2.0%), 0 events +2026-02-04T18:53:32.967023Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2750/133889 blocks (2.1%), 0 events +2026-02-04T18:53:33.181735Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2760/133889 blocks (2.1%), 0 events +2026-02-04T18:53:33.497044Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2770/133889 blocks (2.1%), 0 events +2026-02-04T18:53:33.653833Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2780/133889 blocks (2.1%), 0 events +2026-02-04T18:53:33.831415Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2790/133889 blocks (2.1%), 0 events +2026-02-04T18:53:34.011882Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2800/133889 blocks (2.1%), 0 events +2026-02-04T18:53:34.268444Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2810/133889 blocks (2.1%), 0 events +2026-02-04T18:53:34.373102Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2820/133889 blocks (2.1%), 0 events +2026-02-04T18:53:34.616342Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2830/133889 blocks (2.1%), 0 events +2026-02-04T18:53:34.850455Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2840/133889 blocks (2.1%), 0 events +2026-02-04T18:53:35.061068Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2850/133889 blocks (2.1%), 0 events +2026-02-04T18:53:35.265199Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2860/133889 blocks (2.1%), 0 events +2026-02-04T18:53:35.381250Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2870/133889 blocks (2.1%), 0 events +2026-02-04T18:53:35.626876Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2880/133889 blocks (2.2%), 0 events +2026-02-04T18:53:35.767398Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2890/133889 blocks (2.2%), 0 events +2026-02-04T18:53:36.076777Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2900/133889 blocks (2.2%), 0 events +2026-02-04T18:53:36.168086Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2910/133889 blocks (2.2%), 0 events +2026-02-04T18:53:36.427151Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2920/133889 blocks (2.2%), 0 events +2026-02-04T18:53:36.631871Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2930/133889 blocks (2.2%), 0 events +2026-02-04T18:53:36.828404Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2940/133889 blocks (2.2%), 0 events +2026-02-04T18:53:37.002113Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2950/133889 blocks (2.2%), 0 events +2026-02-04T18:53:37.184940Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2960/133889 blocks (2.2%), 0 events +2026-02-04T18:53:37.430162Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2970/133889 blocks (2.2%), 0 events +2026-02-04T18:53:37.694451Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2980/133889 blocks (2.2%), 0 events +2026-02-04T18:53:37.785621Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2990/133889 blocks (2.2%), 0 events +2026-02-04T18:53:38.018706Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3000/133889 blocks (2.2%), 0 events +2026-02-04T18:53:38.205594Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3010/133889 blocks (2.2%), 0 events +2026-02-04T18:53:38.389720Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3020/133889 blocks (2.3%), 0 events +2026-02-04T18:53:38.569352Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3030/133889 blocks (2.3%), 0 events +2026-02-04T18:53:38.783047Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3040/133889 blocks (2.3%), 0 events +2026-02-04T18:53:39.038754Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3050/133889 blocks (2.3%), 0 events +2026-02-04T18:53:39.259525Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3060/133889 blocks (2.3%), 0 events +2026-02-04T18:53:39.397158Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3070/133889 blocks (2.3%), 0 events +2026-02-04T18:53:39.587498Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3080/133889 blocks (2.3%), 0 events +2026-02-04T18:53:39.824777Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3090/133889 blocks (2.3%), 0 events +2026-02-04T18:53:40.039345Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3100/133889 blocks (2.3%), 0 events +2026-02-04T18:53:40.304562Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3110/133889 blocks (2.3%), 0 events +2026-02-04T18:53:40.439210Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3120/133889 blocks (2.3%), 0 events +2026-02-04T18:53:40.584194Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3130/133889 blocks (2.3%), 0 events +2026-02-04T18:53:40.838632Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3140/133889 blocks (2.3%), 0 events +2026-02-04T18:53:41.033928Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3150/133889 blocks (2.4%), 0 events +2026-02-04T18:53:41.320452Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3160/133889 blocks (2.4%), 0 events +2026-02-04T18:53:41.363959Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3170/133889 blocks (2.4%), 0 events +2026-02-04T18:53:41.628338Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3180/133889 blocks (2.4%), 0 events +2026-02-04T18:53:41.844486Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3190/133889 blocks (2.4%), 0 events +2026-02-04T18:53:42.048641Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3200/133889 blocks (2.4%), 0 events +2026-02-04T18:53:42.223289Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3210/133889 blocks (2.4%), 0 events +2026-02-04T18:53:42.398957Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3220/133889 blocks (2.4%), 0 events +2026-02-04T18:53:42.637639Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3230/133889 blocks (2.4%), 0 events +2026-02-04T18:53:42.922967Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3240/133889 blocks (2.4%), 0 events +2026-02-04T18:53:42.964463Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3250/133889 blocks (2.4%), 0 events +2026-02-04T18:53:43.227972Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3260/133889 blocks (2.4%), 0 events +2026-02-04T18:53:43.449748Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3270/133889 blocks (2.4%), 0 events +2026-02-04T18:53:43.636585Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3280/133889 blocks (2.4%), 0 events +2026-02-04T18:53:43.835747Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3290/133889 blocks (2.5%), 0 events +2026-02-04T18:53:44.001531Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3300/133889 blocks (2.5%), 0 events +2026-02-04T18:53:44.231232Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3310/133889 blocks (2.5%), 0 events +2026-02-04T18:53:44.464826Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3320/133889 blocks (2.5%), 0 events +2026-02-04T18:53:44.616744Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3330/133889 blocks (2.5%), 0 events +2026-02-04T18:53:44.801811Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3340/133889 blocks (2.5%), 0 events +2026-02-04T18:53:45.021102Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3350/133889 blocks (2.5%), 0 events +2026-02-04T18:53:45.252763Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3360/133889 blocks (2.5%), 0 events +2026-02-04T18:53:45.387813Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3370/133889 blocks (2.5%), 0 events +2026-02-04T18:53:45.606489Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3380/133889 blocks (2.5%), 0 events +2026-02-04T18:53:45.854906Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3390/133889 blocks (2.5%), 0 events +2026-02-04T18:53:46.070527Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3400/133889 blocks (2.5%), 0 events +2026-02-04T18:53:46.208862Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3410/133889 blocks (2.5%), 0 events +2026-02-04T18:53:46.461894Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3420/133889 blocks (2.6%), 0 events +2026-02-04T18:53:46.633571Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3430/133889 blocks (2.6%), 0 events +2026-02-04T18:53:46.769265Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3440/133889 blocks (2.6%), 0 events +2026-02-04T18:53:46.965277Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3450/133889 blocks (2.6%), 0 events +2026-02-04T18:53:47.218824Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3460/133889 blocks (2.6%), 0 events +2026-02-04T18:53:47.400228Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3470/133889 blocks (2.6%), 0 events +2026-02-04T18:53:47.648153Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3480/133889 blocks (2.6%), 0 events +2026-02-04T18:53:47.832556Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3490/133889 blocks (2.6%), 0 events +2026-02-04T18:53:48.017580Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3500/133889 blocks (2.6%), 0 events +2026-02-04T18:53:48.209588Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3510/133889 blocks (2.6%), 0 events +2026-02-04T18:53:48.382798Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3520/133889 blocks (2.6%), 0 events +2026-02-04T18:53:48.659606Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3530/133889 blocks (2.6%), 0 events +2026-02-04T18:53:48.847799Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3540/133889 blocks (2.6%), 0 events +2026-02-04T18:53:49.054288Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3550/133889 blocks (2.7%), 0 events +2026-02-04T18:53:49.219440Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3560/133889 blocks (2.7%), 0 events +2026-02-04T18:53:49.374592Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3570/133889 blocks (2.7%), 0 events +2026-02-04T18:53:49.741902Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3580/133889 blocks (2.7%), 0 events +2026-02-04T18:53:49.785979Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3590/133889 blocks (2.7%), 0 events +2026-02-04T18:53:50.028943Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3600/133889 blocks (2.7%), 0 events +2026-02-04T18:53:50.263481Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3610/133889 blocks (2.7%), 0 events +2026-02-04T18:53:50.449201Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3620/133889 blocks (2.7%), 0 events +2026-02-04T18:53:50.614270Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3630/133889 blocks (2.7%), 0 events +2026-02-04T18:53:50.847673Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3640/133889 blocks (2.7%), 0 events +2026-02-04T18:53:51.014348Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3650/133889 blocks (2.7%), 0 events +2026-02-04T18:53:51.172425Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3660/133889 blocks (2.7%), 0 events +2026-02-04T18:53:51.408954Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3670/133889 blocks (2.7%), 0 events +2026-02-04T18:53:51.617268Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3680/133889 blocks (2.7%), 0 events +2026-02-04T18:53:51.866186Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3690/133889 blocks (2.8%), 0 events +2026-02-04T18:53:52.012420Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3700/133889 blocks (2.8%), 0 events +2026-02-04T18:53:52.205125Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3710/133889 blocks (2.8%), 0 events +2026-02-04T18:53:52.406498Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3720/133889 blocks (2.8%), 0 events +2026-02-04T18:53:52.633767Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3730/133889 blocks (2.8%), 0 events +2026-02-04T18:53:52.852869Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3740/133889 blocks (2.8%), 0 events +2026-02-04T18:53:52.966923Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3750/133889 blocks (2.8%), 0 events +2026-02-04T18:53:53.198585Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3760/133889 blocks (2.8%), 0 events +2026-02-04T18:53:53.454847Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3770/133889 blocks (2.8%), 0 events +2026-02-04T18:53:53.566110Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3780/133889 blocks (2.8%), 0 events +2026-02-04T18:53:53.935437Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3790/133889 blocks (2.8%), 0 events +2026-02-04T18:53:53.981320Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3800/133889 blocks (2.8%), 0 events +2026-02-04T18:53:54.164797Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3810/133889 blocks (2.8%), 0 events +2026-02-04T18:53:54.457182Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3820/133889 blocks (2.9%), 0 events +2026-02-04T18:53:54.642697Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3830/133889 blocks (2.9%), 0 events +2026-02-04T18:53:54.802267Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3840/133889 blocks (2.9%), 0 events +2026-02-04T18:53:55.033736Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3850/133889 blocks (2.9%), 0 events +2026-02-04T18:53:55.229080Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3860/133889 blocks (2.9%), 0 events +2026-02-04T18:53:55.472727Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3870/133889 blocks (2.9%), 0 events +2026-02-04T18:53:55.602329Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3880/133889 blocks (2.9%), 0 events +2026-02-04T18:53:55.822377Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3890/133889 blocks (2.9%), 0 events +2026-02-04T18:53:56.028597Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3900/133889 blocks (2.9%), 0 events +2026-02-04T18:53:56.358460Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3910/133889 blocks (2.9%), 0 events +2026-02-04T18:53:56.404139Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3920/133889 blocks (2.9%), 0 events +2026-02-04T18:53:56.567259Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3930/133889 blocks (2.9%), 0 events +2026-02-04T18:53:56.843028Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3940/133889 blocks (2.9%), 0 events +2026-02-04T18:53:57.080217Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3950/133889 blocks (2.9%), 0 events +2026-02-04T18:53:57.166143Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3960/133889 blocks (3.0%), 0 events +2026-02-04T18:53:57.413401Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3970/133889 blocks (3.0%), 0 events +2026-02-04T18:53:57.610047Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3980/133889 blocks (3.0%), 0 events +2026-02-04T18:53:57.781403Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3990/133889 blocks (3.0%), 0 events +2026-02-04T18:53:58.125555Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4000/133889 blocks (3.0%), 0 events +2026-02-04T18:53:58.164389Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4010/133889 blocks (3.0%), 0 events +2026-02-04T18:53:58.450057Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4020/133889 blocks (3.0%), 0 events +2026-02-04T18:53:58.653563Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4030/133889 blocks (3.0%), 0 events +2026-02-04T18:53:58.826066Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4040/133889 blocks (3.0%), 0 events +2026-02-04T18:53:59.036387Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4050/133889 blocks (3.0%), 0 events +2026-02-04T18:53:59.182346Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4060/133889 blocks (3.0%), 0 events +2026-02-04T18:53:59.371328Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4070/133889 blocks (3.0%), 0 events +2026-02-04T18:53:59.697422Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4080/133889 blocks (3.0%), 0 events +2026-02-04T18:53:59.781288Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4090/133889 blocks (3.1%), 0 events +2026-02-04T18:53:59.981690Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4100/133889 blocks (3.1%), 0 events +2026-02-04T18:54:00.239960Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4110/133889 blocks (3.1%), 0 events +2026-02-04T18:54:00.418442Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4120/133889 blocks (3.1%), 0 events +2026-02-04T18:54:00.718469Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4130/133889 blocks (3.1%), 0 events +2026-02-04T18:54:00.829725Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4140/133889 blocks (3.1%), 0 events +2026-02-04T18:54:01.009563Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4150/133889 blocks (3.1%), 0 events +2026-02-04T18:54:01.240395Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4160/133889 blocks (3.1%), 0 events +2026-02-04T18:54:01.447874Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4170/133889 blocks (3.1%), 0 events +2026-02-04T18:54:01.606102Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4180/133889 blocks (3.1%), 0 events +2026-02-04T18:54:01.848258Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4190/133889 blocks (3.1%), 0 events +2026-02-04T18:54:01.969607Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4200/133889 blocks (3.1%), 0 events +2026-02-04T18:54:02.323458Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4210/133889 blocks (3.1%), 0 events +2026-02-04T18:54:02.359514Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4220/133889 blocks (3.2%), 0 events +2026-02-04T18:54:02.573563Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4230/133889 blocks (3.2%), 0 events +2026-02-04T18:54:02.852071Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4240/133889 blocks (3.2%), 0 events +2026-02-04T18:54:03.012972Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4250/133889 blocks (3.2%), 0 events +2026-02-04T18:54:03.235449Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4260/133889 blocks (3.2%), 0 events +2026-02-04T18:54:03.411045Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4270/133889 blocks (3.2%), 0 events +2026-02-04T18:54:03.608774Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4280/133889 blocks (3.2%), 0 events +2026-02-04T18:54:03.903468Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4290/133889 blocks (3.2%), 0 events +2026-02-04T18:54:04.016194Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4300/133889 blocks (3.2%), 0 events +2026-02-04T18:54:04.258396Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4310/133889 blocks (3.2%), 0 events +2026-02-04T18:54:04.451709Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4320/133889 blocks (3.2%), 0 events +2026-02-04T18:54:04.615193Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4330/133889 blocks (3.2%), 0 events +2026-02-04T18:54:04.810127Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4340/133889 blocks (3.2%), 0 events +2026-02-04T18:54:04.980929Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4350/133889 blocks (3.2%), 0 events +2026-02-04T18:54:05.179168Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4360/133889 blocks (3.3%), 0 events +2026-02-04T18:54:05.470645Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4370/133889 blocks (3.3%), 0 events +2026-02-04T18:54:05.661531Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4380/133889 blocks (3.3%), 0 events +2026-02-04T18:54:05.828654Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4390/133889 blocks (3.3%), 0 events +2026-02-04T18:54:06.106794Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4400/133889 blocks (3.3%), 0 events +2026-02-04T18:54:06.230241Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4410/133889 blocks (3.3%), 0 events +2026-02-04T18:54:06.386827Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4420/133889 blocks (3.3%), 0 events +2026-02-04T18:54:06.616380Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4430/133889 blocks (3.3%), 0 events +2026-02-04T18:54:06.797564Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4440/133889 blocks (3.3%), 0 events +2026-02-04T18:54:07.043502Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4450/133889 blocks (3.3%), 0 events +2026-02-04T18:54:07.186641Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4460/133889 blocks (3.3%), 0 events +2026-02-04T18:54:07.418974Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4470/133889 blocks (3.3%), 0 events +2026-02-04T18:54:07.641548Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4480/133889 blocks (3.3%), 0 events +2026-02-04T18:54:07.813109Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4490/133889 blocks (3.4%), 0 events +2026-02-04T18:54:08.091778Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4500/133889 blocks (3.4%), 0 events +2026-02-04T18:54:08.190512Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4510/133889 blocks (3.4%), 0 events +2026-02-04T18:54:08.453088Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4520/133889 blocks (3.4%), 0 events +2026-02-04T18:54:08.658909Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4530/133889 blocks (3.4%), 0 events +2026-02-04T18:54:08.858563Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4540/133889 blocks (3.4%), 0 events +2026-02-04T18:54:09.104418Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4550/133889 blocks (3.4%), 0 events +2026-02-04T18:54:09.201653Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4560/133889 blocks (3.4%), 0 events +2026-02-04T18:54:09.393608Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4570/133889 blocks (3.4%), 0 events +2026-02-04T18:54:09.663702Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4580/133889 blocks (3.4%), 0 events +2026-02-04T18:54:09.830526Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4590/133889 blocks (3.4%), 0 events +2026-02-04T18:54:09.997797Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4600/133889 blocks (3.4%), 0 events +2026-02-04T18:54:10.237755Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4610/133889 blocks (3.4%), 0 events +2026-02-04T18:54:10.359104Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4620/133889 blocks (3.4%), 0 events +2026-02-04T18:54:10.715525Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4630/133889 blocks (3.5%), 0 events +2026-02-04T18:54:10.798758Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4640/133889 blocks (3.5%), 0 events +2026-02-04T18:54:11.033174Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4650/133889 blocks (3.5%), 0 events +2026-02-04T18:54:11.262169Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4660/133889 blocks (3.5%), 0 events +2026-02-04T18:54:11.417392Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4670/133889 blocks (3.5%), 0 events +2026-02-04T18:54:11.578135Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4680/133889 blocks (3.5%), 0 events +2026-02-04T18:54:11.849155Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4690/133889 blocks (3.5%), 0 events +2026-02-04T18:54:12.005150Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4700/133889 blocks (3.5%), 0 events +2026-02-04T18:54:12.251412Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4710/133889 blocks (3.5%), 0 events +2026-02-04T18:54:12.454227Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4720/133889 blocks (3.5%), 0 events +2026-02-04T18:54:12.646812Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4730/133889 blocks (3.5%), 0 events +2026-02-04T18:54:12.811630Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4740/133889 blocks (3.5%), 0 events +2026-02-04T18:54:13.045286Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4750/133889 blocks (3.5%), 0 events +2026-02-04T18:54:13.299791Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4760/133889 blocks (3.6%), 0 events +2026-02-04T18:54:13.380155Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4770/133889 blocks (3.6%), 0 events +2026-02-04T18:54:13.659085Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4780/133889 blocks (3.6%), 0 events +2026-02-04T18:54:13.854295Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4790/133889 blocks (3.6%), 0 events +2026-02-04T18:54:14.010742Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4800/133889 blocks (3.6%), 0 events +2026-02-04T18:54:14.255339Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4810/133889 blocks (3.6%), 0 events +2026-02-04T18:54:14.424028Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4820/133889 blocks (3.6%), 0 events +2026-02-04T18:54:14.635621Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4830/133889 blocks (3.6%), 0 events +2026-02-04T18:54:14.905812Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4840/133889 blocks (3.6%), 0 events +2026-02-04T18:54:14.969304Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4850/133889 blocks (3.6%), 0 events +2026-02-04T18:54:15.210388Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4860/133889 blocks (3.6%), 0 events +2026-02-04T18:54:15.432419Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4870/133889 blocks (3.6%), 0 events +2026-02-04T18:54:15.598886Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4880/133889 blocks (3.6%), 0 events +2026-02-04T18:54:15.780778Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4890/133889 blocks (3.7%), 0 events +2026-02-04T18:54:15.970573Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4900/133889 blocks (3.7%), 0 events +2026-02-04T18:54:16.258225Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4910/133889 blocks (3.7%), 0 events +2026-02-04T18:54:16.446881Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4920/133889 blocks (3.7%), 0 events +2026-02-04T18:54:16.652923Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4930/133889 blocks (3.7%), 0 events +2026-02-04T18:54:16.829421Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4940/133889 blocks (3.7%), 0 events +2026-02-04T18:54:17.040173Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4950/133889 blocks (3.7%), 0 events +2026-02-04T18:54:17.248548Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4960/133889 blocks (3.7%), 0 events +2026-02-04T18:54:17.373671Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4970/133889 blocks (3.7%), 0 events +2026-02-04T18:54:17.574805Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4980/133889 blocks (3.7%), 0 events +2026-02-04T18:54:17.880763Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4990/133889 blocks (3.7%), 0 events +2026-02-04T18:54:18.067991Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5000/133889 blocks (3.7%), 0 events +2026-02-04T18:54:18.240765Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5010/133889 blocks (3.7%), 0 events +2026-02-04T18:54:18.543846Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5020/133889 blocks (3.7%), 0 events +2026-02-04T18:54:18.583024Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5030/133889 blocks (3.8%), 0 events +2026-02-04T18:54:18.787487Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5040/133889 blocks (3.8%), 0 events +2026-02-04T18:54:19.068283Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5050/133889 blocks (3.8%), 0 events +2026-02-04T18:54:19.193270Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5060/133889 blocks (3.8%), 0 events +2026-02-04T18:54:19.397891Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5070/133889 blocks (3.8%), 0 events +2026-02-04T18:54:19.656749Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5080/133889 blocks (3.8%), 0 events +2026-02-04T18:54:19.843563Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5090/133889 blocks (3.8%), 0 events +2026-02-04T18:54:20.114027Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5100/133889 blocks (3.8%), 0 events +2026-02-04T18:54:20.196851Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5110/133889 blocks (3.8%), 0 events +2026-02-04T18:54:20.431529Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5120/133889 blocks (3.8%), 0 events +2026-02-04T18:54:20.671175Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5130/133889 blocks (3.8%), 0 events +2026-02-04T18:54:20.816646Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5140/133889 blocks (3.8%), 0 events +2026-02-04T18:54:20.991231Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5150/133889 blocks (3.8%), 0 events +2026-02-04T18:54:21.198188Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5160/133889 blocks (3.9%), 0 events +2026-02-04T18:54:21.420752Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5170/133889 blocks (3.9%), 0 events +2026-02-04T18:54:21.719503Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5180/133889 blocks (3.9%), 0 events +2026-02-04T18:54:21.808466Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5190/133889 blocks (3.9%), 0 events +2026-02-04T18:54:22.029090Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5200/133889 blocks (3.9%), 0 events +2026-02-04T18:54:22.244958Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5210/133889 blocks (3.9%), 0 events +2026-02-04T18:54:22.400918Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5220/133889 blocks (3.9%), 0 events +2026-02-04T18:54:22.737038Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5230/133889 blocks (3.9%), 0 events +2026-02-04T18:54:22.774123Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5240/133889 blocks (3.9%), 0 events +2026-02-04T18:54:23.066274Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5250/133889 blocks (3.9%), 0 events +2026-02-04T18:54:23.291976Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5260/133889 blocks (3.9%), 0 events +2026-02-04T18:54:23.363633Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5270/133889 blocks (3.9%), 0 events +2026-02-04T18:54:23.583293Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5280/133889 blocks (3.9%), 0 events +2026-02-04T18:54:23.846719Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5290/133889 blocks (4.0%), 0 events +2026-02-04T18:54:24.008969Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5300/133889 blocks (4.0%), 0 events +2026-02-04T18:54:24.309490Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5310/133889 blocks (4.0%), 0 events +2026-02-04T18:54:24.384347Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5320/133889 blocks (4.0%), 0 events +2026-02-04T18:54:24.644539Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5330/133889 blocks (4.0%), 0 events +2026-02-04T18:54:24.865077Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5340/133889 blocks (4.0%), 0 events +2026-02-04T18:54:24.964605Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5350/133889 blocks (4.0%), 0 events +2026-02-04T18:54:25.210361Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5360/133889 blocks (4.0%), 0 events +2026-02-04T18:54:25.426276Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5370/133889 blocks (4.0%), 0 events +2026-02-04T18:54:25.651076Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5380/133889 blocks (4.0%), 0 events +2026-02-04T18:54:25.918340Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5390/133889 blocks (4.0%), 0 events +2026-02-04T18:54:26.002164Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5400/133889 blocks (4.0%), 0 events +2026-02-04T18:54:26.240462Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5410/133889 blocks (4.0%), 0 events +2026-02-04T18:54:26.445467Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5420/133889 blocks (4.0%), 0 events +2026-02-04T18:54:26.665605Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5430/133889 blocks (4.1%), 0 events +2026-02-04T18:54:26.835975Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5440/133889 blocks (4.1%), 0 events +2026-02-04T18:54:26.997912Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5450/133889 blocks (4.1%), 0 events +2026-02-04T18:54:27.258792Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5460/133889 blocks (4.1%), 0 events +2026-02-04T18:54:27.456114Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5470/133889 blocks (4.1%), 0 events +2026-02-04T18:54:27.644877Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5480/133889 blocks (4.1%), 0 events +2026-02-04T18:54:27.856207Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5490/133889 blocks (4.1%), 0 events +2026-02-04T18:54:28.012253Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5500/133889 blocks (4.1%), 0 events +2026-02-04T18:54:28.207918Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5510/133889 blocks (4.1%), 0 events +2026-02-04T18:54:28.381874Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5520/133889 blocks (4.1%), 0 events +2026-02-04T18:54:28.664797Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5530/133889 blocks (4.1%), 0 events +2026-02-04T18:54:28.825260Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5540/133889 blocks (4.1%), 0 events +2026-02-04T18:54:29.065799Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5550/133889 blocks (4.1%), 0 events +2026-02-04T18:54:29.180159Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5560/133889 blocks (4.2%), 0 events +2026-02-04T18:54:29.377802Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5570/133889 blocks (4.2%), 0 events +2026-02-04T18:54:29.637833Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5580/133889 blocks (4.2%), 0 events +2026-02-04T18:54:29.789378Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5590/133889 blocks (4.2%), 0 events +2026-02-04T18:54:30.110111Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5600/133889 blocks (4.2%), 0 events +2026-02-04T18:54:30.221719Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5610/133889 blocks (4.2%), 0 events +2026-02-04T18:54:30.402560Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5620/133889 blocks (4.2%), 0 events +2026-02-04T18:54:30.635820Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5630/133889 blocks (4.2%), 0 events +2026-02-04T18:54:30.801646Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5640/133889 blocks (4.2%), 0 events +2026-02-04T18:54:30.991537Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5650/133889 blocks (4.2%), 0 events +2026-02-04T18:54:31.226699Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5660/133889 blocks (4.2%), 0 events +2026-02-04T18:54:31.448882Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5670/133889 blocks (4.2%), 0 events +2026-02-04T18:54:31.683677Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5680/133889 blocks (4.2%), 0 events +2026-02-04T18:54:31.803978Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5690/133889 blocks (4.2%), 0 events +2026-02-04T18:54:31.989366Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5700/133889 blocks (4.3%), 0 events +2026-02-04T18:54:32.206437Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5710/133889 blocks (4.3%), 0 events +2026-02-04T18:54:32.379439Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5720/133889 blocks (4.3%), 0 events +2026-02-04T18:54:32.697796Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5730/133889 blocks (4.3%), 0 events +2026-02-04T18:54:32.793134Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5740/133889 blocks (4.3%), 0 events +2026-02-04T18:54:33.014143Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5750/133889 blocks (4.3%), 0 events +2026-02-04T18:54:33.256183Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5760/133889 blocks (4.3%), 0 events +2026-02-04T18:54:33.420644Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5770/133889 blocks (4.3%), 0 events +2026-02-04T18:54:33.585845Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5780/133889 blocks (4.3%), 0 events +2026-02-04T18:54:33.819198Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5790/133889 blocks (4.3%), 0 events +2026-02-04T18:54:33.972703Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5800/133889 blocks (4.3%), 0 events +2026-02-04T18:54:34.302187Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5810/133889 blocks (4.3%), 0 events +2026-02-04T18:54:34.404835Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5820/133889 blocks (4.3%), 0 events +2026-02-04T18:54:34.662742Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5830/133889 blocks (4.4%), 0 events +2026-02-04T18:54:34.828349Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5840/133889 blocks (4.4%), 0 events +2026-02-04T18:54:35.030120Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5850/133889 blocks (4.4%), 0 events +2026-02-04T18:54:35.320158Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5860/133889 blocks (4.4%), 0 events +2026-02-04T18:54:35.359494Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5870/133889 blocks (4.4%), 0 events +2026-02-04T18:54:35.602481Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5880/133889 blocks (4.4%), 0 events +2026-02-04T18:54:35.875040Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5890/133889 blocks (4.4%), 0 events +2026-02-04T18:54:36.001618Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5900/133889 blocks (4.4%), 0 events +2026-02-04T18:54:36.223533Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5910/133889 blocks (4.4%), 0 events +2026-02-04T18:54:36.398036Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5920/133889 blocks (4.4%), 0 events +2026-02-04T18:54:36.618349Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5930/133889 blocks (4.4%), 0 events +2026-02-04T18:54:36.891987Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5940/133889 blocks (4.4%), 0 events +2026-02-04T18:54:37.035605Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5950/133889 blocks (4.4%), 0 events +2026-02-04T18:54:37.233892Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5960/133889 blocks (4.5%), 0 events +2026-02-04T18:54:37.462232Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5970/133889 blocks (4.5%), 0 events +2026-02-04T18:54:37.582184Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5980/133889 blocks (4.5%), 0 events +2026-02-04T18:54:37.940277Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5990/133889 blocks (4.5%), 0 events +2026-02-04T18:54:37.981980Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6000/133889 blocks (4.5%), 0 events +2026-02-04T18:54:38.252988Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6010/133889 blocks (4.5%), 0 events +2026-02-04T18:54:38.464942Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6020/133889 blocks (4.5%), 0 events +2026-02-04T18:54:38.633905Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6030/133889 blocks (4.5%), 0 events +2026-02-04T18:54:38.829534Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6040/133889 blocks (4.5%), 0 events +2026-02-04T18:54:39.057092Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6050/133889 blocks (4.5%), 0 events +2026-02-04T18:54:39.178700Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6060/133889 blocks (4.5%), 0 events +2026-02-04T18:54:39.407083Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6070/133889 blocks (4.5%), 0 events +2026-02-04T18:54:39.631526Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6080/133889 blocks (4.5%), 0 events +2026-02-04T18:54:39.785866Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6090/133889 blocks (4.5%), 0 events +2026-02-04T18:54:40.072112Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6100/133889 blocks (4.6%), 0 events +2026-02-04T18:54:40.254725Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6110/133889 blocks (4.6%), 0 events +2026-02-04T18:54:40.444287Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6120/133889 blocks (4.6%), 0 events +2026-02-04T18:54:40.605758Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6130/133889 blocks (4.6%), 0 events +2026-02-04T18:54:40.837540Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6140/133889 blocks (4.6%), 0 events +2026-02-04T18:54:41.083720Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6150/133889 blocks (4.6%), 0 events +2026-02-04T18:54:41.229011Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6160/133889 blocks (4.6%), 0 events +2026-02-04T18:54:41.418451Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6170/133889 blocks (4.6%), 0 events +2026-02-04T18:54:41.656404Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6180/133889 blocks (4.6%), 0 events +2026-02-04T18:54:41.811542Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6190/133889 blocks (4.6%), 0 events +2026-02-04T18:54:42.027747Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6200/133889 blocks (4.6%), 0 events +2026-02-04T18:54:42.193303Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6210/133889 blocks (4.6%), 0 events +2026-02-04T18:54:42.375586Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6220/133889 blocks (4.6%), 0 events +2026-02-04T18:54:42.658437Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6230/133889 blocks (4.7%), 0 events +2026-02-04T18:54:42.862230Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6240/133889 blocks (4.7%), 0 events +2026-02-04T18:54:42.989930Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6250/133889 blocks (4.7%), 0 events +2026-02-04T18:54:43.219659Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6260/133889 blocks (4.7%), 0 events +2026-02-04T18:54:43.468004Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6270/133889 blocks (4.7%), 0 events +2026-02-04T18:54:43.617027Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6280/133889 blocks (4.7%), 0 events +2026-02-04T18:54:43.772674Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6290/133889 blocks (4.7%), 0 events +2026-02-04T18:54:44.041709Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6300/133889 blocks (4.7%), 0 events +2026-02-04T18:54:44.262822Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6310/133889 blocks (4.7%), 0 events +2026-02-04T18:54:44.422958Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6320/133889 blocks (4.7%), 0 events +2026-02-04T18:54:44.754264Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6330/133889 blocks (4.7%), 0 events +2026-02-04T18:54:44.788868Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6340/133889 blocks (4.7%), 0 events +2026-02-04T18:54:45.010654Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6350/133889 blocks (4.7%), 0 events +2026-02-04T18:54:45.314652Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6360/133889 blocks (4.7%), 0 events +2026-02-04T18:54:45.392842Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6370/133889 blocks (4.8%), 0 events +2026-02-04T18:54:45.660019Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6380/133889 blocks (4.8%), 0 events +2026-02-04T18:54:45.835765Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6390/133889 blocks (4.8%), 0 events +2026-02-04T18:54:45.969679Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6400/133889 blocks (4.8%), 0 events +2026-02-04T18:54:46.233517Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6410/133889 blocks (4.8%), 0 events +2026-02-04T18:54:46.414740Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6420/133889 blocks (4.8%), 0 events +2026-02-04T18:54:46.571843Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6430/133889 blocks (4.8%), 0 events +2026-02-04T18:54:46.885104Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6440/133889 blocks (4.8%), 0 events +2026-02-04T18:54:47.030187Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6450/133889 blocks (4.8%), 0 events +2026-02-04T18:54:47.236244Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6460/133889 blocks (4.8%), 0 events +2026-02-04T18:54:47.438667Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6470/133889 blocks (4.8%), 0 events +2026-02-04T18:54:47.649966Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6480/133889 blocks (4.8%), 0 events +2026-02-04T18:54:47.776690Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6490/133889 blocks (4.8%), 0 events +2026-02-04T18:54:48.003373Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6500/133889 blocks (4.9%), 0 events +2026-02-04T18:54:48.261530Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6510/133889 blocks (4.9%), 0 events +2026-02-04T18:54:48.460912Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6520/133889 blocks (4.9%), 0 events +2026-02-04T18:54:48.645874Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6530/133889 blocks (4.9%), 0 events +2026-02-04T18:54:48.775302Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6540/133889 blocks (4.9%), 0 events +2026-02-04T18:54:49.034130Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6550/133889 blocks (4.9%), 0 events +2026-02-04T18:54:49.192195Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6560/133889 blocks (4.9%), 0 events +2026-02-04T18:54:49.510767Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6570/133889 blocks (4.9%), 0 events +2026-02-04T18:54:49.637751Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6580/133889 blocks (4.9%), 0 events +2026-02-04T18:54:49.843656Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6590/133889 blocks (4.9%), 0 events +2026-02-04T18:54:50.069327Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6600/133889 blocks (4.9%), 0 events +2026-02-04T18:54:50.247195Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6610/133889 blocks (4.9%), 0 events +2026-02-04T18:54:50.420627Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6620/133889 blocks (4.9%), 0 events +2026-02-04T18:54:50.636102Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6630/133889 blocks (5.0%), 0 events +2026-02-04T18:54:50.807632Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6640/133889 blocks (5.0%), 0 events +2026-02-04T18:54:51.078968Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6650/133889 blocks (5.0%), 0 events +2026-02-04T18:54:51.184959Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6660/133889 blocks (5.0%), 0 events +2026-02-04T18:54:51.414100Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6670/133889 blocks (5.0%), 0 events +2026-02-04T18:54:51.603031Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6680/133889 blocks (5.0%), 0 events +2026-02-04T18:54:51.801972Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6690/133889 blocks (5.0%), 0 events +2026-02-04T18:54:51.986295Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6700/133889 blocks (5.0%), 0 events +2026-02-04T18:54:52.248383Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6710/133889 blocks (5.0%), 0 events +2026-02-04T18:54:52.457695Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6720/133889 blocks (5.0%), 0 events +2026-02-04T18:54:52.653994Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6730/133889 blocks (5.0%), 0 events +2026-02-04T18:54:52.827793Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6740/133889 blocks (5.0%), 0 events +2026-02-04T18:54:53.030710Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6750/133889 blocks (5.0%), 0 events +2026-02-04T18:54:53.184530Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6760/133889 blocks (5.0%), 0 events +2026-02-04T18:54:53.454415Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6770/133889 blocks (5.1%), 0 events +2026-02-04T18:54:53.714680Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6780/133889 blocks (5.1%), 0 events +2026-02-04T18:54:53.849030Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6790/133889 blocks (5.1%), 0 events +2026-02-04T18:54:54.022547Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6800/133889 blocks (5.1%), 0 events +2026-02-04T18:54:54.266019Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6810/133889 blocks (5.1%), 0 events +2026-02-04T18:54:54.437016Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6820/133889 blocks (5.1%), 0 events +2026-02-04T18:54:54.609423Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6830/133889 blocks (5.1%), 0 events +2026-02-04T18:54:54.781194Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6840/133889 blocks (5.1%), 0 events +2026-02-04T18:54:54.983711Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6850/133889 blocks (5.1%), 0 events +2026-02-04T18:54:55.277858Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6860/133889 blocks (5.1%), 0 events +2026-02-04T18:54:55.428168Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6870/133889 blocks (5.1%), 0 events +2026-02-04T18:54:55.633373Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6880/133889 blocks (5.1%), 0 events +2026-02-04T18:54:55.796165Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6890/133889 blocks (5.1%), 0 events +2026-02-04T18:54:56.003797Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6900/133889 blocks (5.2%), 0 events +2026-02-04T18:54:56.289229Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6910/133889 blocks (5.2%), 0 events +2026-02-04T18:54:56.375241Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6920/133889 blocks (5.2%), 0 events +2026-02-04T18:54:56.655447Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6930/133889 blocks (5.2%), 0 events +2026-02-04T18:54:56.843805Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6940/133889 blocks (5.2%), 0 events +2026-02-04T18:54:57.043755Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6950/133889 blocks (5.2%), 0 events +2026-02-04T18:54:57.200451Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6960/133889 blocks (5.2%), 0 events +2026-02-04T18:54:57.390518Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6970/133889 blocks (5.2%), 0 events +2026-02-04T18:54:57.562317Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6980/133889 blocks (5.2%), 0 events +2026-02-04T18:54:57.861710Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6990/133889 blocks (5.2%), 0 events +2026-02-04T18:54:58.008734Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7000/133889 blocks (5.2%), 0 events +2026-02-04T18:54:58.213053Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7010/133889 blocks (5.2%), 0 events +2026-02-04T18:54:58.417186Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7020/133889 blocks (5.2%), 0 events +2026-02-04T18:54:58.582283Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7030/133889 blocks (5.2%), 0 events +2026-02-04T18:54:58.781428Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7040/133889 blocks (5.3%), 0 events +2026-02-04T18:54:59.052802Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7050/133889 blocks (5.3%), 0 events +2026-02-04T18:54:59.168676Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7060/133889 blocks (5.3%), 0 events +2026-02-04T18:54:59.471422Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7070/133889 blocks (5.3%), 0 events +2026-02-04T18:54:59.636074Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7080/133889 blocks (5.3%), 0 events +2026-02-04T18:54:59.808468Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7090/133889 blocks (5.3%), 0 events +2026-02-04T18:55:00.056800Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7100/133889 blocks (5.3%), 0 events +2026-02-04T18:55:00.264787Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7110/133889 blocks (5.3%), 0 events +2026-02-04T18:55:00.483790Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7120/133889 blocks (5.3%), 0 events +2026-02-04T18:55:00.620949Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7130/133889 blocks (5.3%), 0 events +2026-02-04T18:55:00.850210Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7140/133889 blocks (5.3%), 0 events +2026-02-04T18:55:01.044154Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7150/133889 blocks (5.3%), 0 events +2026-02-04T18:55:01.245978Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7160/133889 blocks (5.3%), 0 events +2026-02-04T18:55:01.413650Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7170/133889 blocks (5.4%), 0 events +2026-02-04T18:55:01.659595Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7180/133889 blocks (5.4%), 0 events +2026-02-04T18:55:01.808508Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7190/133889 blocks (5.4%), 0 events +2026-02-04T18:55:02.053418Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7200/133889 blocks (5.4%), 0 events +2026-02-04T18:55:02.269236Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7210/133889 blocks (5.4%), 0 events +2026-02-04T18:55:02.409902Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7220/133889 blocks (5.4%), 0 events +2026-02-04T18:55:02.621288Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7230/133889 blocks (5.4%), 0 events +2026-02-04T18:55:02.865826Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7240/133889 blocks (5.4%), 0 events +2026-02-04T18:55:02.982794Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7250/133889 blocks (5.4%), 0 events +2026-02-04T18:55:03.176014Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7260/133889 blocks (5.4%), 0 events +2026-02-04T18:55:03.460443Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7270/133889 blocks (5.4%), 0 events +2026-02-04T18:55:03.662086Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7280/133889 blocks (5.4%), 0 events +2026-02-04T18:55:03.806955Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7290/133889 blocks (5.4%), 0 events +2026-02-04T18:55:03.998762Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7300/133889 blocks (5.5%), 0 events +2026-02-04T18:55:04.237840Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7310/133889 blocks (5.5%), 0 events +2026-02-04T18:55:04.431684Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7320/133889 blocks (5.5%), 0 events +2026-02-04T18:55:04.719701Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7330/133889 blocks (5.5%), 0 events +2026-02-04T18:55:04.771101Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7340/133889 blocks (5.5%), 0 events +2026-02-04T18:55:04.983831Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7350/133889 blocks (5.5%), 0 events +2026-02-04T18:55:05.239740Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7360/133889 blocks (5.5%), 0 events +2026-02-04T18:55:05.391120Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7370/133889 blocks (5.5%), 0 events +2026-02-04T18:55:05.627140Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7380/133889 blocks (5.5%), 0 events +2026-02-04T18:55:05.843619Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7390/133889 blocks (5.5%), 0 events +2026-02-04T18:55:06.022731Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7400/133889 blocks (5.5%), 0 events +2026-02-04T18:55:06.286078Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7410/133889 blocks (5.5%), 0 events +2026-02-04T18:55:06.424932Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7420/133889 blocks (5.5%), 0 events +2026-02-04T18:55:06.592690Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7430/133889 blocks (5.5%), 0 events +2026-02-04T18:55:06.805382Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7440/133889 blocks (5.6%), 0 events +2026-02-04T18:55:07.041655Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7450/133889 blocks (5.6%), 0 events +2026-02-04T18:55:07.166679Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7460/133889 blocks (5.6%), 0 events +2026-02-04T18:55:07.432840Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7470/133889 blocks (5.6%), 0 events +2026-02-04T18:55:07.658962Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7480/133889 blocks (5.6%), 0 events +2026-02-04T18:55:07.862391Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7490/133889 blocks (5.6%), 0 events +2026-02-04T18:55:07.969030Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7500/133889 blocks (5.6%), 0 events +2026-02-04T18:55:08.197652Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7510/133889 blocks (5.6%), 0 events +2026-02-04T18:55:08.387563Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7520/133889 blocks (5.6%), 0 events +2026-02-04T18:55:08.576004Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7530/133889 blocks (5.6%), 0 events +2026-02-04T18:55:08.905680Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7540/133889 blocks (5.6%), 0 events +2026-02-04T18:55:08.999736Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7550/133889 blocks (5.6%), 0 events +2026-02-04T18:55:09.199598Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7560/133889 blocks (5.6%), 0 events +2026-02-04T18:55:09.454230Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7570/133889 blocks (5.7%), 0 events +2026-02-04T18:55:09.583367Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7580/133889 blocks (5.7%), 0 events +2026-02-04T18:55:09.789631Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7590/133889 blocks (5.7%), 0 events +2026-02-04T18:55:10.002228Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7600/133889 blocks (5.7%), 0 events +2026-02-04T18:55:10.243801Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7610/133889 blocks (5.7%), 0 events +2026-02-04T18:55:10.484430Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7620/133889 blocks (5.7%), 0 events +2026-02-04T18:55:10.603134Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7630/133889 blocks (5.7%), 0 events +2026-02-04T18:55:10.813445Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7640/133889 blocks (5.7%), 0 events +2026-02-04T18:55:11.004029Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7650/133889 blocks (5.7%), 0 events +2026-02-04T18:55:11.247792Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7660/133889 blocks (5.7%), 0 events +2026-02-04T18:55:11.367818Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7670/133889 blocks (5.7%), 0 events +2026-02-04T18:55:11.582486Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7680/133889 blocks (5.7%), 0 events +2026-02-04T18:55:11.784209Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7690/133889 blocks (5.7%), 0 events +2026-02-04T18:55:12.045916Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7700/133889 blocks (5.8%), 0 events +2026-02-04T18:55:12.198062Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7710/133889 blocks (5.8%), 0 events +2026-02-04T18:55:12.399367Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7720/133889 blocks (5.8%), 0 events +2026-02-04T18:55:12.574521Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7730/133889 blocks (5.8%), 0 events +2026-02-04T18:55:12.869340Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7740/133889 blocks (5.8%), 0 events +2026-02-04T18:55:13.066612Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7750/133889 blocks (5.8%), 0 events +2026-02-04T18:55:13.184257Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7760/133889 blocks (5.8%), 0 events +2026-02-04T18:55:13.440403Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7770/133889 blocks (5.8%), 0 events +2026-02-04T18:55:13.626565Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7780/133889 blocks (5.8%), 0 events +2026-02-04T18:55:13.796541Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7790/133889 blocks (5.8%), 0 events +2026-02-04T18:55:13.973190Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7800/133889 blocks (5.8%), 0 events +2026-02-04T18:55:14.206053Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7810/133889 blocks (5.8%), 0 events +2026-02-04T18:55:14.449421Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7820/133889 blocks (5.8%), 0 events +2026-02-04T18:55:14.671550Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7830/133889 blocks (5.8%), 0 events +2026-02-04T18:55:14.823017Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7840/133889 blocks (5.9%), 0 events +2026-02-04T18:55:15.044009Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7850/133889 blocks (5.9%), 0 events +2026-02-04T18:55:15.253757Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7860/133889 blocks (5.9%), 0 events +2026-02-04T18:55:15.375457Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7870/133889 blocks (5.9%), 0 events +2026-02-04T18:55:15.581216Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7880/133889 blocks (5.9%), 0 events +2026-02-04T18:55:15.777748Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7890/133889 blocks (5.9%), 0 events +2026-02-04T18:55:16.052636Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7900/133889 blocks (5.9%), 0 events +2026-02-04T18:55:16.244726Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7910/133889 blocks (5.9%), 0 events +2026-02-04T18:55:16.389551Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7920/133889 blocks (5.9%), 0 events +2026-02-04T18:55:16.592365Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7930/133889 blocks (5.9%), 0 events +2026-02-04T18:55:16.860117Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7940/133889 blocks (5.9%), 0 events +2026-02-04T18:55:16.996172Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7950/133889 blocks (5.9%), 0 events +2026-02-04T18:55:17.292109Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7960/133889 blocks (5.9%), 0 events +2026-02-04T18:55:17.423389Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7970/133889 blocks (6.0%), 0 events +2026-02-04T18:55:17.606675Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7980/133889 blocks (6.0%), 0 events +2026-02-04T18:55:17.859706Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7990/133889 blocks (6.0%), 0 events +2026-02-04T18:55:17.974066Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8000/133889 blocks (6.0%), 0 events +2026-02-04T18:55:18.310073Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8010/133889 blocks (6.0%), 0 events +2026-02-04T18:55:18.406140Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8020/133889 blocks (6.0%), 0 events +2026-02-04T18:55:18.658384Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8030/133889 blocks (6.0%), 0 events +2026-02-04T18:55:18.869839Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8040/133889 blocks (6.0%), 0 events +2026-02-04T18:55:18.968930Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8050/133889 blocks (6.0%), 0 events +2026-02-04T18:55:19.181092Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8060/133889 blocks (6.0%), 0 events +2026-02-04T18:55:19.444118Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8070/133889 blocks (6.0%), 0 events +2026-02-04T18:55:19.636422Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8080/133889 blocks (6.0%), 0 events +2026-02-04T18:55:19.881079Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8090/133889 blocks (6.0%), 0 events +2026-02-04T18:55:20.041429Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8100/133889 blocks (6.0%), 0 events +2026-02-04T18:55:20.251624Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8110/133889 blocks (6.1%), 0 events +2026-02-04T18:55:20.452947Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8120/133889 blocks (6.1%), 0 events +2026-02-04T18:55:20.641737Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8130/133889 blocks (6.1%), 0 events +2026-02-04T18:55:20.813213Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8140/133889 blocks (6.1%), 0 events +2026-02-04T18:55:21.031423Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8150/133889 blocks (6.1%), 0 events +2026-02-04T18:55:21.179883Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8160/133889 blocks (6.1%), 0 events +2026-02-04T18:55:21.453472Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8170/133889 blocks (6.1%), 0 events +2026-02-04T18:55:21.582897Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8180/133889 blocks (6.1%), 0 events +2026-02-04T18:55:21.834923Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8190/133889 blocks (6.1%), 0 events +2026-02-04T18:55:22.030010Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8200/133889 blocks (6.1%), 0 events +2026-02-04T18:55:22.220812Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8210/133889 blocks (6.1%), 0 events +2026-02-04T18:55:22.408505Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8220/133889 blocks (6.1%), 0 events +2026-02-04T18:55:22.605112Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8230/133889 blocks (6.1%), 0 events +2026-02-04T18:55:22.795421Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8240/133889 blocks (6.2%), 0 events +2026-02-04T18:55:23.064907Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8250/133889 blocks (6.2%), 0 events +2026-02-04T18:55:23.213300Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8260/133889 blocks (6.2%), 0 events +2026-02-04T18:55:23.420456Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8270/133889 blocks (6.2%), 0 events +2026-02-04T18:55:23.584561Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8280/133889 blocks (6.2%), 0 events +2026-02-04T18:55:23.796594Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8290/133889 blocks (6.2%), 0 events +2026-02-04T18:55:24.076322Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8300/133889 blocks (6.2%), 0 events +2026-02-04T18:55:24.262889Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8310/133889 blocks (6.2%), 0 events +2026-02-04T18:55:24.454319Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8320/133889 blocks (6.2%), 0 events +2026-02-04T18:55:24.631771Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8330/133889 blocks (6.2%), 0 events +2026-02-04T18:55:24.793627Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8340/133889 blocks (6.2%), 0 events +2026-02-04T18:55:24.980996Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8350/133889 blocks (6.2%), 0 events +2026-02-04T18:55:25.179015Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8360/133889 blocks (6.2%), 0 events +2026-02-04T18:55:25.415645Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8370/133889 blocks (6.3%), 0 events +2026-02-04T18:55:25.685695Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8380/133889 blocks (6.3%), 0 events +2026-02-04T18:55:25.798537Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8390/133889 blocks (6.3%), 0 events +2026-02-04T18:55:26.029809Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8400/133889 blocks (6.3%), 0 events +2026-02-04T18:55:26.211939Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8410/133889 blocks (6.3%), 0 events +2026-02-04T18:55:26.396276Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8420/133889 blocks (6.3%), 0 events +2026-02-04T18:55:26.696437Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8430/133889 blocks (6.3%), 0 events +2026-02-04T18:55:26.771471Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8440/133889 blocks (6.3%), 0 events +2026-02-04T18:55:27.056102Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8450/133889 blocks (6.3%), 0 events +2026-02-04T18:55:27.507441Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8460/133889 blocks (6.3%), 0 events +2026-02-04T18:55:27.555005Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8470/133889 blocks (6.3%), 0 events +2026-02-04T18:55:27.594057Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8480/133889 blocks (6.3%), 0 events +2026-02-04T18:55:27.849572Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8490/133889 blocks (6.3%), 0 events +2026-02-04T18:55:28.007663Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8500/133889 blocks (6.3%), 0 events +2026-02-04T18:55:28.304326Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8510/133889 blocks (6.4%), 0 events +2026-02-04T18:55:28.376849Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8520/133889 blocks (6.4%), 0 events +2026-02-04T18:55:28.648167Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8530/133889 blocks (6.4%), 0 events +2026-02-04T18:55:28.847086Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8540/133889 blocks (6.4%), 0 events +2026-02-04T18:55:29.010418Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8550/133889 blocks (6.4%), 0 events +2026-02-04T18:55:29.317598Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8560/133889 blocks (6.4%), 0 events +2026-02-04T18:55:29.436825Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8570/133889 blocks (6.4%), 0 events +2026-02-04T18:55:29.633624Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8580/133889 blocks (6.4%), 0 events +2026-02-04T18:55:29.876696Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8590/133889 blocks (6.4%), 0 events +2026-02-04T18:55:30.001782Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8600/133889 blocks (6.4%), 0 events +2026-02-04T18:55:30.248037Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8610/133889 blocks (6.4%), 0 events +2026-02-04T18:55:30.405405Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8620/133889 blocks (6.4%), 0 events +2026-02-04T18:55:30.654112Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8630/133889 blocks (6.4%), 0 events +2026-02-04T18:55:30.892697Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8640/133889 blocks (6.5%), 0 events +2026-02-04T18:55:31.022005Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8650/133889 blocks (6.5%), 0 events +2026-02-04T18:55:31.219927Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8660/133889 blocks (6.5%), 0 events +2026-02-04T18:55:31.451012Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8670/133889 blocks (6.5%), 0 events +2026-02-04T18:55:31.581106Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8680/133889 blocks (6.5%), 0 events +2026-02-04T18:55:31.939654Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8690/133889 blocks (6.5%), 0 events +2026-02-04T18:55:31.981328Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8700/133889 blocks (6.5%), 0 events +2026-02-04T18:55:32.270974Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8710/133889 blocks (6.5%), 0 events +2026-02-04T18:55:32.363829Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8720/133889 blocks (6.5%), 0 events +2026-02-04T18:55:32.638128Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8730/133889 blocks (6.5%), 0 events +2026-02-04T18:55:32.833524Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8740/133889 blocks (6.5%), 0 events +2026-02-04T18:55:33.025646Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8750/133889 blocks (6.5%), 0 events +2026-02-04T18:55:33.266013Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8760/133889 blocks (6.5%), 0 events +2026-02-04T18:55:33.391321Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8770/133889 blocks (6.5%), 0 events +2026-02-04T18:55:33.608546Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8780/133889 blocks (6.6%), 0 events +2026-02-04T18:55:33.819369Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8790/133889 blocks (6.6%), 0 events +2026-02-04T18:55:34.090600Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8800/133889 blocks (6.6%), 0 events +2026-02-04T18:55:34.232997Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8810/133889 blocks (6.6%), 0 events +2026-02-04T18:55:34.401360Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8820/133889 blocks (6.6%), 0 events +2026-02-04T18:55:34.608766Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8830/133889 blocks (6.6%), 0 events +2026-02-04T18:55:34.817835Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8840/133889 blocks (6.6%), 0 events +2026-02-04T18:55:35.129546Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8850/133889 blocks (6.6%), 0 events +2026-02-04T18:55:35.168904Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8860/133889 blocks (6.6%), 0 events +2026-02-04T18:55:35.414533Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8870/133889 blocks (6.6%), 0 events +2026-02-04T18:55:35.648416Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8880/133889 blocks (6.6%), 0 events +2026-02-04T18:55:35.818434Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8890/133889 blocks (6.6%), 0 events +2026-02-04T18:55:35.991914Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8900/133889 blocks (6.6%), 0 events +2026-02-04T18:55:36.223156Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8910/133889 blocks (6.7%), 0 events +2026-02-04T18:55:36.447383Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8920/133889 blocks (6.7%), 0 events +2026-02-04T18:55:36.657535Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8930/133889 blocks (6.7%), 0 events +2026-02-04T18:55:36.840957Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8940/133889 blocks (6.7%), 0 events +2026-02-04T18:55:36.972847Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8950/133889 blocks (6.7%), 0 events +2026-02-04T18:55:37.214866Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8960/133889 blocks (6.7%), 0 events +2026-02-04T18:55:37.423836Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8970/133889 blocks (6.7%), 0 events +2026-02-04T18:55:37.747053Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8980/133889 blocks (6.7%), 0 events +2026-02-04T18:55:37.798005Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8990/133889 blocks (6.7%), 0 events +2026-02-04T18:55:38.045386Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9000/133889 blocks (6.7%), 0 events +2026-02-04T18:55:38.261522Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9010/133889 blocks (6.7%), 0 events +2026-02-04T18:55:38.436508Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9020/133889 blocks (6.7%), 0 events +2026-02-04T18:55:38.574785Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9030/133889 blocks (6.7%), 0 events +2026-02-04T18:55:38.791967Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9040/133889 blocks (6.8%), 0 events +2026-02-04T18:55:39.040920Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9050/133889 blocks (6.8%), 0 events +2026-02-04T18:55:39.316405Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9060/133889 blocks (6.8%), 0 events +2026-02-04T18:55:39.369530Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9070/133889 blocks (6.8%), 0 events +2026-02-04T18:55:39.615144Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9080/133889 blocks (6.8%), 0 events +2026-02-04T18:55:39.837972Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9090/133889 blocks (6.8%), 0 events +2026-02-04T18:55:40.032427Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9100/133889 blocks (6.8%), 0 events +2026-02-04T18:55:40.190859Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9110/133889 blocks (6.8%), 0 events +2026-02-04T18:55:40.457829Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9120/133889 blocks (6.8%), 0 events +2026-02-04T18:55:40.573566Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9130/133889 blocks (6.8%), 0 events +2026-02-04T18:55:40.852070Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9140/133889 blocks (6.8%), 0 events +2026-02-04T18:55:40.983392Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9150/133889 blocks (6.8%), 0 events +2026-02-04T18:55:41.265675Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9160/133889 blocks (6.8%), 0 events +2026-02-04T18:55:41.443591Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9170/133889 blocks (6.8%), 0 events +2026-02-04T18:55:41.605919Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9180/133889 blocks (6.9%), 0 events +2026-02-04T18:55:41.934272Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9190/133889 blocks (6.9%), 0 events +2026-02-04T18:55:41.978121Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9200/133889 blocks (6.9%), 0 events +2026-02-04T18:55:42.207365Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9210/133889 blocks (6.9%), 0 events +2026-02-04T18:55:42.458739Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9220/133889 blocks (6.9%), 0 events +2026-02-04T18:55:42.621439Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9230/133889 blocks (6.9%), 0 events +2026-02-04T18:55:42.851256Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9240/133889 blocks (6.9%), 0 events +2026-02-04T18:55:43.020469Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9250/133889 blocks (6.9%), 0 events +2026-02-04T18:55:43.198241Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9260/133889 blocks (6.9%), 0 events +2026-02-04T18:55:43.512518Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9270/133889 blocks (6.9%), 0 events +2026-02-04T18:55:43.641543Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9280/133889 blocks (6.9%), 0 events +2026-02-04T18:55:43.782643Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9290/133889 blocks (6.9%), 0 events +2026-02-04T18:55:44.063060Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9300/133889 blocks (6.9%), 0 events +2026-02-04T18:55:44.233230Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9310/133889 blocks (7.0%), 0 events +2026-02-04T18:55:44.520613Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9320/133889 blocks (7.0%), 0 events +2026-02-04T18:55:44.556494Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9330/133889 blocks (7.0%), 0 events +2026-02-04T18:55:44.820699Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9340/133889 blocks (7.0%), 0 events +2026-02-04T18:55:45.079985Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9350/133889 blocks (7.0%), 0 events +2026-02-04T18:55:45.266173Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9360/133889 blocks (7.0%), 0 events +2026-02-04T18:55:45.418765Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9370/133889 blocks (7.0%), 0 events +2026-02-04T18:55:45.624352Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9380/133889 blocks (7.0%), 0 events +2026-02-04T18:55:45.821696Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9390/133889 blocks (7.0%), 0 events +2026-02-04T18:55:46.000247Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9400/133889 blocks (7.0%), 0 events +2026-02-04T18:55:46.250054Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9410/133889 blocks (7.0%), 0 events +2026-02-04T18:55:46.429780Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9420/133889 blocks (7.0%), 0 events +2026-02-04T18:55:46.655094Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9430/133889 blocks (7.0%), 0 events +2026-02-04T18:55:46.809116Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9440/133889 blocks (7.0%), 0 events +2026-02-04T18:55:47.141033Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9450/133889 blocks (7.1%), 0 events +2026-02-04T18:55:47.178815Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9460/133889 blocks (7.1%), 0 events +2026-02-04T18:55:47.393898Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9470/133889 blocks (7.1%), 0 events +2026-02-04T18:55:47.699686Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9480/133889 blocks (7.1%), 0 events +2026-02-04T18:55:47.823045Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9490/133889 blocks (7.1%), 0 events +2026-02-04T18:55:48.027031Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9500/133889 blocks (7.1%), 0 events +2026-02-04T18:55:48.235683Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9510/133889 blocks (7.1%), 0 events +2026-02-04T18:55:48.429995Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9520/133889 blocks (7.1%), 0 events +2026-02-04T18:55:48.714153Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9530/133889 blocks (7.1%), 0 events +2026-02-04T18:55:48.787840Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9540/133889 blocks (7.1%), 0 events +2026-02-04T18:55:48.969578Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9550/133889 blocks (7.1%), 0 events +2026-02-04T18:55:49.274531Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9560/133889 blocks (7.1%), 0 events +2026-02-04T18:55:49.448226Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9570/133889 blocks (7.1%), 0 events +2026-02-04T18:55:49.621027Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9580/133889 blocks (7.2%), 0 events +2026-02-04T18:55:49.808514Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9590/133889 blocks (7.2%), 0 events +2026-02-04T18:55:49.994297Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9600/133889 blocks (7.2%), 0 events +2026-02-04T18:55:50.180561Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9610/133889 blocks (7.2%), 0 events +2026-02-04T18:55:50.430715Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9620/133889 blocks (7.2%), 0 events +2026-02-04T18:55:50.617840Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9630/133889 blocks (7.2%), 0 events +2026-02-04T18:55:50.846112Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9640/133889 blocks (7.2%), 0 events +2026-02-04T18:55:51.037930Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9650/133889 blocks (7.2%), 0 events +2026-02-04T18:55:51.240870Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9660/133889 blocks (7.2%), 0 events +2026-02-04T18:55:51.386275Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9670/133889 blocks (7.2%), 0 events +2026-02-04T18:55:51.574941Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9680/133889 blocks (7.2%), 0 events +2026-02-04T18:55:51.909864Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9690/133889 blocks (7.2%), 0 events +2026-02-04T18:55:52.013452Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9700/133889 blocks (7.2%), 0 events +2026-02-04T18:55:52.193804Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9710/133889 blocks (7.3%), 0 events +2026-02-04T18:55:52.416205Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9720/133889 blocks (7.3%), 0 events +2026-02-04T18:55:52.575145Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9730/133889 blocks (7.3%), 0 events +2026-02-04T18:55:52.798455Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9740/133889 blocks (7.3%), 0 events +2026-02-04T18:55:53.049558Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9750/133889 blocks (7.3%), 0 events +2026-02-04T18:55:53.315675Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9760/133889 blocks (7.3%), 0 events +2026-02-04T18:55:53.464552Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9770/133889 blocks (7.3%), 0 events +2026-02-04T18:55:53.610217Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9780/133889 blocks (7.3%), 0 events +2026-02-04T18:55:53.784541Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9790/133889 blocks (7.3%), 0 events +2026-02-04T18:55:54.017722Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9800/133889 blocks (7.3%), 0 events +2026-02-04T18:55:54.241563Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9810/133889 blocks (7.3%), 0 events +2026-02-04T18:55:54.518032Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9820/133889 blocks (7.3%), 0 events +2026-02-04T18:55:54.625803Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9830/133889 blocks (7.3%), 0 events +2026-02-04T18:55:54.791467Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9840/133889 blocks (7.3%), 0 events +2026-02-04T18:55:55.053066Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9850/133889 blocks (7.4%), 0 events +2026-02-04T18:55:55.168455Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9860/133889 blocks (7.4%), 0 events +2026-02-04T18:55:55.409659Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9870/133889 blocks (7.4%), 0 events +2026-02-04T18:55:55.609531Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9880/133889 blocks (7.4%), 0 events +2026-02-04T18:55:55.798598Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9890/133889 blocks (7.4%), 0 events +2026-02-04T18:55:56.053550Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9900/133889 blocks (7.4%), 0 events +2026-02-04T18:55:56.246722Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9910/133889 blocks (7.4%), 0 events +2026-02-04T18:55:56.410584Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9920/133889 blocks (7.4%), 0 events +2026-02-04T18:55:56.613634Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9930/133889 blocks (7.4%), 0 events +2026-02-04T18:55:56.808401Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9940/133889 blocks (7.4%), 0 events +2026-02-04T18:55:56.989819Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9950/133889 blocks (7.4%), 0 events +2026-02-04T18:55:57.238514Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9960/133889 blocks (7.4%), 0 events +2026-02-04T18:55:57.456595Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9970/133889 blocks (7.4%), 0 events +2026-02-04T18:55:57.664435Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9980/133889 blocks (7.5%), 0 events +2026-02-04T18:55:57.829943Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9990/133889 blocks (7.5%), 0 events +2026-02-04T18:55:58.054469Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10000/133889 blocks (7.5%), 0 events +2026-02-04T18:55:58.235739Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10010/133889 blocks (7.5%), 0 events +2026-02-04T18:55:58.396711Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10020/133889 blocks (7.5%), 0 events +2026-02-04T18:55:58.585768Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10030/133889 blocks (7.5%), 0 events +2026-02-04T18:55:58.854862Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10040/133889 blocks (7.5%), 0 events +2026-02-04T18:55:58.977718Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10050/133889 blocks (7.5%), 0 events +2026-02-04T18:55:59.255133Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10060/133889 blocks (7.5%), 0 events +2026-02-04T18:55:59.376293Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10070/133889 blocks (7.5%), 0 events +2026-02-04T18:55:59.783581Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10080/133889 blocks (7.5%), 0 events +2026-02-04T18:55:59.822448Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10090/133889 blocks (7.5%), 0 events +2026-02-04T18:55:59.976401Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10100/133889 blocks (7.5%), 0 events +2026-02-04T18:56:00.440954Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10110/133889 blocks (7.6%), 0 events +2026-02-04T18:56:00.480390Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10120/133889 blocks (7.6%), 0 events +2026-02-04T18:56:00.655850Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10130/133889 blocks (7.6%), 0 events +2026-02-04T18:56:00.825190Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10140/133889 blocks (7.6%), 0 events +2026-02-04T18:56:01.048619Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10150/133889 blocks (7.6%), 0 events +2026-02-04T18:56:01.298788Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10160/133889 blocks (7.6%), 0 events +2026-02-04T18:56:01.468660Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10170/133889 blocks (7.6%), 0 events +2026-02-04T18:56:01.577566Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10180/133889 blocks (7.6%), 0 events +2026-02-04T18:56:01.857093Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10190/133889 blocks (7.6%), 0 events +2026-02-04T18:56:02.000958Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10200/133889 blocks (7.6%), 0 events +2026-02-04T18:56:02.229827Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10210/133889 blocks (7.6%), 0 events +2026-02-04T18:56:02.438781Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10220/133889 blocks (7.6%), 0 events +2026-02-04T18:56:02.656099Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10230/133889 blocks (7.6%), 0 events +2026-02-04T18:56:02.905703Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10240/133889 blocks (7.6%), 0 events +2026-02-04T18:56:02.970857Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10250/133889 blocks (7.7%), 0 events +2026-02-04T18:56:03.183025Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10260/133889 blocks (7.7%), 0 events +2026-02-04T18:56:03.432041Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10270/133889 blocks (7.7%), 0 events +2026-02-04T18:56:03.619941Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10280/133889 blocks (7.7%), 0 events +2026-02-04T18:56:03.957596Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10290/133889 blocks (7.7%), 0 events +2026-02-04T18:56:03.998961Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10300/133889 blocks (7.7%), 0 events +2026-02-04T18:56:04.187683Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10310/133889 blocks (7.7%), 0 events +2026-02-04T18:56:04.475791Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10320/133889 blocks (7.7%), 0 events +2026-02-04T18:56:04.588915Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10330/133889 blocks (7.7%), 0 events +2026-02-04T18:56:04.873721Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10340/133889 blocks (7.7%), 0 events +2026-02-04T18:56:05.062220Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10350/133889 blocks (7.7%), 0 events +2026-02-04T18:56:05.268979Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10360/133889 blocks (7.7%), 0 events +2026-02-04T18:56:05.493465Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10370/133889 blocks (7.7%), 0 events +2026-02-04T18:56:05.604982Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10380/133889 blocks (7.8%), 0 events +2026-02-04T18:56:05.792416Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10390/133889 blocks (7.8%), 0 events +2026-02-04T18:56:06.048178Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10400/133889 blocks (7.8%), 0 events +2026-02-04T18:56:06.172010Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10410/133889 blocks (7.8%), 0 events +2026-02-04T18:56:06.393985Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10420/133889 blocks (7.8%), 0 events +2026-02-04T18:56:06.643231Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10430/133889 blocks (7.8%), 0 events +2026-02-04T18:56:06.832741Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10440/133889 blocks (7.8%), 0 events +2026-02-04T18:56:07.064839Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10450/133889 blocks (7.8%), 0 events +2026-02-04T18:56:07.239943Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10460/133889 blocks (7.8%), 0 events +2026-02-04T18:56:07.443157Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10470/133889 blocks (7.8%), 0 events +2026-02-04T18:56:07.621340Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10480/133889 blocks (7.8%), 0 events +2026-02-04T18:56:07.845893Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10490/133889 blocks (7.8%), 0 events +2026-02-04T18:56:08.147571Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10500/133889 blocks (7.8%), 0 events +2026-02-04T18:56:08.196256Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10510/133889 blocks (7.8%), 0 events +2026-02-04T18:56:08.409737Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10520/133889 blocks (7.9%), 0 events +2026-02-04T18:56:08.638116Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10530/133889 blocks (7.9%), 0 events +2026-02-04T18:56:08.843552Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10540/133889 blocks (7.9%), 0 events +2026-02-04T18:56:09.018120Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10550/133889 blocks (7.9%), 0 events +2026-02-04T18:56:09.201577Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10560/133889 blocks (7.9%), 0 events +2026-02-04T18:56:09.424244Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10570/133889 blocks (7.9%), 0 events +2026-02-04T18:56:09.716712Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10580/133889 blocks (7.9%), 0 events +2026-02-04T18:56:09.791495Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10590/133889 blocks (7.9%), 0 events +2026-02-04T18:56:10.065659Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10600/133889 blocks (7.9%), 0 events +2026-02-04T18:56:10.244936Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10610/133889 blocks (7.9%), 0 events +2026-02-04T18:56:10.425196Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10620/133889 blocks (7.9%), 0 events +2026-02-04T18:56:10.577723Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10630/133889 blocks (7.9%), 0 events +2026-02-04T18:56:10.862380Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10640/133889 blocks (7.9%), 0 events +2026-02-04T18:56:10.987608Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10650/133889 blocks (8.0%), 0 events +2026-02-04T18:56:11.169048Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10660/133889 blocks (8.0%), 0 events +2026-02-04T18:56:11.465829Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10670/133889 blocks (8.0%), 0 events +2026-02-04T18:56:11.646938Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10680/133889 blocks (8.0%), 0 events +2026-02-04T18:56:11.829644Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10690/133889 blocks (8.0%), 0 events +2026-02-04T18:56:12.026960Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10700/133889 blocks (8.0%), 0 events +2026-02-04T18:56:12.308291Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10710/133889 blocks (8.0%), 0 events +2026-02-04T18:56:12.398829Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10720/133889 blocks (8.0%), 0 events +2026-02-04T18:56:12.661157Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10730/133889 blocks (8.0%), 0 events +2026-02-04T18:56:12.866825Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10740/133889 blocks (8.0%), 0 events +2026-02-04T18:56:13.022434Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10750/133889 blocks (8.0%), 0 events +2026-02-04T18:56:13.192851Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10760/133889 blocks (8.0%), 0 events +2026-02-04T18:56:13.410165Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10770/133889 blocks (8.0%), 0 events +2026-02-04T18:56:13.670884Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10780/133889 blocks (8.1%), 0 events +2026-02-04T18:56:13.778233Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10790/133889 blocks (8.1%), 0 events +2026-02-04T18:56:14.013961Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10800/133889 blocks (8.1%), 0 events +2026-02-04T18:56:14.208592Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10810/133889 blocks (8.1%), 0 events +2026-02-04T18:56:14.444653Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10820/133889 blocks (8.1%), 0 events +2026-02-04T18:56:14.588226Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10830/133889 blocks (8.1%), 0 events +2026-02-04T18:56:14.769717Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10840/133889 blocks (8.1%), 0 events +2026-02-04T18:56:14.986448Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10850/133889 blocks (8.1%), 0 events +2026-02-04T18:56:15.188616Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10860/133889 blocks (8.1%), 0 events +2026-02-04T18:56:15.498522Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10870/133889 blocks (8.1%), 0 events +2026-02-04T18:56:15.608694Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10880/133889 blocks (8.1%), 0 events +2026-02-04T18:56:15.781301Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10890/133889 blocks (8.1%), 0 events +2026-02-04T18:56:16.017962Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10900/133889 blocks (8.1%), 0 events +2026-02-04T18:56:16.191146Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10910/133889 blocks (8.1%), 0 events +2026-02-04T18:56:16.392304Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10920/133889 blocks (8.2%), 0 events +2026-02-04T18:56:16.651454Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10930/133889 blocks (8.2%), 0 events +2026-02-04T18:56:16.832918Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10940/133889 blocks (8.2%), 0 events +2026-02-04T18:56:17.056651Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10950/133889 blocks (8.2%), 0 events +2026-02-04T18:56:17.241207Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10960/133889 blocks (8.2%), 0 events +2026-02-04T18:56:17.374696Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10970/133889 blocks (8.2%), 0 events +2026-02-04T18:56:17.626223Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10980/133889 blocks (8.2%), 0 events +2026-02-04T18:56:17.817573Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10990/133889 blocks (8.2%), 0 events +2026-02-04T18:56:18.110323Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11000/133889 blocks (8.2%), 0 events +2026-02-04T18:56:18.182166Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11010/133889 blocks (8.2%), 0 events +2026-02-04T18:56:18.404039Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11020/133889 blocks (8.2%), 0 events +2026-02-04T18:56:18.632844Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11030/133889 blocks (8.2%), 0 events +2026-02-04T18:56:18.815387Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11040/133889 blocks (8.2%), 0 events +2026-02-04T18:56:18.974461Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11050/133889 blocks (8.3%), 0 events +2026-02-04T18:56:19.228042Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11060/133889 blocks (8.3%), 0 events +2026-02-04T18:56:19.375004Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11070/133889 blocks (8.3%), 0 events +2026-02-04T18:56:19.680439Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11080/133889 blocks (8.3%), 0 events +2026-02-04T18:56:19.793503Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11090/133889 blocks (8.3%), 0 events +2026-02-04T18:56:19.971177Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11100/133889 blocks (8.3%), 0 events +2026-02-04T18:56:20.268381Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11110/133889 blocks (8.3%), 0 events +2026-02-04T18:56:20.418163Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11120/133889 blocks (8.3%), 0 events +2026-02-04T18:56:20.566420Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11130/133889 blocks (8.3%), 0 events +2026-02-04T18:56:20.780242Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11140/133889 blocks (8.3%), 0 events +2026-02-04T18:56:21.050739Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11150/133889 blocks (8.3%), 0 events +2026-02-04T18:56:21.256016Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11160/133889 blocks (8.3%), 0 events +2026-02-04T18:56:21.391943Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11170/133889 blocks (8.3%), 0 events +2026-02-04T18:56:21.607922Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11180/133889 blocks (8.3%), 0 events +2026-02-04T18:56:21.818806Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11190/133889 blocks (8.4%), 0 events +2026-02-04T18:56:22.047624Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11200/133889 blocks (8.4%), 0 events +2026-02-04T18:56:22.171662Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11210/133889 blocks (8.4%), 0 events +2026-02-04T18:56:22.418552Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11220/133889 blocks (8.4%), 0 events +2026-02-04T18:56:22.635503Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11230/133889 blocks (8.4%), 0 events +2026-02-04T18:56:22.843132Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11240/133889 blocks (8.4%), 0 events +2026-02-04T18:56:22.966408Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11250/133889 blocks (8.4%), 0 events +2026-02-04T18:56:23.317668Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11260/133889 blocks (8.4%), 0 events +2026-02-04T18:56:23.429328Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11270/133889 blocks (8.4%), 0 events +2026-02-04T18:56:23.660732Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11280/133889 blocks (8.4%), 0 events +2026-02-04T18:56:23.881857Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11290/133889 blocks (8.4%), 0 events +2026-02-04T18:56:24.040917Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11300/133889 blocks (8.4%), 0 events +2026-02-04T18:56:24.262005Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11310/133889 blocks (8.4%), 0 events +2026-02-04T18:56:24.398320Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11320/133889 blocks (8.5%), 0 events +2026-02-04T18:56:24.634691Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11330/133889 blocks (8.5%), 0 events +2026-02-04T18:56:24.921965Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11340/133889 blocks (8.5%), 0 events +2026-02-04T18:56:24.965537Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11350/133889 blocks (8.5%), 0 events +2026-02-04T18:56:25.175032Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11360/133889 blocks (8.5%), 0 events +2026-02-04T18:56:25.444823Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11370/133889 blocks (8.5%), 0 events +2026-02-04T18:56:25.661055Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11380/133889 blocks (8.5%), 0 events +2026-02-04T18:56:25.787086Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11390/133889 blocks (8.5%), 0 events +2026-02-04T18:56:26.036647Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11400/133889 blocks (8.5%), 0 events +2026-02-04T18:56:26.185124Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11410/133889 blocks (8.5%), 0 events +2026-02-04T18:56:26.496552Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11420/133889 blocks (8.5%), 0 events +2026-02-04T18:56:26.589597Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11430/133889 blocks (8.5%), 0 events +2026-02-04T18:56:26.831245Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11440/133889 blocks (8.5%), 0 events +2026-02-04T18:56:27.059354Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11450/133889 blocks (8.6%), 0 events +2026-02-04T18:56:27.209379Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11460/133889 blocks (8.6%), 0 events +2026-02-04T18:56:27.369632Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11470/133889 blocks (8.6%), 0 events +2026-02-04T18:56:27.605481Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11480/133889 blocks (8.6%), 0 events +2026-02-04T18:56:27.857778Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11490/133889 blocks (8.6%), 0 events +2026-02-04T18:56:28.035585Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11500/133889 blocks (8.6%), 0 events +2026-02-04T18:56:28.249047Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11510/133889 blocks (8.6%), 0 events +2026-02-04T18:56:28.431318Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11520/133889 blocks (8.6%), 0 events +2026-02-04T18:56:28.603714Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11530/133889 blocks (8.6%), 0 events +2026-02-04T18:56:28.803021Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11540/133889 blocks (8.6%), 0 events +2026-02-04T18:56:28.980652Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11550/133889 blocks (8.6%), 0 events +2026-02-04T18:56:29.174175Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11560/133889 blocks (8.6%), 0 events +2026-02-04T18:56:29.413276Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11570/133889 blocks (8.6%), 0 events +2026-02-04T18:56:29.644893Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11580/133889 blocks (8.6%), 0 events +2026-02-04T18:56:29.833861Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11590/133889 blocks (8.7%), 0 events +2026-02-04T18:56:30.035770Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11600/133889 blocks (8.7%), 0 events +2026-02-04T18:56:30.256678Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11610/133889 blocks (8.7%), 0 events +2026-02-04T18:56:30.441450Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11620/133889 blocks (8.7%), 0 events +2026-02-04T18:56:30.690751Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11630/133889 blocks (8.7%), 0 events +2026-02-04T18:56:30.797074Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11640/133889 blocks (8.7%), 0 events +2026-02-04T18:56:31.050023Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11650/133889 blocks (8.7%), 0 events +2026-02-04T18:56:31.218462Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11660/133889 blocks (8.7%), 0 events +2026-02-04T18:56:31.456649Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11670/133889 blocks (8.7%), 0 events +2026-02-04T18:56:31.706037Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11680/133889 blocks (8.7%), 0 events +2026-02-04T18:56:31.856993Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11690/133889 blocks (8.7%), 0 events +2026-02-04T18:56:32.035723Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11700/133889 blocks (8.7%), 0 events +2026-02-04T18:56:32.258335Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11710/133889 blocks (8.7%), 0 events +2026-02-04T18:56:32.367122Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11720/133889 blocks (8.8%), 0 events +2026-02-04T18:56:32.566300Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11730/133889 blocks (8.8%), 0 events +2026-02-04T18:56:32.805204Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11740/133889 blocks (8.8%), 0 events +2026-02-04T18:56:33.020982Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11750/133889 blocks (8.8%), 0 events +2026-02-04T18:56:33.277400Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11760/133889 blocks (8.8%), 0 events +2026-02-04T18:56:33.411805Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11770/133889 blocks (8.8%), 0 events +2026-02-04T18:56:33.610086Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11780/133889 blocks (8.8%), 0 events +2026-02-04T18:56:33.837216Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11790/133889 blocks (8.8%), 0 events +2026-02-04T18:56:33.987580Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11800/133889 blocks (8.8%), 0 events +2026-02-04T18:56:34.327066Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11810/133889 blocks (8.8%), 0 events +2026-02-04T18:56:34.369201Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11820/133889 blocks (8.8%), 0 events +2026-02-04T18:56:34.659310Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11830/133889 blocks (8.8%), 0 events +2026-02-04T18:56:34.884249Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11840/133889 blocks (8.8%), 0 events +2026-02-04T18:56:35.036631Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11850/133889 blocks (8.8%), 0 events +2026-02-04T18:56:35.203421Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11860/133889 blocks (8.9%), 0 events +2026-02-04T18:56:35.444544Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11870/133889 blocks (8.9%), 0 events +2026-02-04T18:56:35.599695Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11880/133889 blocks (8.9%), 0 events +2026-02-04T18:56:35.896974Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11890/133889 blocks (8.9%), 0 events +2026-02-04T18:56:36.003655Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11900/133889 blocks (8.9%), 0 events +2026-02-04T18:56:36.241335Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11910/133889 blocks (8.9%), 0 events +2026-02-04T18:56:36.458547Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11920/133889 blocks (8.9%), 0 events +2026-02-04T18:56:36.661500Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11930/133889 blocks (8.9%), 0 events +2026-02-04T18:56:36.789632Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11940/133889 blocks (8.9%), 0 events +2026-02-04T18:56:37.005561Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11950/133889 blocks (8.9%), 0 events +2026-02-04T18:56:37.227631Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11960/133889 blocks (8.9%), 0 events +2026-02-04T18:56:37.506064Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11970/133889 blocks (8.9%), 0 events +2026-02-04T18:56:37.624081Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11980/133889 blocks (8.9%), 0 events +2026-02-04T18:56:37.862330Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11990/133889 blocks (9.0%), 0 events +2026-02-04T18:56:38.039191Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12000/133889 blocks (9.0%), 0 events +2026-02-04T18:56:38.234139Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12010/133889 blocks (9.0%), 0 events +2026-02-04T18:56:38.402595Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12020/133889 blocks (9.0%), 0 events +2026-02-04T18:56:38.622995Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12030/133889 blocks (9.0%), 0 events +2026-02-04T18:56:38.829554Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12040/133889 blocks (9.0%), 0 events +2026-02-04T18:56:39.083961Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12050/133889 blocks (9.0%), 0 events +2026-02-04T18:56:39.209918Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12060/133889 blocks (9.0%), 0 events +2026-02-04T18:56:39.415183Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12070/133889 blocks (9.0%), 0 events +2026-02-04T18:56:39.602868Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12080/133889 blocks (9.0%), 0 events +2026-02-04T18:56:39.771789Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12090/133889 blocks (9.0%), 0 events +2026-02-04T18:56:39.987732Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12100/133889 blocks (9.0%), 0 events +2026-02-04T18:56:40.239339Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12110/133889 blocks (9.0%), 0 events +2026-02-04T18:56:40.404528Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12120/133889 blocks (9.1%), 0 events +2026-02-04T18:56:40.649741Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12130/133889 blocks (9.1%), 0 events +2026-02-04T18:56:40.831593Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12140/133889 blocks (9.1%), 0 events +2026-02-04T18:56:40.993602Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12150/133889 blocks (9.1%), 0 events +2026-02-04T18:56:41.177697Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12160/133889 blocks (9.1%), 0 events +2026-02-04T18:56:41.419725Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12170/133889 blocks (9.1%), 0 events +2026-02-04T18:56:41.700600Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12180/133889 blocks (9.1%), 0 events +2026-02-04T18:56:41.801291Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12190/133889 blocks (9.1%), 0 events +2026-02-04T18:56:41.967192Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12200/133889 blocks (9.1%), 0 events +2026-02-04T18:56:42.222942Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12210/133889 blocks (9.1%), 0 events +2026-02-04T18:56:42.443486Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12220/133889 blocks (9.1%), 0 events +2026-02-04T18:56:42.712150Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12230/133889 blocks (9.1%), 0 events +2026-02-04T18:56:42.999604Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12240/133889 blocks (9.1%), 0 events +2026-02-04T18:56:43.038589Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12250/133889 blocks (9.1%), 0 events +2026-02-04T18:56:43.269177Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12260/133889 blocks (9.2%), 0 events +2026-02-04T18:56:43.370302Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12270/133889 blocks (9.2%), 0 events +2026-02-04T18:56:43.622687Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12280/133889 blocks (9.2%), 0 events +2026-02-04T18:56:43.857807Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12290/133889 blocks (9.2%), 0 events +2026-02-04T18:56:43.981401Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12300/133889 blocks (9.2%), 0 events +2026-02-04T18:56:44.291285Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12310/133889 blocks (9.2%), 0 events +2026-02-04T18:56:44.369297Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12320/133889 blocks (9.2%), 0 events +2026-02-04T18:56:44.645873Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12330/133889 blocks (9.2%), 0 events +2026-02-04T18:56:44.844169Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12340/133889 blocks (9.2%), 0 events +2026-02-04T18:56:45.048844Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12350/133889 blocks (9.2%), 0 events +2026-02-04T18:56:45.231202Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12360/133889 blocks (9.2%), 0 events +2026-02-04T18:56:45.379104Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12370/133889 blocks (9.2%), 0 events +2026-02-04T18:56:45.634840Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12380/133889 blocks (9.2%), 0 events +2026-02-04T18:56:45.890586Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12390/133889 blocks (9.3%), 0 events +2026-02-04T18:56:45.991749Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12400/133889 blocks (9.3%), 0 events +2026-02-04T18:56:46.241214Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12410/133889 blocks (9.3%), 0 events +2026-02-04T18:56:46.458118Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12420/133889 blocks (9.3%), 0 events +2026-02-04T18:56:46.576672Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12430/133889 blocks (9.3%), 0 events +2026-02-04T18:56:46.798134Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12440/133889 blocks (9.3%), 0 events +2026-02-04T18:56:47.031394Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12450/133889 blocks (9.3%), 0 events +2026-02-04T18:56:47.222358Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12460/133889 blocks (9.3%), 0 events +2026-02-04T18:56:47.465201Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12470/133889 blocks (9.3%), 0 events +2026-02-04T18:56:47.620458Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12480/133889 blocks (9.3%), 0 events +2026-02-04T18:56:47.829018Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12490/133889 blocks (9.3%), 0 events +2026-02-04T18:56:48.048006Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12500/133889 blocks (9.3%), 0 events +2026-02-04T18:56:48.197315Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12510/133889 blocks (9.3%), 0 events +2026-02-04T18:56:48.480379Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12520/133889 blocks (9.4%), 0 events +2026-02-04T18:56:48.624141Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12530/133889 blocks (9.4%), 0 events +2026-02-04T18:56:48.774910Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12540/133889 blocks (9.4%), 0 events +2026-02-04T18:56:49.043332Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12550/133889 blocks (9.4%), 0 events +2026-02-04T18:56:49.207976Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12560/133889 blocks (9.4%), 0 events +2026-02-04T18:56:49.388076Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12570/133889 blocks (9.4%), 0 events +2026-02-04T18:56:49.638038Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12580/133889 blocks (9.4%), 0 events +2026-02-04T18:56:49.845089Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12590/133889 blocks (9.4%), 0 events +2026-02-04T18:56:50.054434Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12600/133889 blocks (9.4%), 0 events +2026-02-04T18:56:50.231669Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12610/133889 blocks (9.4%), 0 events +2026-02-04T18:56:50.484886Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12620/133889 blocks (9.4%), 0 events +2026-02-04T18:56:50.627438Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12630/133889 blocks (9.4%), 0 events +2026-02-04T18:56:50.824313Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12640/133889 blocks (9.4%), 0 events +2026-02-04T18:56:51.140859Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12650/133889 blocks (9.4%), 0 events +2026-02-04T18:56:51.179333Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12660/133889 blocks (9.5%), 0 events +2026-02-04T18:56:51.406195Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12670/133889 blocks (9.5%), 0 events +2026-02-04T18:56:51.626001Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12680/133889 blocks (9.5%), 0 events +2026-02-04T18:56:51.782086Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12690/133889 blocks (9.5%), 0 events +2026-02-04T18:56:52.000722Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12700/133889 blocks (9.5%), 0 events +2026-02-04T18:56:52.184389Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12710/133889 blocks (9.5%), 0 events +2026-02-04T18:56:52.456848Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12720/133889 blocks (9.5%), 0 events +2026-02-04T18:56:52.673207Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12730/133889 blocks (9.5%), 0 events +2026-02-04T18:56:52.831282Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12740/133889 blocks (9.5%), 0 events +2026-02-04T18:56:53.003686Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12750/133889 blocks (9.5%), 0 events +2026-02-04T18:56:53.230514Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12760/133889 blocks (9.5%), 0 events +2026-02-04T18:56:53.377421Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12770/133889 blocks (9.5%), 0 events +2026-02-04T18:56:53.604953Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12780/133889 blocks (9.5%), 0 events +2026-02-04T18:56:53.836618Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12790/133889 blocks (9.6%), 0 events +2026-02-04T18:56:54.001752Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12800/133889 blocks (9.6%), 0 events +2026-02-04T18:56:54.284405Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12810/133889 blocks (9.6%), 0 events +2026-02-04T18:56:54.455697Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12820/133889 blocks (9.6%), 0 events +2026-02-04T18:56:54.638203Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12830/133889 blocks (9.6%), 0 events +2026-02-04T18:56:54.805441Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12840/133889 blocks (9.6%), 0 events +2026-02-04T18:56:55.028081Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12850/133889 blocks (9.6%), 0 events +2026-02-04T18:56:55.329435Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12860/133889 blocks (9.6%), 0 events +2026-02-04T18:56:55.368125Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12870/133889 blocks (9.6%), 0 events +2026-02-04T18:56:55.596664Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12880/133889 blocks (9.6%), 0 events +2026-02-04T18:56:55.819407Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12890/133889 blocks (9.6%), 0 events +2026-02-04T18:56:56.059189Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12900/133889 blocks (9.6%), 0 events +2026-02-04T18:56:56.184787Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12910/133889 blocks (9.6%), 0 events +2026-02-04T18:56:56.382176Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12920/133889 blocks (9.6%), 0 events +2026-02-04T18:56:56.615885Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12930/133889 blocks (9.7%), 0 events +2026-02-04T18:56:56.901124Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12940/133889 blocks (9.7%), 0 events +2026-02-04T18:56:56.993462Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12950/133889 blocks (9.7%), 0 events +2026-02-04T18:56:57.185357Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12960/133889 blocks (9.7%), 0 events +2026-02-04T18:56:57.424577Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12970/133889 blocks (9.7%), 0 events +2026-02-04T18:56:57.588619Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12980/133889 blocks (9.7%), 0 events +2026-02-04T18:56:57.814316Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12990/133889 blocks (9.7%), 0 events +2026-02-04T18:56:57.992621Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13000/133889 blocks (9.7%), 0 events +2026-02-04T18:56:58.230830Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13010/133889 blocks (9.7%), 0 events +2026-02-04T18:56:58.472552Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13020/133889 blocks (9.7%), 0 events +2026-02-04T18:56:58.608006Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13030/133889 blocks (9.7%), 0 events +2026-02-04T18:56:58.849474Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13040/133889 blocks (9.7%), 0 events +2026-02-04T18:56:59.000753Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13050/133889 blocks (9.7%), 0 events +2026-02-04T18:56:59.234403Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13060/133889 blocks (9.8%), 0 events +2026-02-04T18:56:59.383765Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13070/133889 blocks (9.8%), 0 events +2026-02-04T18:56:59.653411Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13080/133889 blocks (9.8%), 0 events +2026-02-04T18:56:59.830915Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13090/133889 blocks (9.8%), 0 events +2026-02-04T18:57:00.047980Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13100/133889 blocks (9.8%), 0 events +2026-02-04T18:57:00.197276Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13110/133889 blocks (9.8%), 0 events +2026-02-04T18:57:00.430279Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13120/133889 blocks (9.8%), 0 events +2026-02-04T18:57:00.591885Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13130/133889 blocks (9.8%), 0 events +2026-02-04T18:57:00.769551Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13140/133889 blocks (9.8%), 0 events +2026-02-04T18:57:01.115440Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13150/133889 blocks (9.8%), 0 events +2026-02-04T18:57:01.229635Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13160/133889 blocks (9.8%), 0 events +2026-02-04T18:57:01.440722Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13170/133889 blocks (9.8%), 0 events +2026-02-04T18:57:01.631677Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13180/133889 blocks (9.8%), 0 events +2026-02-04T18:57:01.791580Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13190/133889 blocks (9.9%), 0 events +2026-02-04T18:57:02.110013Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13200/133889 blocks (9.9%), 0 events +2026-02-04T18:57:02.233098Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13210/133889 blocks (9.9%), 0 events +2026-02-04T18:57:02.378811Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13220/133889 blocks (9.9%), 0 events +2026-02-04T18:57:02.668053Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13230/133889 blocks (9.9%), 0 events +2026-02-04T18:57:02.780013Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13240/133889 blocks (9.9%), 0 events +2026-02-04T18:57:02.996431Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13250/133889 blocks (9.9%), 0 events +2026-02-04T18:57:03.194174Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13260/133889 blocks (9.9%), 0 events +2026-02-04T18:57:03.405596Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13270/133889 blocks (9.9%), 0 events +2026-02-04T18:57:03.685046Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13280/133889 blocks (9.9%), 0 events +2026-02-04T18:57:03.766813Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13290/133889 blocks (9.9%), 0 events +2026-02-04T18:57:04.001646Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13300/133889 blocks (9.9%), 0 events +2026-02-04T18:57:04.243195Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13310/133889 blocks (9.9%), 0 events +2026-02-04T18:57:04.415948Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13320/133889 blocks (9.9%), 0 events +2026-02-04T18:57:04.614603Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13330/133889 blocks (10.0%), 0 events +2026-02-04T18:57:04.826029Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13340/133889 blocks (10.0%), 0 events +2026-02-04T18:57:05.060274Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13350/133889 blocks (10.0%), 0 events +2026-02-04T18:57:05.293912Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13360/133889 blocks (10.0%), 0 events +2026-02-04T18:57:05.364575Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13370/133889 blocks (10.0%), 0 events +2026-02-04T18:57:05.589810Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13380/133889 blocks (10.0%), 0 events +2026-02-04T18:57:05.832730Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13390/133889 blocks (10.0%), 0 events +2026-02-04T18:57:06.016974Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13400/133889 blocks (10.0%), 0 events +2026-02-04T18:57:06.335693Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13410/133889 blocks (10.0%), 0 events +2026-02-04T18:57:06.379832Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13420/133889 blocks (10.0%), 0 events +2026-02-04T18:57:06.584537Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13430/133889 blocks (10.0%), 0 events +2026-02-04T18:57:06.867920Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13440/133889 blocks (10.0%), 0 events +2026-02-04T18:57:06.998971Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13450/133889 blocks (10.0%), 0 events +2026-02-04T18:57:07.270217Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13460/133889 blocks (10.1%), 0 events +2026-02-04T18:57:07.416836Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13470/133889 blocks (10.1%), 0 events +2026-02-04T18:57:07.578336Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13480/133889 blocks (10.1%), 0 events +2026-02-04T18:57:07.913392Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13490/133889 blocks (10.1%), 0 events +2026-02-04T18:57:08.050337Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13500/133889 blocks (10.1%), 0 events +2026-02-04T18:57:08.196485Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13510/133889 blocks (10.1%), 0 events +2026-02-04T18:57:08.431499Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13520/133889 blocks (10.1%), 0 events +2026-02-04T18:57:08.589000Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13530/133889 blocks (10.1%), 0 events +2026-02-04T18:57:08.816239Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13540/133889 blocks (10.1%), 0 events +2026-02-04T18:57:09.057839Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13550/133889 blocks (10.1%), 0 events +2026-02-04T18:57:09.205345Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13560/133889 blocks (10.1%), 0 events +2026-02-04T18:57:09.451547Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13570/133889 blocks (10.1%), 0 events +2026-02-04T18:57:09.656979Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13580/133889 blocks (10.1%), 0 events +2026-02-04T18:57:09.818237Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13590/133889 blocks (10.1%), 0 events +2026-02-04T18:57:10.030882Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13600/133889 blocks (10.2%), 0 events +2026-02-04T18:57:10.171838Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13610/133889 blocks (10.2%), 0 events +2026-02-04T18:57:10.517249Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13620/133889 blocks (10.2%), 0 events +2026-02-04T18:57:10.658183Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13630/133889 blocks (10.2%), 0 events +2026-02-04T18:57:10.861918Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13640/133889 blocks (10.2%), 0 events +2026-02-04T18:57:11.055718Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13650/133889 blocks (10.2%), 0 events +2026-02-04T18:57:11.172218Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13660/133889 blocks (10.2%), 0 events +2026-02-04T18:57:11.437578Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13670/133889 blocks (10.2%), 0 events +2026-02-04T18:57:11.609741Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13680/133889 blocks (10.2%), 0 events +2026-02-04T18:57:11.839956Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13690/133889 blocks (10.2%), 0 events +2026-02-04T18:57:12.105313Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13700/133889 blocks (10.2%), 0 events +2026-02-04T18:57:12.239588Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13710/133889 blocks (10.2%), 0 events +2026-02-04T18:57:12.413653Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13720/133889 blocks (10.2%), 0 events +2026-02-04T18:57:12.650549Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13730/133889 blocks (10.3%), 0 events +2026-02-04T18:57:12.782062Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13740/133889 blocks (10.3%), 0 events +2026-02-04T18:57:13.028059Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13750/133889 blocks (10.3%), 0 events +2026-02-04T18:57:13.271350Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13760/133889 blocks (10.3%), 0 events +2026-02-04T18:57:13.402089Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13770/133889 blocks (10.3%), 0 events +2026-02-04T18:57:13.645922Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13780/133889 blocks (10.3%), 0 events +2026-02-04T18:57:13.785923Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13790/133889 blocks (10.3%), 0 events +2026-02-04T18:57:13.974683Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13800/133889 blocks (10.3%), 0 events +2026-02-04T18:57:14.232985Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13810/133889 blocks (10.3%), 0 events +2026-02-04T18:57:14.451761Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13820/133889 blocks (10.3%), 0 events +2026-02-04T18:57:14.594504Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13830/133889 blocks (10.3%), 0 events +2026-02-04T18:57:14.834328Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13840/133889 blocks (10.3%), 0 events +2026-02-04T18:57:15.043086Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13850/133889 blocks (10.3%), 0 events +2026-02-04T18:57:15.274035Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13860/133889 blocks (10.4%), 0 events +2026-02-04T18:57:15.459305Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13870/133889 blocks (10.4%), 0 events +2026-02-04T18:57:15.628732Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13880/133889 blocks (10.4%), 0 events +2026-02-04T18:57:15.852955Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13890/133889 blocks (10.4%), 0 events +2026-02-04T18:57:15.996572Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13900/133889 blocks (10.4%), 0 events +2026-02-04T18:57:16.302242Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13910/133889 blocks (10.4%), 0 events +2026-02-04T18:57:16.442230Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13920/133889 blocks (10.4%), 0 events +2026-02-04T18:57:16.592753Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13930/133889 blocks (10.4%), 0 events +2026-02-04T18:57:16.834860Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13940/133889 blocks (10.4%), 0 events +2026-02-04T18:57:17.029286Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13950/133889 blocks (10.4%), 0 events +2026-02-04T18:57:17.197421Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13960/133889 blocks (10.4%), 0 events +2026-02-04T18:57:17.445905Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13970/133889 blocks (10.4%), 0 events +2026-02-04T18:57:17.647077Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13980/133889 blocks (10.4%), 0 events +2026-02-04T18:57:17.871432Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13990/133889 blocks (10.4%), 0 events +2026-02-04T18:57:17.980665Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14000/133889 blocks (10.5%), 0 events +2026-02-04T18:57:18.181003Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14010/133889 blocks (10.5%), 0 events +2026-02-04T18:57:18.424557Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14020/133889 blocks (10.5%), 0 events +2026-02-04T18:57:18.659156Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14030/133889 blocks (10.5%), 0 events +2026-02-04T18:57:18.772184Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14040/133889 blocks (10.5%), 0 events +2026-02-04T18:57:18.982220Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14050/133889 blocks (10.5%), 0 events +2026-02-04T18:57:19.244143Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14060/133889 blocks (10.5%), 0 events +2026-02-04T18:57:19.452392Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14070/133889 blocks (10.5%), 0 events +2026-02-04T18:57:19.614430Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14080/133889 blocks (10.5%), 0 events +2026-02-04T18:57:19.828874Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14090/133889 blocks (10.5%), 0 events +2026-02-04T18:57:20.006048Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14100/133889 blocks (10.5%), 0 events +2026-02-04T18:57:20.186258Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14110/133889 blocks (10.5%), 0 events +2026-02-04T18:57:20.496442Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14120/133889 blocks (10.5%), 0 events +2026-02-04T18:57:20.597250Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14130/133889 blocks (10.6%), 0 events +2026-02-04T18:57:20.787577Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14140/133889 blocks (10.6%), 0 events +2026-02-04T18:57:21.023148Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14150/133889 blocks (10.6%), 0 events +2026-02-04T18:57:21.254110Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14160/133889 blocks (10.6%), 0 events +2026-02-04T18:57:21.390572Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14170/133889 blocks (10.6%), 0 events +2026-02-04T18:57:21.592128Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14180/133889 blocks (10.6%), 0 events +2026-02-04T18:57:21.810884Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14190/133889 blocks (10.6%), 0 events +2026-02-04T18:57:22.065990Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14200/133889 blocks (10.6%), 0 events +2026-02-04T18:57:22.166476Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14210/133889 blocks (10.6%), 0 events +2026-02-04T18:57:22.462922Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14220/133889 blocks (10.6%), 0 events +2026-02-04T18:57:22.634262Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14230/133889 blocks (10.6%), 0 events +2026-02-04T18:57:22.784377Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14240/133889 blocks (10.6%), 0 events +2026-02-04T18:57:23.112925Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14250/133889 blocks (10.6%), 0 events +2026-02-04T18:57:23.220074Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14260/133889 blocks (10.6%), 0 events +2026-02-04T18:57:23.422910Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14270/133889 blocks (10.7%), 0 events +2026-02-04T18:57:23.644715Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14280/133889 blocks (10.7%), 0 events +2026-02-04T18:57:23.809610Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14290/133889 blocks (10.7%), 0 events +2026-02-04T18:57:24.132556Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14300/133889 blocks (10.7%), 0 events +2026-02-04T18:57:24.173772Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14310/133889 blocks (10.7%), 0 events +2026-02-04T18:57:24.429825Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14320/133889 blocks (10.7%), 0 events +2026-02-04T18:57:24.687594Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14330/133889 blocks (10.7%), 0 events +2026-02-04T18:57:24.801929Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14340/133889 blocks (10.7%), 0 events +2026-02-04T18:57:25.002524Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14350/133889 blocks (10.7%), 0 events +2026-02-04T18:57:25.217960Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14360/133889 blocks (10.7%), 0 events +2026-02-04T18:57:25.430579Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14370/133889 blocks (10.7%), 0 events +2026-02-04T18:57:25.735994Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14380/133889 blocks (10.7%), 0 events +2026-02-04T18:57:25.775783Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14390/133889 blocks (10.7%), 0 events +2026-02-04T18:57:26.056824Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14400/133889 blocks (10.8%), 0 events +2026-02-04T18:57:26.263241Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14410/133889 blocks (10.8%), 0 events +2026-02-04T18:57:26.450914Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14420/133889 blocks (10.8%), 0 events +2026-02-04T18:57:26.624066Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14430/133889 blocks (10.8%), 0 events +2026-02-04T18:57:26.839222Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14440/133889 blocks (10.8%), 0 events +2026-02-04T18:57:27.040872Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14450/133889 blocks (10.8%), 0 events +2026-02-04T18:57:27.317840Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14460/133889 blocks (10.8%), 0 events +2026-02-04T18:57:27.460035Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14470/133889 blocks (10.8%), 0 events +2026-02-04T18:57:27.570090Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14480/133889 blocks (10.8%), 0 events +2026-02-04T18:57:27.844682Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14490/133889 blocks (10.8%), 0 events +2026-02-04T18:57:28.024369Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14500/133889 blocks (10.8%), 0 events +2026-02-04T18:57:28.181655Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14510/133889 blocks (10.8%), 0 events +2026-02-04T18:57:28.428090Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14520/133889 blocks (10.8%), 0 events +2026-02-04T18:57:28.663060Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14530/133889 blocks (10.9%), 0 events +2026-02-04T18:57:28.886787Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14540/133889 blocks (10.9%), 0 events +2026-02-04T18:57:29.059383Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14550/133889 blocks (10.9%), 0 events +2026-02-04T18:57:29.207460Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14560/133889 blocks (10.9%), 0 events +2026-02-04T18:57:29.409948Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14570/133889 blocks (10.9%), 0 events +2026-02-04T18:57:29.582369Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14580/133889 blocks (10.9%), 0 events +2026-02-04T18:57:29.898759Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14590/133889 blocks (10.9%), 0 events +2026-02-04T18:57:30.004680Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14600/133889 blocks (10.9%), 0 events +2026-02-04T18:57:30.247394Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14610/133889 blocks (10.9%), 0 events +2026-02-04T18:57:30.453512Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14620/133889 blocks (10.9%), 0 events +2026-02-04T18:57:30.576610Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14630/133889 blocks (10.9%), 0 events +2026-02-04T18:57:30.805164Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14640/133889 blocks (10.9%), 0 events +2026-02-04T18:57:31.004197Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14650/133889 blocks (10.9%), 0 events +2026-02-04T18:57:31.174624Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14660/133889 blocks (10.9%), 0 events +2026-02-04T18:57:31.516521Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14670/133889 blocks (11.0%), 0 events +2026-02-04T18:57:31.653432Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14680/133889 blocks (11.0%), 0 events +2026-02-04T18:57:31.858730Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14690/133889 blocks (11.0%), 0 events +2026-02-04T18:57:32.042263Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14700/133889 blocks (11.0%), 0 events +2026-02-04T18:57:32.238658Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14710/133889 blocks (11.0%), 0 events +2026-02-04T18:57:32.405705Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14720/133889 blocks (11.0%), 0 events +2026-02-04T18:57:32.656826Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14730/133889 blocks (11.0%), 0 events +2026-02-04T18:57:32.800754Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14740/133889 blocks (11.0%), 0 events +2026-02-04T18:57:33.044466Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14750/133889 blocks (11.0%), 0 events +2026-02-04T18:57:33.202983Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14760/133889 blocks (11.0%), 0 events +2026-02-04T18:57:33.465586Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14770/133889 blocks (11.0%), 0 events +2026-02-04T18:57:33.664779Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14780/133889 blocks (11.0%), 0 events +2026-02-04T18:57:33.823409Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14790/133889 blocks (11.0%), 0 events +2026-02-04T18:57:34.093104Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14800/133889 blocks (11.1%), 0 events +2026-02-04T18:57:34.169162Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14810/133889 blocks (11.1%), 0 events +2026-02-04T18:57:34.381193Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14820/133889 blocks (11.1%), 0 events +2026-02-04T18:57:34.663999Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14830/133889 blocks (11.1%), 0 events +2026-02-04T18:57:34.786014Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14840/133889 blocks (11.1%), 0 events +2026-02-04T18:57:34.974747Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14850/133889 blocks (11.1%), 0 events +2026-02-04T18:57:35.241060Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14860/133889 blocks (11.1%), 0 events +2026-02-04T18:57:35.377783Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14870/133889 blocks (11.1%), 0 events +2026-02-04T18:57:35.666066Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14880/133889 blocks (11.1%), 0 events +2026-02-04T18:57:35.831202Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14890/133889 blocks (11.1%), 0 events +2026-02-04T18:57:35.974404Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14900/133889 blocks (11.1%), 0 events +2026-02-04T18:57:36.237082Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14910/133889 blocks (11.1%), 0 events +2026-02-04T18:57:36.440708Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14920/133889 blocks (11.1%), 0 events +2026-02-04T18:57:36.714555Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14930/133889 blocks (11.2%), 0 events +2026-02-04T18:57:36.802951Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14940/133889 blocks (11.2%), 0 events +2026-02-04T18:57:37.036392Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14950/133889 blocks (11.2%), 0 events +2026-02-04T18:57:37.270936Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14960/133889 blocks (11.2%), 0 events +2026-02-04T18:57:37.447439Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14970/133889 blocks (11.2%), 0 events +2026-02-04T18:57:37.613532Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14980/133889 blocks (11.2%), 0 events +2026-02-04T18:57:37.863159Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14990/133889 blocks (11.2%), 0 events +2026-02-04T18:57:37.989856Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15000/133889 blocks (11.2%), 0 events +2026-02-04T18:57:38.284580Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15010/133889 blocks (11.2%), 0 events +2026-02-04T18:57:38.419092Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15020/133889 blocks (11.2%), 0 events +2026-02-04T18:57:38.586083Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15030/133889 blocks (11.2%), 0 events +2026-02-04T18:57:38.848713Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15040/133889 blocks (11.2%), 0 events +2026-02-04T18:57:39.004670Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15050/133889 blocks (11.2%), 0 events +2026-02-04T18:57:39.229179Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15060/133889 blocks (11.2%), 0 events +2026-02-04T18:57:39.442046Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15070/133889 blocks (11.3%), 0 events +2026-02-04T18:57:39.612603Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15080/133889 blocks (11.3%), 0 events +2026-02-04T18:57:39.896984Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15090/133889 blocks (11.3%), 0 events +2026-02-04T18:57:40.020107Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15100/133889 blocks (11.3%), 0 events +2026-02-04T18:57:40.252339Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15110/133889 blocks (11.3%), 0 events +2026-02-04T18:57:40.418419Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15120/133889 blocks (11.3%), 0 events +2026-02-04T18:57:40.571959Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15130/133889 blocks (11.3%), 0 events +2026-02-04T18:57:40.785552Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15140/133889 blocks (11.3%), 0 events +2026-02-04T18:57:40.978440Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15150/133889 blocks (11.3%), 0 events +2026-02-04T18:57:41.233778Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15160/133889 blocks (11.3%), 0 events +2026-02-04T18:57:41.471792Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15170/133889 blocks (11.3%), 0 events +2026-02-04T18:57:41.639750Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15180/133889 blocks (11.3%), 0 events +2026-02-04T18:57:41.788580Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15190/133889 blocks (11.3%), 0 events +2026-02-04T18:57:42.032577Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15200/133889 blocks (11.4%), 0 events +2026-02-04T18:57:42.247092Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15210/133889 blocks (11.4%), 0 events +2026-02-04T18:57:42.481419Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15220/133889 blocks (11.4%), 0 events +2026-02-04T18:57:42.561395Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15230/133889 blocks (11.4%), 0 events +2026-02-04T18:57:42.865698Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15240/133889 blocks (11.4%), 0 events +2026-02-04T18:57:43.039315Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15250/133889 blocks (11.4%), 0 events +2026-02-04T18:57:43.218401Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15260/133889 blocks (11.4%), 0 events +2026-02-04T18:57:43.387505Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15270/133889 blocks (11.4%), 0 events +2026-02-04T18:57:43.574062Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15280/133889 blocks (11.4%), 0 events +2026-02-04T18:57:43.807496Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15290/133889 blocks (11.4%), 0 events +2026-02-04T18:57:44.054935Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15300/133889 blocks (11.4%), 0 events +2026-02-04T18:57:44.233973Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15310/133889 blocks (11.4%), 0 events +2026-02-04T18:57:44.439952Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15320/133889 blocks (11.4%), 0 events +2026-02-04T18:57:44.619113Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15330/133889 blocks (11.4%), 0 events +2026-02-04T18:57:44.828530Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15340/133889 blocks (11.5%), 0 events +2026-02-04T18:57:45.131501Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15350/133889 blocks (11.5%), 0 events +2026-02-04T18:57:45.167876Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15360/133889 blocks (11.5%), 0 events +2026-02-04T18:57:45.446370Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15370/133889 blocks (11.5%), 0 events +2026-02-04T18:57:45.658734Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15380/133889 blocks (11.5%), 0 events +2026-02-04T18:57:45.763933Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15390/133889 blocks (11.5%), 0 events +2026-02-04T18:57:46.020119Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15400/133889 blocks (11.5%), 0 events +2026-02-04T18:57:46.243376Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15410/133889 blocks (11.5%), 0 events +2026-02-04T18:57:46.388194Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15420/133889 blocks (11.5%), 0 events +2026-02-04T18:57:46.704068Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15430/133889 blocks (11.5%), 0 events +2026-02-04T18:57:46.785860Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15440/133889 blocks (11.5%), 0 events +2026-02-04T18:57:47.015901Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15450/133889 blocks (11.5%), 0 events +2026-02-04T18:57:47.235774Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15460/133889 blocks (11.5%), 0 events +2026-02-04T18:57:47.412393Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15470/133889 blocks (11.6%), 0 events +2026-02-04T18:57:47.591673Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15480/133889 blocks (11.6%), 0 events +2026-02-04T18:57:47.808443Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15490/133889 blocks (11.6%), 0 events +2026-02-04T18:57:47.998811Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15500/133889 blocks (11.6%), 0 events +2026-02-04T18:57:48.245751Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15510/133889 blocks (11.6%), 0 events +2026-02-04T18:57:48.383439Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15520/133889 blocks (11.6%), 0 events +2026-02-04T18:57:48.583446Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15530/133889 blocks (11.6%), 0 events +2026-02-04T18:57:48.830084Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15540/133889 blocks (11.6%), 0 events +2026-02-04T18:57:48.985570Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15550/133889 blocks (11.6%), 0 events +2026-02-04T18:57:49.332374Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15560/133889 blocks (11.6%), 0 events +2026-02-04T18:57:49.375622Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15570/133889 blocks (11.6%), 0 events +2026-02-04T18:57:49.615919Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15580/133889 blocks (11.6%), 0 events +2026-02-04T18:57:49.866252Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15590/133889 blocks (11.6%), 0 events +2026-02-04T18:57:49.997673Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15600/133889 blocks (11.7%), 0 events +2026-02-04T18:57:50.181004Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15610/133889 blocks (11.7%), 0 events +2026-02-04T18:57:50.447197Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15620/133889 blocks (11.7%), 0 events +2026-02-04T18:57:50.627452Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15630/133889 blocks (11.7%), 0 events +2026-02-04T18:57:50.776750Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15640/133889 blocks (11.7%), 0 events +2026-02-04T18:57:50.977626Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15650/133889 blocks (11.7%), 0 events +2026-02-04T18:57:51.196694Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15660/133889 blocks (11.7%), 0 events +2026-02-04T18:57:51.438564Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15670/133889 blocks (11.7%), 0 events +2026-02-04T18:57:51.608112Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15680/133889 blocks (11.7%), 0 events +2026-02-04T18:57:51.917971Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15690/133889 blocks (11.7%), 0 events +2026-02-04T18:57:52.032127Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15700/133889 blocks (11.7%), 0 events +2026-02-04T18:57:52.242213Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15710/133889 blocks (11.7%), 0 events +2026-02-04T18:57:52.443729Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15720/133889 blocks (11.7%), 0 events +2026-02-04T18:57:52.586743Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15730/133889 blocks (11.7%), 0 events +2026-02-04T18:57:52.837389Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15740/133889 blocks (11.8%), 0 events +2026-02-04T18:57:52.998917Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15750/133889 blocks (11.8%), 0 events +2026-02-04T18:57:53.201086Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15760/133889 blocks (11.8%), 0 events +2026-02-04T18:57:53.382019Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15770/133889 blocks (11.8%), 0 events +2026-02-04T18:57:53.571046Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15780/133889 blocks (11.8%), 0 events +2026-02-04T18:57:53.789848Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15790/133889 blocks (11.8%), 0 events +2026-02-04T18:57:54.046429Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15800/133889 blocks (11.8%), 0 events +2026-02-04T18:57:54.232252Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15810/133889 blocks (11.8%), 0 events +2026-02-04T18:57:54.439379Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15820/133889 blocks (11.8%), 0 events +2026-02-04T18:57:54.628337Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15830/133889 blocks (11.8%), 0 events +2026-02-04T18:57:54.834280Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15840/133889 blocks (11.8%), 0 events +2026-02-04T18:57:55.063072Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15850/133889 blocks (11.8%), 0 events +2026-02-04T18:57:55.242716Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15860/133889 blocks (11.8%), 0 events +2026-02-04T18:57:55.369158Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15870/133889 blocks (11.9%), 0 events +2026-02-04T18:57:55.646076Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15880/133889 blocks (11.9%), 0 events +2026-02-04T18:57:55.811941Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15890/133889 blocks (11.9%), 0 events +2026-02-04T18:57:56.113207Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15900/133889 blocks (11.9%), 0 events +2026-02-04T18:57:56.252860Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15910/133889 blocks (11.9%), 0 events +2026-02-04T18:57:56.442251Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15920/133889 blocks (11.9%), 0 events +2026-02-04T18:57:56.672657Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15930/133889 blocks (11.9%), 0 events +2026-02-04T18:57:56.845539Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15940/133889 blocks (11.9%), 0 events +2026-02-04T18:57:56.966713Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15950/133889 blocks (11.9%), 0 events +2026-02-04T18:57:57.213427Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15960/133889 blocks (11.9%), 0 events +2026-02-04T18:57:57.444261Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15970/133889 blocks (11.9%), 0 events +2026-02-04T18:57:57.685561Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15980/133889 blocks (11.9%), 0 events +2026-02-04T18:57:57.782024Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15990/133889 blocks (11.9%), 0 events +2026-02-04T18:57:57.981271Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16000/133889 blocks (11.9%), 0 events +2026-02-04T18:57:58.241265Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16010/133889 blocks (12.0%), 0 events +2026-02-04T18:57:58.423018Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16020/133889 blocks (12.0%), 0 events +2026-02-04T18:57:58.733225Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16030/133889 blocks (12.0%), 0 events +2026-02-04T18:57:58.774132Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16040/133889 blocks (12.0%), 0 events +2026-02-04T18:57:59.012162Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16050/133889 blocks (12.0%), 0 events +2026-02-04T18:57:59.299352Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16060/133889 blocks (12.0%), 0 events +2026-02-04T18:57:59.401733Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16070/133889 blocks (12.0%), 0 events +2026-02-04T18:57:59.648398Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16080/133889 blocks (12.0%), 0 events +2026-02-04T18:57:59.844923Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16090/133889 blocks (12.0%), 0 events +2026-02-04T18:57:59.989825Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16100/133889 blocks (12.0%), 0 events +2026-02-04T18:58:00.342046Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16110/133889 blocks (12.0%), 0 events +2026-02-04T18:58:00.384953Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16120/133889 blocks (12.0%), 0 events +2026-02-04T18:58:00.614952Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16130/133889 blocks (12.0%), 0 events +2026-02-04T18:58:00.862139Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16140/133889 blocks (12.1%), 0 events +2026-02-04T18:58:01.000896Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16150/133889 blocks (12.1%), 0 events +2026-02-04T18:58:01.215954Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16160/133889 blocks (12.1%), 0 events +2026-02-04T18:58:01.387056Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16170/133889 blocks (12.1%), 0 events +2026-02-04T18:58:01.666376Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16180/133889 blocks (12.1%), 0 events +2026-02-04T18:58:01.769747Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16190/133889 blocks (12.1%), 0 events +2026-02-04T18:58:01.999570Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16200/133889 blocks (12.1%), 0 events +2026-02-04T18:58:02.211047Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16210/133889 blocks (12.1%), 0 events +2026-02-04T18:58:02.441883Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16220/133889 blocks (12.1%), 0 events +2026-02-04T18:58:02.581124Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16230/133889 blocks (12.1%), 0 events +2026-02-04T18:58:02.803626Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16240/133889 blocks (12.1%), 0 events +2026-02-04T18:58:03.035162Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16250/133889 blocks (12.1%), 0 events +2026-02-04T18:58:03.192955Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16260/133889 blocks (12.1%), 0 events +2026-02-04T18:58:03.490918Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16270/133889 blocks (12.2%), 0 events +2026-02-04T18:58:03.582699Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16280/133889 blocks (12.2%), 0 events +2026-02-04T18:58:03.804000Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16290/133889 blocks (12.2%), 0 events +2026-02-04T18:58:04.063946Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16300/133889 blocks (12.2%), 0 events +2026-02-04T18:58:04.200556Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16310/133889 blocks (12.2%), 0 events +2026-02-04T18:58:04.543472Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16320/133889 blocks (12.2%), 0 events +2026-02-04T18:58:04.598291Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16330/133889 blocks (12.2%), 0 events +2026-02-04T18:58:04.807552Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16340/133889 blocks (12.2%), 0 events +2026-02-04T18:58:05.059849Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16350/133889 blocks (12.2%), 0 events +2026-02-04T18:58:05.225447Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16360/133889 blocks (12.2%), 0 events +2026-02-04T18:58:05.382607Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16370/133889 blocks (12.2%), 0 events +2026-02-04T18:58:05.651763Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16380/133889 blocks (12.2%), 0 events +2026-02-04T18:58:05.814034Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16390/133889 blocks (12.2%), 0 events +2026-02-04T18:58:06.109434Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16400/133889 blocks (12.2%), 0 events +2026-02-04T18:58:06.204257Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16410/133889 blocks (12.3%), 0 events +2026-02-04T18:58:06.387183Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16420/133889 blocks (12.3%), 0 events +2026-02-04T18:58:06.632592Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16430/133889 blocks (12.3%), 0 events +2026-02-04T18:58:06.798972Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16440/133889 blocks (12.3%), 0 events +2026-02-04T18:58:06.996612Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16450/133889 blocks (12.3%), 0 events +2026-02-04T18:58:07.189322Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16460/133889 blocks (12.3%), 0 events +2026-02-04T18:58:07.419172Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16470/133889 blocks (12.3%), 0 events +2026-02-04T18:58:07.682900Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16480/133889 blocks (12.3%), 0 events +2026-02-04T18:58:07.778685Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16490/133889 blocks (12.3%), 0 events +2026-02-04T18:58:07.993244Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16500/133889 blocks (12.3%), 0 events +2026-02-04T18:58:08.218074Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16510/133889 blocks (12.3%), 0 events +2026-02-04T18:58:08.365263Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16520/133889 blocks (12.3%), 0 events +2026-02-04T18:58:08.693792Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16530/133889 blocks (12.3%), 0 events +2026-02-04T18:58:08.820252Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16540/133889 blocks (12.4%), 0 events +2026-02-04T18:58:09.043362Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16550/133889 blocks (12.4%), 0 events +2026-02-04T18:58:09.255338Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16560/133889 blocks (12.4%), 0 events +2026-02-04T18:58:09.428690Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16570/133889 blocks (12.4%), 0 events +2026-02-04T18:58:09.627407Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16580/133889 blocks (12.4%), 0 events +2026-02-04T18:58:09.788219Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16590/133889 blocks (12.4%), 0 events +2026-02-04T18:58:10.066317Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16600/133889 blocks (12.4%), 0 events +2026-02-04T18:58:10.300440Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16610/133889 blocks (12.4%), 0 events +2026-02-04T18:58:10.396647Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16620/133889 blocks (12.4%), 0 events +2026-02-04T18:58:10.564761Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16630/133889 blocks (12.4%), 0 events +2026-02-04T18:58:10.864654Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16640/133889 blocks (12.4%), 0 events +2026-02-04T18:58:11.042650Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16650/133889 blocks (12.4%), 0 events +2026-02-04T18:58:11.314184Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16660/133889 blocks (12.4%), 0 events +2026-02-04T18:58:11.393421Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16670/133889 blocks (12.4%), 0 events +2026-02-04T18:58:11.568969Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16680/133889 blocks (12.5%), 0 events +2026-02-04T18:58:11.877258Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16690/133889 blocks (12.5%), 0 events +2026-02-04T18:58:12.065156Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16700/133889 blocks (12.5%), 0 events +2026-02-04T18:58:12.167401Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16710/133889 blocks (12.5%), 0 events +2026-02-04T18:58:12.402259Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16720/133889 blocks (12.5%), 0 events +2026-02-04T18:58:12.586419Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16730/133889 blocks (12.5%), 0 events +2026-02-04T18:58:12.889119Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16740/133889 blocks (12.5%), 0 events +2026-02-04T18:58:12.997000Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16750/133889 blocks (12.5%), 0 events +2026-02-04T18:58:13.263185Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16760/133889 blocks (12.5%), 0 events +2026-02-04T18:58:13.458658Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16770/133889 blocks (12.5%), 0 events +2026-02-04T18:58:13.595011Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16780/133889 blocks (12.5%), 0 events +2026-02-04T18:58:13.810454Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16790/133889 blocks (12.5%), 0 events +2026-02-04T18:58:14.004482Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16800/133889 blocks (12.5%), 0 events +2026-02-04T18:58:14.238054Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16810/133889 blocks (12.6%), 0 events +2026-02-04T18:58:14.497744Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16820/133889 blocks (12.6%), 0 events +2026-02-04T18:58:14.636575Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16830/133889 blocks (12.6%), 0 events +2026-02-04T18:58:14.851291Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16840/133889 blocks (12.6%), 0 events +2026-02-04T18:58:15.018813Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16850/133889 blocks (12.6%), 0 events +2026-02-04T18:58:15.198347Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16860/133889 blocks (12.6%), 0 events +2026-02-04T18:58:15.396549Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16870/133889 blocks (12.6%), 0 events +2026-02-04T18:58:15.566757Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16880/133889 blocks (12.6%), 0 events +2026-02-04T18:58:15.818998Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16890/133889 blocks (12.6%), 0 events +2026-02-04T18:58:16.032729Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16900/133889 blocks (12.6%), 0 events +2026-02-04T18:58:16.220608Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16910/133889 blocks (12.6%), 0 events +2026-02-04T18:58:16.455529Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16920/133889 blocks (12.6%), 0 events +2026-02-04T18:58:16.590484Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16930/133889 blocks (12.6%), 0 events +2026-02-04T18:58:16.839172Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16940/133889 blocks (12.7%), 0 events +2026-02-04T18:58:16.989618Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16950/133889 blocks (12.7%), 0 events +2026-02-04T18:58:17.189420Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16960/133889 blocks (12.7%), 0 events +2026-02-04T18:58:17.371970Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16970/133889 blocks (12.7%), 0 events +2026-02-04T18:58:17.647523Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16980/133889 blocks (12.7%), 0 events +2026-02-04T18:58:17.773300Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16990/133889 blocks (12.7%), 0 events +2026-02-04T18:58:18.002311Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17000/133889 blocks (12.7%), 0 events +2026-02-04T18:58:18.212768Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17010/133889 blocks (12.7%), 0 events +2026-02-04T18:58:18.461343Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17020/133889 blocks (12.7%), 0 events +2026-02-04T18:58:18.654724Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17030/133889 blocks (12.7%), 0 events +2026-02-04T18:58:18.801955Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17040/133889 blocks (12.7%), 0 events +2026-02-04T18:58:19.029157Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17050/133889 blocks (12.7%), 0 events +2026-02-04T18:58:19.214141Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17060/133889 blocks (12.7%), 0 events +2026-02-04T18:58:19.444820Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17070/133889 blocks (12.7%), 0 events +2026-02-04T18:58:19.702335Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17080/133889 blocks (12.8%), 0 events +2026-02-04T18:58:19.807472Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17090/133889 blocks (12.8%), 0 events +2026-02-04T18:58:20.016599Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17100/133889 blocks (12.8%), 0 events +2026-02-04T18:58:20.260905Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17110/133889 blocks (12.8%), 0 events +2026-02-04T18:58:20.389204Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17120/133889 blocks (12.8%), 0 events +2026-02-04T18:58:20.643831Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17130/133889 blocks (12.8%), 0 events +2026-02-04T18:58:20.810792Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17140/133889 blocks (12.8%), 0 events +2026-02-04T18:58:20.997278Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17150/133889 blocks (12.8%), 0 events +2026-02-04T18:58:21.275396Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17160/133889 blocks (12.8%), 0 events +2026-02-04T18:58:21.440105Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17170/133889 blocks (12.8%), 0 events +2026-02-04T18:58:21.599806Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17180/133889 blocks (12.8%), 0 events +2026-02-04T18:58:21.832362Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17190/133889 blocks (12.8%), 0 events +2026-02-04T18:58:22.060828Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17200/133889 blocks (12.8%), 0 events +2026-02-04T18:58:22.182825Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17210/133889 blocks (12.9%), 0 events +2026-02-04T18:58:22.399615Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17220/133889 blocks (12.9%), 0 events +2026-02-04T18:58:22.579557Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17230/133889 blocks (12.9%), 0 events +2026-02-04T18:58:22.893046Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17240/133889 blocks (12.9%), 0 events +2026-02-04T18:58:23.066158Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17250/133889 blocks (12.9%), 0 events +2026-02-04T18:58:23.175560Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17260/133889 blocks (12.9%), 0 events +2026-02-04T18:58:23.440513Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17270/133889 blocks (12.9%), 0 events +2026-02-04T18:58:23.586177Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17280/133889 blocks (12.9%), 0 events +2026-02-04T18:58:23.934288Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17290/133889 blocks (12.9%), 0 events +2026-02-04T18:58:23.978097Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17300/133889 blocks (12.9%), 0 events +2026-02-04T18:58:24.226495Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17310/133889 blocks (12.9%), 0 events +2026-02-04T18:58:24.465698Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17320/133889 blocks (12.9%), 0 events +2026-02-04T18:58:24.598243Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17330/133889 blocks (12.9%), 0 events +2026-02-04T18:58:24.831898Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17340/133889 blocks (13.0%), 0 events +2026-02-04T18:58:25.042703Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17350/133889 blocks (13.0%), 0 events +2026-02-04T18:58:25.225031Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17360/133889 blocks (13.0%), 0 events +2026-02-04T18:58:25.507876Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17370/133889 blocks (13.0%), 0 events +2026-02-04T18:58:25.572306Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17380/133889 blocks (13.0%), 0 events +2026-02-04T18:58:25.821686Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17390/133889 blocks (13.0%), 0 events +2026-02-04T18:58:26.030096Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17400/133889 blocks (13.0%), 0 events +2026-02-04T18:58:26.191726Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17410/133889 blocks (13.0%), 0 events +2026-02-04T18:58:26.381721Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17420/133889 blocks (13.0%), 0 events +2026-02-04T18:58:26.634873Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17430/133889 blocks (13.0%), 0 events +2026-02-04T18:58:26.849727Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17440/133889 blocks (13.0%), 0 events +2026-02-04T18:58:27.043366Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17450/133889 blocks (13.0%), 0 events +2026-02-04T18:58:27.209472Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17460/133889 blocks (13.0%), 0 events +2026-02-04T18:58:27.384499Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17470/133889 blocks (13.0%), 0 events +2026-02-04T18:58:27.627663Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17480/133889 blocks (13.1%), 0 events +2026-02-04T18:58:27.826405Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17490/133889 blocks (13.1%), 0 events +2026-02-04T18:58:27.977040Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17500/133889 blocks (13.1%), 0 events +2026-02-04T18:58:28.264821Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17510/133889 blocks (13.1%), 0 events +2026-02-04T18:58:28.446297Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17520/133889 blocks (13.1%), 0 events +2026-02-04T18:58:28.652537Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17530/133889 blocks (13.1%), 0 events +2026-02-04T18:58:28.799631Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17540/133889 blocks (13.1%), 0 events +2026-02-04T18:58:29.047439Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17550/133889 blocks (13.1%), 0 events +2026-02-04T18:58:29.235022Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17560/133889 blocks (13.1%), 0 events +2026-02-04T18:58:29.386317Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17570/133889 blocks (13.1%), 0 events +2026-02-04T18:58:29.699928Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17580/133889 blocks (13.1%), 0 events +2026-02-04T18:58:29.772482Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17590/133889 blocks (13.1%), 0 events +2026-02-04T18:58:30.037929Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17600/133889 blocks (13.1%), 0 events +2026-02-04T18:58:30.224378Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17610/133889 blocks (13.2%), 0 events +2026-02-04T18:58:30.413594Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17620/133889 blocks (13.2%), 0 events +2026-02-04T18:58:30.713489Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17630/133889 blocks (13.2%), 0 events +2026-02-04T18:58:30.798766Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17640/133889 blocks (13.2%), 0 events +2026-02-04T18:58:30.971470Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17650/133889 blocks (13.2%), 0 events +2026-02-04T18:58:31.273775Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17660/133889 blocks (13.2%), 0 events +2026-02-04T18:58:31.382455Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17670/133889 blocks (13.2%), 0 events +2026-02-04T18:58:31.609977Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17680/133889 blocks (13.2%), 0 events +2026-02-04T18:58:31.810998Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17690/133889 blocks (13.2%), 0 events +2026-02-04T18:58:31.975818Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17700/133889 blocks (13.2%), 0 events +2026-02-04T18:58:32.315298Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17710/133889 blocks (13.2%), 0 events +2026-02-04T18:58:32.401727Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17720/133889 blocks (13.2%), 0 events +2026-02-04T18:58:32.578993Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17730/133889 blocks (13.2%), 0 events +2026-02-04T18:58:32.850621Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17740/133889 blocks (13.2%), 0 events +2026-02-04T18:58:33.038360Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17750/133889 blocks (13.3%), 0 events +2026-02-04T18:58:33.198538Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17760/133889 blocks (13.3%), 0 events +2026-02-04T18:58:33.402781Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17770/133889 blocks (13.3%), 0 events +2026-02-04T18:58:33.612237Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17780/133889 blocks (13.3%), 0 events +2026-02-04T18:58:33.894009Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17790/133889 blocks (13.3%), 0 events +2026-02-04T18:58:34.062396Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17800/133889 blocks (13.3%), 0 events +2026-02-04T18:58:34.234066Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17810/133889 blocks (13.3%), 0 events +2026-02-04T18:58:34.416845Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17820/133889 blocks (13.3%), 0 events +2026-02-04T18:58:34.582487Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17830/133889 blocks (13.3%), 0 events +2026-02-04T18:58:34.795555Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17840/133889 blocks (13.3%), 0 events +2026-02-04T18:58:35.045665Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17850/133889 blocks (13.3%), 0 events +2026-02-04T18:58:35.257747Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17860/133889 blocks (13.3%), 0 events +2026-02-04T18:58:35.473462Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17870/133889 blocks (13.3%), 0 events +2026-02-04T18:58:35.633879Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17880/133889 blocks (13.4%), 0 events +2026-02-04T18:58:35.783378Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17890/133889 blocks (13.4%), 0 events +2026-02-04T18:58:36.055843Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17900/133889 blocks (13.4%), 0 events +2026-02-04T18:58:36.169648Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17910/133889 blocks (13.4%), 0 events +2026-02-04T18:58:36.480666Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17920/133889 blocks (13.4%), 0 events +2026-02-04T18:58:36.651207Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17930/133889 blocks (13.4%), 0 events +2026-02-04T18:58:36.827462Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17940/133889 blocks (13.4%), 0 events +2026-02-04T18:58:37.038988Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17950/133889 blocks (13.4%), 0 events +2026-02-04T18:58:37.245605Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17960/133889 blocks (13.4%), 0 events +2026-02-04T18:58:37.382089Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17970/133889 blocks (13.4%), 0 events +2026-02-04T18:58:37.587050Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17980/133889 blocks (13.4%), 0 events +2026-02-04T18:58:37.860432Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17990/133889 blocks (13.4%), 0 events +2026-02-04T18:58:38.092205Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18000/133889 blocks (13.4%), 0 events +2026-02-04T18:58:38.266580Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18010/133889 blocks (13.5%), 0 events +2026-02-04T18:58:38.436750Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18020/133889 blocks (13.5%), 0 events +2026-02-04T18:58:38.653964Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18030/133889 blocks (13.5%), 0 events +2026-02-04T18:58:38.820020Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18040/133889 blocks (13.5%), 0 events +2026-02-04T18:58:38.981560Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18050/133889 blocks (13.5%), 0 events +2026-02-04T18:58:39.200316Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18060/133889 blocks (13.5%), 0 events +2026-02-04T18:58:39.464160Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18070/133889 blocks (13.5%), 0 events +2026-02-04T18:58:39.661988Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18080/133889 blocks (13.5%), 0 events +2026-02-04T18:58:39.790734Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18090/133889 blocks (13.5%), 0 events +2026-02-04T18:58:40.009609Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18100/133889 blocks (13.5%), 0 events +2026-02-04T18:58:40.239463Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18110/133889 blocks (13.5%), 0 events +2026-02-04T18:58:40.444858Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18120/133889 blocks (13.5%), 0 events +2026-02-04T18:58:40.675568Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18130/133889 blocks (13.5%), 0 events +2026-02-04T18:58:40.847517Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18140/133889 blocks (13.5%), 0 events +2026-02-04T18:58:40.978797Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18150/133889 blocks (13.6%), 0 events +2026-02-04T18:58:41.256474Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18160/133889 blocks (13.6%), 0 events +2026-02-04T18:58:41.456795Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18170/133889 blocks (13.6%), 0 events +2026-02-04T18:58:41.600879Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18180/133889 blocks (13.6%), 0 events +2026-02-04T18:58:41.861850Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18190/133889 blocks (13.6%), 0 events +2026-02-04T18:58:42.030389Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18200/133889 blocks (13.6%), 0 events +2026-02-04T18:58:42.245243Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18210/133889 blocks (13.6%), 0 events +2026-02-04T18:58:42.399217Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18220/133889 blocks (13.6%), 0 events +2026-02-04T18:58:42.595307Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18230/133889 blocks (13.6%), 0 events +2026-02-04T18:58:42.802810Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18240/133889 blocks (13.6%), 0 events +2026-02-04T18:58:43.002823Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18250/133889 blocks (13.6%), 0 events +2026-02-04T18:58:43.175753Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18260/133889 blocks (13.6%), 0 events +2026-02-04T18:58:43.400024Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18270/133889 blocks (13.6%), 0 events +2026-02-04T18:58:43.595714Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18280/133889 blocks (13.7%), 0 events +2026-02-04T18:58:43.860210Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18290/133889 blocks (13.7%), 0 events +2026-02-04T18:58:44.044767Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18300/133889 blocks (13.7%), 0 events +2026-02-04T18:58:44.250901Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18310/133889 blocks (13.7%), 0 events +2026-02-04T18:58:44.378827Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18320/133889 blocks (13.7%), 0 events +2026-02-04T18:58:44.644297Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18330/133889 blocks (13.7%), 0 events +2026-02-04T18:58:44.899695Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18340/133889 blocks (13.7%), 0 events +2026-02-04T18:58:45.008170Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18350/133889 blocks (13.7%), 0 events +2026-02-04T18:58:45.220045Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18360/133889 blocks (13.7%), 0 events +2026-02-04T18:58:45.423132Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18370/133889 blocks (13.7%), 0 events +2026-02-04T18:58:45.586770Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18380/133889 blocks (13.7%), 0 events +2026-02-04T18:58:45.810247Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18390/133889 blocks (13.7%), 0 events +2026-02-04T18:58:45.989928Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18400/133889 blocks (13.7%), 0 events +2026-02-04T18:58:46.224417Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18410/133889 blocks (13.7%), 0 events +2026-02-04T18:58:46.473400Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18420/133889 blocks (13.8%), 0 events +2026-02-04T18:58:46.564479Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18430/133889 blocks (13.8%), 0 events +2026-02-04T18:58:46.807832Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18440/133889 blocks (13.8%), 0 events +2026-02-04T18:58:46.998596Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18450/133889 blocks (13.8%), 0 events +2026-02-04T18:58:47.202390Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18460/133889 blocks (13.8%), 0 events +2026-02-04T18:58:47.531473Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18470/133889 blocks (13.8%), 0 events +2026-02-04T18:58:47.570190Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18480/133889 blocks (13.8%), 0 events +2026-02-04T18:58:47.788809Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18490/133889 blocks (13.8%), 0 events +2026-02-04T18:58:48.053017Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18500/133889 blocks (13.8%), 0 events +2026-02-04T18:58:48.252055Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18510/133889 blocks (13.8%), 0 events +2026-02-04T18:58:48.538690Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18520/133889 blocks (13.8%), 0 events +2026-02-04T18:58:48.577514Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18530/133889 blocks (13.8%), 0 events +2026-02-04T18:58:48.785060Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18540/133889 blocks (13.8%), 0 events +2026-02-04T18:58:49.061990Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18550/133889 blocks (13.9%), 0 events +2026-02-04T18:58:49.208309Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18560/133889 blocks (13.9%), 0 events +2026-02-04T18:58:49.375361Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18570/133889 blocks (13.9%), 0 events +2026-02-04T18:58:49.617217Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18580/133889 blocks (13.9%), 0 events +2026-02-04T18:58:49.841282Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18590/133889 blocks (13.9%), 0 events +2026-02-04T18:58:50.110235Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18600/133889 blocks (13.9%), 0 events +2026-02-04T18:58:50.251306Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18610/133889 blocks (13.9%), 0 events +2026-02-04T18:58:50.461249Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18620/133889 blocks (13.9%), 0 events +2026-02-04T18:58:50.731103Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18630/133889 blocks (13.9%), 0 events +2026-02-04T18:58:50.776713Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18640/133889 blocks (13.9%), 0 events +2026-02-04T18:58:51.060080Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18650/133889 blocks (13.9%), 0 events +2026-02-04T18:58:51.293908Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18660/133889 blocks (13.9%), 0 events +2026-02-04T18:58:51.440932Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18670/133889 blocks (13.9%), 0 events +2026-02-04T18:58:51.607468Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18680/133889 blocks (14.0%), 0 events +2026-02-04T18:58:51.825530Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18690/133889 blocks (14.0%), 0 events +2026-02-04T18:58:52.013178Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18700/133889 blocks (14.0%), 0 events +2026-02-04T18:58:52.303290Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18710/133889 blocks (14.0%), 0 events +2026-02-04T18:58:52.415814Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18720/133889 blocks (14.0%), 0 events +2026-02-04T18:58:52.664466Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18730/133889 blocks (14.0%), 0 events +2026-02-04T18:58:52.861314Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18740/133889 blocks (14.0%), 0 events +2026-02-04T18:58:52.987125Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18750/133889 blocks (14.0%), 0 events +2026-02-04T18:58:53.255244Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18760/133889 blocks (14.0%), 0 events +2026-02-04T18:58:53.458109Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18770/133889 blocks (14.0%), 0 events +2026-02-04T18:58:53.616868Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18780/133889 blocks (14.0%), 0 events +2026-02-04T18:58:53.875391Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18790/133889 blocks (14.0%), 0 events +2026-02-04T18:58:53.996560Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18800/133889 blocks (14.0%), 0 events +2026-02-04T18:58:54.170464Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18810/133889 blocks (14.0%), 0 events +2026-02-04T18:58:54.432717Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18820/133889 blocks (14.1%), 0 events +2026-02-04T18:58:54.617366Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18830/133889 blocks (14.1%), 0 events +2026-02-04T18:58:54.791980Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18840/133889 blocks (14.1%), 0 events +2026-02-04T18:58:54.972048Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18850/133889 blocks (14.1%), 0 events +2026-02-04T18:58:55.232254Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18860/133889 blocks (14.1%), 0 events +2026-02-04T18:58:55.449081Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18870/133889 blocks (14.1%), 0 events +2026-02-04T18:58:55.581945Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18880/133889 blocks (14.1%), 0 events +2026-02-04T18:58:55.832237Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18890/133889 blocks (14.1%), 0 events +2026-02-04T18:58:56.018422Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18900/133889 blocks (14.1%), 0 events +2026-02-04T18:58:56.213733Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18910/133889 blocks (14.1%), 0 events +2026-02-04T18:58:56.397141Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18920/133889 blocks (14.1%), 0 events +2026-02-04T18:58:56.665415Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18930/133889 blocks (14.1%), 0 events +2026-02-04T18:58:56.797549Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18940/133889 blocks (14.1%), 0 events +2026-02-04T18:58:57.055334Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18950/133889 blocks (14.2%), 0 events +2026-02-04T18:58:57.218835Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18960/133889 blocks (14.2%), 0 events +2026-02-04T18:58:57.420291Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18970/133889 blocks (14.2%), 0 events +2026-02-04T18:58:57.594355Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18980/133889 blocks (14.2%), 0 events +2026-02-04T18:58:57.822078Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18990/133889 blocks (14.2%), 0 events +2026-02-04T18:58:58.070201Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19000/133889 blocks (14.2%), 0 events +2026-02-04T18:58:58.173188Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19010/133889 blocks (14.2%), 0 events +2026-02-04T18:58:58.403995Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19020/133889 blocks (14.2%), 0 events +2026-02-04T18:58:58.626838Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19030/133889 blocks (14.2%), 0 events +2026-02-04T18:58:58.840441Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19040/133889 blocks (14.2%), 0 events +2026-02-04T18:58:59.120020Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19050/133889 blocks (14.2%), 0 events +2026-02-04T18:58:59.166702Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19060/133889 blocks (14.2%), 0 events +2026-02-04T18:58:59.392572Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19070/133889 blocks (14.2%), 0 events +2026-02-04T18:58:59.678898Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19080/133889 blocks (14.2%), 0 events +2026-02-04T18:58:59.808772Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19090/133889 blocks (14.3%), 0 events +2026-02-04T18:59:00.051960Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19100/133889 blocks (14.3%), 0 events +2026-02-04T18:59:00.208158Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19110/133889 blocks (14.3%), 0 events +2026-02-04T18:59:00.373131Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19120/133889 blocks (14.3%), 0 events +2026-02-04T18:59:00.724606Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19130/133889 blocks (14.3%), 0 events +2026-02-04T18:59:00.772276Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19140/133889 blocks (14.3%), 0 events +2026-02-04T18:59:01.011524Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19150/133889 blocks (14.3%), 0 events +2026-02-04T18:59:01.252453Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19160/133889 blocks (14.3%), 0 events +2026-02-04T18:59:01.462882Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19170/133889 blocks (14.3%), 0 events +2026-02-04T18:59:01.594114Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19180/133889 blocks (14.3%), 0 events +2026-02-04T18:59:01.812802Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19190/133889 blocks (14.3%), 0 events +2026-02-04T18:59:02.068909Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19200/133889 blocks (14.3%), 0 events +2026-02-04T18:59:02.263440Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19210/133889 blocks (14.3%), 0 events +2026-02-04T18:59:02.373164Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19220/133889 blocks (14.4%), 0 events +2026-02-04T18:59:02.595377Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19230/133889 blocks (14.4%), 0 events +2026-02-04T18:59:02.827409Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19240/133889 blocks (14.4%), 0 events +2026-02-04T18:59:03.060679Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19250/133889 blocks (14.4%), 0 events +2026-02-04T18:59:03.313457Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19260/133889 blocks (14.4%), 0 events +2026-02-04T18:59:03.396249Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19270/133889 blocks (14.4%), 0 events +2026-02-04T18:59:03.611572Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19280/133889 blocks (14.4%), 0 events +2026-02-04T18:59:03.838123Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19290/133889 blocks (14.4%), 0 events +2026-02-04T18:59:03.987857Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19300/133889 blocks (14.4%), 0 events +2026-02-04T18:59:04.238889Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19310/133889 blocks (14.4%), 0 events +2026-02-04T18:59:04.418094Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19320/133889 blocks (14.4%), 0 events +2026-02-04T18:59:04.573866Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19330/133889 blocks (14.4%), 0 events +2026-02-04T18:59:04.789702Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19340/133889 blocks (14.4%), 0 events +2026-02-04T18:59:05.063435Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19350/133889 blocks (14.5%), 0 events +2026-02-04T18:59:05.227176Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19360/133889 blocks (14.5%), 0 events +2026-02-04T18:59:05.441766Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19370/133889 blocks (14.5%), 0 events +2026-02-04T18:59:05.614715Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19380/133889 blocks (14.5%), 0 events +2026-02-04T18:59:05.797449Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19390/133889 blocks (14.5%), 0 events +2026-02-04T18:59:06.056285Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19400/133889 blocks (14.5%), 0 events +2026-02-04T18:59:06.232195Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19410/133889 blocks (14.5%), 0 events +2026-02-04T18:59:06.496566Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19420/133889 blocks (14.5%), 0 events +2026-02-04T18:59:06.638484Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19430/133889 blocks (14.5%), 0 events +2026-02-04T18:59:06.855938Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19440/133889 blocks (14.5%), 0 events +2026-02-04T18:59:07.038014Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19450/133889 blocks (14.5%), 0 events +2026-02-04T18:59:07.217499Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19460/133889 blocks (14.5%), 0 events +2026-02-04T18:59:07.365298Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19470/133889 blocks (14.5%), 0 events +2026-02-04T18:59:07.647246Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19480/133889 blocks (14.5%), 0 events +2026-02-04T18:59:07.793763Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19490/133889 blocks (14.6%), 0 events +2026-02-04T18:59:08.070757Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19500/133889 blocks (14.6%), 0 events +2026-02-04T18:59:08.243191Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19510/133889 blocks (14.6%), 0 events +2026-02-04T18:59:08.443238Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19520/133889 blocks (14.6%), 0 events +2026-02-04T18:59:08.610195Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19530/133889 blocks (14.6%), 0 events +2026-02-04T18:59:08.857820Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19540/133889 blocks (14.6%), 0 events +2026-02-04T18:59:08.987638Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19550/133889 blocks (14.6%), 0 events +2026-02-04T18:59:09.199832Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19560/133889 blocks (14.6%), 0 events +2026-02-04T18:59:09.373802Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19570/133889 blocks (14.6%), 0 events +2026-02-04T18:59:09.639055Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19580/133889 blocks (14.6%), 0 events +2026-02-04T18:59:09.790913Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19590/133889 blocks (14.6%), 0 events +2026-02-04T18:59:10.128955Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19600/133889 blocks (14.6%), 0 events +2026-02-04T18:59:10.169135Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19610/133889 blocks (14.6%), 0 events +2026-02-04T18:59:10.373775Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19620/133889 blocks (14.7%), 0 events +2026-02-04T18:59:10.694050Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19630/133889 blocks (14.7%), 0 events +2026-02-04T18:59:10.795661Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19640/133889 blocks (14.7%), 0 events +2026-02-04T18:59:11.004262Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19650/133889 blocks (14.7%), 0 events +2026-02-04T18:59:11.253503Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19660/133889 blocks (14.7%), 0 events +2026-02-04T18:59:11.429430Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19670/133889 blocks (14.7%), 0 events +2026-02-04T18:59:11.701996Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19680/133889 blocks (14.7%), 0 events +2026-02-04T18:59:11.776828Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19690/133889 blocks (14.7%), 0 events +2026-02-04T18:59:11.979356Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19700/133889 blocks (14.7%), 0 events +2026-02-04T18:59:12.255347Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19710/133889 blocks (14.7%), 0 events +2026-02-04T18:59:12.450510Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19720/133889 blocks (14.7%), 0 events +2026-02-04T18:59:12.639114Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19730/133889 blocks (14.7%), 0 events +2026-02-04T18:59:12.790287Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19740/133889 blocks (14.7%), 0 events +2026-02-04T18:59:13.071962Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19750/133889 blocks (14.8%), 0 events +2026-02-04T18:59:13.167972Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19760/133889 blocks (14.8%), 0 events +2026-02-04T18:59:13.458538Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19770/133889 blocks (14.8%), 0 events +2026-02-04T18:59:13.610331Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19780/133889 blocks (14.8%), 0 events +2026-02-04T18:59:13.849368Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19790/133889 blocks (14.8%), 0 events +2026-02-04T18:59:14.044370Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19800/133889 blocks (14.8%), 0 events +2026-02-04T18:59:14.172038Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19810/133889 blocks (14.8%), 0 events +2026-02-04T18:59:14.457064Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19820/133889 blocks (14.8%), 0 events +2026-02-04T18:59:14.638996Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19830/133889 blocks (14.8%), 0 events +2026-02-04T18:59:14.885686Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19840/133889 blocks (14.8%), 0 events +2026-02-04T18:59:15.063485Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19850/133889 blocks (14.8%), 0 events +2026-02-04T18:59:15.240185Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19860/133889 blocks (14.8%), 0 events +2026-02-04T18:59:15.448240Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19870/133889 blocks (14.8%), 0 events +2026-02-04T18:59:15.608529Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19880/133889 blocks (14.8%), 0 events +2026-02-04T18:59:15.896450Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19890/133889 blocks (14.9%), 0 events +2026-02-04T18:59:16.003034Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19900/133889 blocks (14.9%), 0 events +2026-02-04T18:59:16.233804Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19910/133889 blocks (14.9%), 0 events +2026-02-04T18:59:16.473427Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19920/133889 blocks (14.9%), 0 events +2026-02-04T18:59:16.635684Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19930/133889 blocks (14.9%), 0 events +2026-02-04T18:59:16.766593Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19940/133889 blocks (14.9%), 0 events +2026-02-04T18:59:17.050673Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19950/133889 blocks (14.9%), 0 events +2026-02-04T18:59:17.213986Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19960/133889 blocks (14.9%), 0 events +2026-02-04T18:59:17.499012Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19970/133889 blocks (14.9%), 0 events +2026-02-04T18:59:17.667865Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19980/133889 blocks (14.9%), 0 events +2026-02-04T18:59:17.844272Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19990/133889 blocks (14.9%), 0 events +2026-02-04T18:59:18.030800Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20000/133889 blocks (14.9%), 0 events +2026-02-04T18:59:18.179502Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20010/133889 blocks (14.9%), 0 events +2026-02-04T18:59:18.366234Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20020/133889 blocks (15.0%), 0 events +2026-02-04T18:59:18.637102Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20030/133889 blocks (15.0%), 0 events +2026-02-04T18:59:18.816596Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20040/133889 blocks (15.0%), 0 events +2026-02-04T18:59:19.042261Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20050/133889 blocks (15.0%), 0 events +2026-02-04T18:59:19.239807Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20060/133889 blocks (15.0%), 0 events +2026-02-04T18:59:19.377761Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20070/133889 blocks (15.0%), 0 events +2026-02-04T18:59:19.597091Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20080/133889 blocks (15.0%), 0 events +2026-02-04T18:59:19.796704Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20090/133889 blocks (15.0%), 0 events +2026-02-04T18:59:20.088002Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20100/133889 blocks (15.0%), 0 events +2026-02-04T18:59:20.231562Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20110/133889 blocks (15.0%), 0 events +2026-02-04T18:59:20.460495Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20120/133889 blocks (15.0%), 0 events +2026-02-04T18:59:20.648798Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20130/133889 blocks (15.0%), 0 events +2026-02-04T18:59:20.797049Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20140/133889 blocks (15.0%), 0 events +2026-02-04T18:59:21.044346Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20150/133889 blocks (15.0%), 0 events +2026-02-04T18:59:21.177179Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20160/133889 blocks (15.1%), 0 events +2026-02-04T18:59:21.460531Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20170/133889 blocks (15.1%), 0 events +2026-02-04T18:59:21.699332Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20180/133889 blocks (15.1%), 0 events +2026-02-04T18:59:21.867522Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20190/133889 blocks (15.1%), 0 events +2026-02-04T18:59:22.000255Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20200/133889 blocks (15.1%), 0 events +2026-02-04T18:59:22.262975Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20210/133889 blocks (15.1%), 0 events +2026-02-04T18:59:22.385296Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20220/133889 blocks (15.1%), 0 events +2026-02-04T18:59:22.565014Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20230/133889 blocks (15.1%), 0 events +2026-02-04T18:59:22.830090Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20240/133889 blocks (15.1%), 0 events +2026-02-04T18:59:22.968894Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20250/133889 blocks (15.1%), 0 events +2026-02-04T18:59:23.274706Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20260/133889 blocks (15.1%), 0 events +2026-02-04T18:59:23.460987Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20270/133889 blocks (15.1%), 0 events +2026-02-04T18:59:23.629009Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20280/133889 blocks (15.1%), 0 events +2026-02-04T18:59:23.791867Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20290/133889 blocks (15.2%), 0 events +2026-02-04T18:59:24.007253Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20300/133889 blocks (15.2%), 0 events +2026-02-04T18:59:24.284763Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20310/133889 blocks (15.2%), 0 events +2026-02-04T18:59:24.446222Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20320/133889 blocks (15.2%), 0 events +2026-02-04T18:59:24.633719Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20330/133889 blocks (15.2%), 0 events +2026-02-04T18:59:24.866522Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20340/133889 blocks (15.2%), 0 events +2026-02-04T18:59:24.994263Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20350/133889 blocks (15.2%), 0 events +2026-02-04T18:59:25.332102Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20360/133889 blocks (15.2%), 0 events +2026-02-04T18:59:25.372361Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20370/133889 blocks (15.2%), 0 events +2026-02-04T18:59:25.570392Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20380/133889 blocks (15.2%), 0 events +2026-02-04T18:59:25.856399Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20390/133889 blocks (15.2%), 0 events +2026-02-04T18:59:25.976352Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20400/133889 blocks (15.2%), 0 events +2026-02-04T18:59:26.180631Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20410/133889 blocks (15.2%), 0 events +2026-02-04T18:59:26.458226Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20420/133889 blocks (15.3%), 0 events +2026-02-04T18:59:26.574413Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20430/133889 blocks (15.3%), 0 events +2026-02-04T18:59:26.810825Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20440/133889 blocks (15.3%), 0 events +2026-02-04T18:59:27.019867Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20450/133889 blocks (15.3%), 0 events +2026-02-04T18:59:27.220579Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20460/133889 blocks (15.3%), 0 events +2026-02-04T18:59:27.476287Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20470/133889 blocks (15.3%), 0 events +2026-02-04T18:59:27.634925Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20480/133889 blocks (15.3%), 0 events +2026-02-04T18:59:27.836535Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20490/133889 blocks (15.3%), 0 events +2026-02-04T18:59:28.034825Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20500/133889 blocks (15.3%), 0 events +2026-02-04T18:59:28.263878Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20510/133889 blocks (15.3%), 0 events +2026-02-04T18:59:28.514135Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20520/133889 blocks (15.3%), 0 events +2026-02-04T18:59:28.609110Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20530/133889 blocks (15.3%), 0 events +2026-02-04T18:59:28.841363Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20540/133889 blocks (15.3%), 0 events +2026-02-04T18:59:29.035359Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20550/133889 blocks (15.3%), 0 events +2026-02-04T18:59:29.176497Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20560/133889 blocks (15.4%), 0 events +2026-02-04T18:59:29.415399Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20570/133889 blocks (15.4%), 0 events +2026-02-04T18:59:29.642656Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20580/133889 blocks (15.4%), 0 events +2026-02-04T18:59:29.840577Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20590/133889 blocks (15.4%), 0 events +2026-02-04T18:59:30.086631Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20600/133889 blocks (15.4%), 0 events +2026-02-04T18:59:30.218754Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20610/133889 blocks (15.4%), 0 events +2026-02-04T18:59:30.409878Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20620/133889 blocks (15.4%), 0 events +2026-02-04T18:59:30.609859Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20630/133889 blocks (15.4%), 0 events +2026-02-04T18:59:30.863354Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20640/133889 blocks (15.4%), 0 events +2026-02-04T18:59:31.100673Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20650/133889 blocks (15.4%), 0 events +2026-02-04T18:59:31.246282Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20660/133889 blocks (15.4%), 0 events +2026-02-04T18:59:31.461556Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20670/133889 blocks (15.4%), 0 events +2026-02-04T18:59:31.656622Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20680/133889 blocks (15.4%), 0 events +2026-02-04T18:59:31.800008Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20690/133889 blocks (15.5%), 0 events +2026-02-04T18:59:32.049432Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20700/133889 blocks (15.5%), 0 events +2026-02-04T18:59:32.241158Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20710/133889 blocks (15.5%), 0 events +2026-02-04T18:59:32.432210Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20720/133889 blocks (15.5%), 0 events +2026-02-04T18:59:32.569100Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20730/133889 blocks (15.5%), 0 events +2026-02-04T18:59:32.780177Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20740/133889 blocks (15.5%), 0 events +2026-02-04T18:59:33.005728Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20750/133889 blocks (15.5%), 0 events +2026-02-04T18:59:33.231894Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20760/133889 blocks (15.5%), 0 events +2026-02-04T18:59:33.446867Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20770/133889 blocks (15.5%), 0 events +2026-02-04T18:59:33.578107Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20780/133889 blocks (15.5%), 0 events +2026-02-04T18:59:33.799993Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20790/133889 blocks (15.5%), 0 events +2026-02-04T18:59:34.028010Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20800/133889 blocks (15.5%), 0 events +2026-02-04T18:59:34.277350Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20810/133889 blocks (15.5%), 0 events +2026-02-04T18:59:34.373035Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20820/133889 blocks (15.5%), 0 events +2026-02-04T18:59:34.590650Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20830/133889 blocks (15.6%), 0 events +2026-02-04T18:59:34.799272Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20840/133889 blocks (15.6%), 0 events +2026-02-04T18:59:35.025280Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20850/133889 blocks (15.6%), 0 events +2026-02-04T18:59:35.327817Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20860/133889 blocks (15.6%), 0 events +2026-02-04T18:59:35.366064Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20870/133889 blocks (15.6%), 0 events +2026-02-04T18:59:35.588352Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20880/133889 blocks (15.6%), 0 events +2026-02-04T18:59:35.849466Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20890/133889 blocks (15.6%), 0 events +2026-02-04T18:59:35.994058Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20900/133889 blocks (15.6%), 0 events +2026-02-04T18:59:36.185776Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20910/133889 blocks (15.6%), 0 events +2026-02-04T18:59:36.382675Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20920/133889 blocks (15.6%), 0 events +2026-02-04T18:59:36.633242Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20930/133889 blocks (15.6%), 0 events +2026-02-04T18:59:36.866950Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20940/133889 blocks (15.6%), 0 events +2026-02-04T18:59:37.007785Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20950/133889 blocks (15.6%), 0 events +2026-02-04T18:59:37.217480Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20960/133889 blocks (15.7%), 0 events +2026-02-04T18:59:37.439141Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20970/133889 blocks (15.7%), 0 events +2026-02-04T18:59:37.586664Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20980/133889 blocks (15.7%), 0 events +2026-02-04T18:59:37.768114Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20990/133889 blocks (15.7%), 0 events +2026-02-04T18:59:37.988038Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21000/133889 blocks (15.7%), 0 events +2026-02-04T18:59:38.232702Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21010/133889 blocks (15.7%), 0 events +2026-02-04T18:59:38.484414Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21020/133889 blocks (15.7%), 0 events +2026-02-04T18:59:38.614701Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21030/133889 blocks (15.7%), 0 events +2026-02-04T18:59:38.771325Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21040/133889 blocks (15.7%), 0 events +2026-02-04T18:59:39.012538Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21050/133889 blocks (15.7%), 0 events +2026-02-04T18:59:39.203847Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21060/133889 blocks (15.7%), 0 events +2026-02-04T18:59:39.372601Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21070/133889 blocks (15.7%), 0 events +2026-02-04T18:59:39.622020Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21080/133889 blocks (15.7%), 0 events +2026-02-04T18:59:39.842761Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21090/133889 blocks (15.8%), 0 events +2026-02-04T18:59:40.056296Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21100/133889 blocks (15.8%), 0 events +2026-02-04T18:59:40.242333Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21110/133889 blocks (15.8%), 0 events +2026-02-04T18:59:40.428639Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21120/133889 blocks (15.8%), 0 events +2026-02-04T18:59:40.585301Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21130/133889 blocks (15.8%), 0 events +2026-02-04T18:59:40.805583Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21140/133889 blocks (15.8%), 0 events +2026-02-04T18:59:41.093073Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21150/133889 blocks (15.8%), 0 events +2026-02-04T18:59:41.191158Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21160/133889 blocks (15.8%), 0 events +2026-02-04T18:59:41.465182Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21170/133889 blocks (15.8%), 0 events +2026-02-04T18:59:41.617133Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21180/133889 blocks (15.8%), 0 events +2026-02-04T18:59:41.827035Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21190/133889 blocks (15.8%), 0 events +2026-02-04T18:59:41.982561Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21200/133889 blocks (15.8%), 0 events +2026-02-04T18:59:42.215272Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21210/133889 blocks (15.8%), 0 events +2026-02-04T18:59:42.432499Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21220/133889 blocks (15.8%), 0 events +2026-02-04T18:59:42.667027Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21230/133889 blocks (15.9%), 0 events +2026-02-04T18:59:42.769753Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21240/133889 blocks (15.9%), 0 events +2026-02-04T18:59:43.027513Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21250/133889 blocks (15.9%), 0 events +2026-02-04T18:59:43.198268Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21260/133889 blocks (15.9%), 0 events +2026-02-04T18:59:43.399733Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21270/133889 blocks (15.9%), 0 events +2026-02-04T18:59:43.577736Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21280/133889 blocks (15.9%), 0 events +2026-02-04T18:59:43.778754Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21290/133889 blocks (15.9%), 0 events +2026-02-04T18:59:44.051188Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21300/133889 blocks (15.9%), 0 events +2026-02-04T18:59:44.239189Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21310/133889 blocks (15.9%), 0 events +2026-02-04T18:59:44.373177Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21320/133889 blocks (15.9%), 0 events +2026-02-04T18:59:44.731563Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21330/133889 blocks (15.9%), 0 events +2026-02-04T18:59:44.773048Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21340/133889 blocks (15.9%), 0 events +2026-02-04T18:59:44.974757Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21350/133889 blocks (15.9%), 0 events +2026-02-04T18:59:45.255874Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21360/133889 blocks (16.0%), 0 events +2026-02-04T18:59:45.419668Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21370/133889 blocks (16.0%), 0 events +2026-02-04T18:59:45.601846Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21380/133889 blocks (16.0%), 0 events +2026-02-04T18:59:45.819051Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21390/133889 blocks (16.0%), 0 events +2026-02-04T18:59:46.057107Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21400/133889 blocks (16.0%), 0 events +2026-02-04T18:59:46.303146Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21410/133889 blocks (16.0%), 0 events +2026-02-04T18:59:46.364066Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21420/133889 blocks (16.0%), 0 events +2026-02-04T18:59:46.645426Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21430/133889 blocks (16.0%), 0 events +2026-02-04T18:59:46.860390Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21440/133889 blocks (16.0%), 0 events +2026-02-04T18:59:46.998503Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21450/133889 blocks (16.0%), 0 events +2026-02-04T18:59:47.186723Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21460/133889 blocks (16.0%), 0 events +2026-02-04T18:59:47.392474Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21470/133889 blocks (16.0%), 0 events +2026-02-04T18:59:47.653871Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21480/133889 blocks (16.0%), 0 events +2026-02-04T18:59:47.902779Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21490/133889 blocks (16.0%), 0 events +2026-02-04T18:59:47.993448Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21500/133889 blocks (16.1%), 0 events +2026-02-04T18:59:48.239308Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21510/133889 blocks (16.1%), 0 events +2026-02-04T18:59:48.433647Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21520/133889 blocks (16.1%), 0 events +2026-02-04T18:59:48.588955Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21530/133889 blocks (16.1%), 0 events +2026-02-04T18:59:48.923552Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21540/133889 blocks (16.1%), 0 events +2026-02-04T18:59:48.961099Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21550/133889 blocks (16.1%), 0 events +2026-02-04T18:59:49.238740Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21560/133889 blocks (16.1%), 0 events +2026-02-04T18:59:49.482991Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21570/133889 blocks (16.1%), 0 events +2026-02-04T18:59:49.644255Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21580/133889 blocks (16.1%), 0 events +2026-02-04T18:59:49.818337Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21590/133889 blocks (16.1%), 0 events +2026-02-04T18:59:50.014600Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21600/133889 blocks (16.1%), 0 events +2026-02-04T18:59:50.261315Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21610/133889 blocks (16.1%), 0 events +2026-02-04T18:59:50.395471Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21620/133889 blocks (16.1%), 0 events +2026-02-04T18:59:50.664030Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21630/133889 blocks (16.2%), 0 events +2026-02-04T18:59:50.821760Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21640/133889 blocks (16.2%), 0 events +2026-02-04T18:59:51.058003Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21650/133889 blocks (16.2%), 0 events +2026-02-04T18:59:51.261650Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21660/133889 blocks (16.2%), 0 events +2026-02-04T18:59:51.391541Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21670/133889 blocks (16.2%), 0 events +2026-02-04T18:59:51.648119Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21680/133889 blocks (16.2%), 0 events +2026-02-04T18:59:51.814922Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21690/133889 blocks (16.2%), 0 events +2026-02-04T18:59:51.964844Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21700/133889 blocks (16.2%), 0 events +2026-02-04T18:59:52.244923Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21710/133889 blocks (16.2%), 0 events +2026-02-04T18:59:52.418008Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21720/133889 blocks (16.2%), 0 events +2026-02-04T18:59:52.624552Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21730/133889 blocks (16.2%), 0 events +2026-02-04T18:59:52.844165Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21740/133889 blocks (16.2%), 0 events +2026-02-04T18:59:53.118122Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21750/133889 blocks (16.2%), 0 events +2026-02-04T18:59:53.179752Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21760/133889 blocks (16.3%), 0 events +2026-02-04T18:59:53.446605Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21770/133889 blocks (16.3%), 0 events +2026-02-04T18:59:53.644196Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21780/133889 blocks (16.3%), 0 events +2026-02-04T18:59:53.789344Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21790/133889 blocks (16.3%), 0 events +2026-02-04T18:59:53.994202Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21800/133889 blocks (16.3%), 0 events +2026-02-04T18:59:54.249688Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21810/133889 blocks (16.3%), 0 events +2026-02-04T18:59:54.419876Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21820/133889 blocks (16.3%), 0 events +2026-02-04T18:59:54.564957Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21830/133889 blocks (16.3%), 0 events +2026-02-04T18:59:54.841332Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21840/133889 blocks (16.3%), 0 events +2026-02-04T18:59:54.982658Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21850/133889 blocks (16.3%), 0 events +2026-02-04T18:59:55.251341Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21860/133889 blocks (16.3%), 0 events +2026-02-04T18:59:55.389068Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21870/133889 blocks (16.3%), 0 events +2026-02-04T18:59:55.739879Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21880/133889 blocks (16.3%), 0 events +2026-02-04T18:59:55.781823Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21890/133889 blocks (16.3%), 0 events +2026-02-04T18:59:55.981558Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21900/133889 blocks (16.4%), 0 events +2026-02-04T18:59:56.301121Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21910/133889 blocks (16.4%), 0 events +2026-02-04T18:59:56.434361Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21920/133889 blocks (16.4%), 0 events +2026-02-04T18:59:56.645129Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21930/133889 blocks (16.4%), 0 events +2026-02-04T18:59:56.846983Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21940/133889 blocks (16.4%), 0 events +2026-02-04T18:59:56.985783Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21950/133889 blocks (16.4%), 0 events +2026-02-04T18:59:57.310426Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21960/133889 blocks (16.4%), 0 events +2026-02-04T18:59:57.381479Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21970/133889 blocks (16.4%), 0 events +2026-02-04T18:59:57.610408Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21980/133889 blocks (16.4%), 0 events +2026-02-04T18:59:57.871058Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21990/133889 blocks (16.4%), 0 events +2026-02-04T18:59:58.053176Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22000/133889 blocks (16.4%), 0 events +2026-02-04T18:59:58.227375Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22010/133889 blocks (16.4%), 0 events +2026-02-04T18:59:58.451280Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22020/133889 blocks (16.4%), 0 events +2026-02-04T18:59:58.590606Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22030/133889 blocks (16.5%), 0 events +2026-02-04T18:59:58.917085Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22040/133889 blocks (16.5%), 0 events +2026-02-04T18:59:58.990249Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22050/133889 blocks (16.5%), 0 events +2026-02-04T18:59:59.192608Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22060/133889 blocks (16.5%), 0 events +2026-02-04T18:59:59.438520Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22070/133889 blocks (16.5%), 0 events +2026-02-04T18:59:59.619692Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22080/133889 blocks (16.5%), 0 events +2026-02-04T18:59:59.798005Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22090/133889 blocks (16.5%), 0 events +2026-02-04T19:00:00.015933Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22100/133889 blocks (16.5%), 0 events +2026-02-04T19:00:00.266432Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22110/133889 blocks (16.5%), 0 events +2026-02-04T19:00:00.459291Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22120/133889 blocks (16.5%), 0 events +2026-02-04T19:00:00.665445Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22130/133889 blocks (16.5%), 0 events +2026-02-04T19:00:00.829338Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22140/133889 blocks (16.5%), 0 events +2026-02-04T19:00:01.032054Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22150/133889 blocks (16.5%), 0 events +2026-02-04T19:00:01.278363Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22160/133889 blocks (16.6%), 0 events +2026-02-04T19:00:01.506343Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22170/133889 blocks (16.6%), 0 events +2026-02-04T19:00:01.592065Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22180/133889 blocks (16.6%), 0 events +2026-02-04T19:00:01.813121Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22190/133889 blocks (16.6%), 0 events +2026-02-04T19:00:02.095760Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22200/133889 blocks (16.6%), 0 events +2026-02-04T19:00:02.191881Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22210/133889 blocks (16.6%), 0 events +2026-02-04T19:00:02.464169Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22220/133889 blocks (16.6%), 0 events +2026-02-04T19:00:02.593788Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22230/133889 blocks (16.6%), 0 events +2026-02-04T19:00:02.771315Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22240/133889 blocks (16.6%), 0 events +2026-02-04T19:00:02.984709Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22250/133889 blocks (16.6%), 0 events +2026-02-04T19:00:03.231537Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22260/133889 blocks (16.6%), 0 events +2026-02-04T19:00:03.366177Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22270/133889 blocks (16.6%), 0 events +2026-02-04T19:00:03.634296Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22280/133889 blocks (16.6%), 0 events +2026-02-04T19:00:03.850411Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22290/133889 blocks (16.6%), 0 events +2026-02-04T19:00:04.132484Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22300/133889 blocks (16.7%), 0 events +2026-02-04T19:00:04.192005Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22310/133889 blocks (16.7%), 0 events +2026-02-04T19:00:04.386665Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22320/133889 blocks (16.7%), 0 events +2026-02-04T19:00:04.697765Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22330/133889 blocks (16.7%), 0 events +2026-02-04T19:00:04.833783Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22340/133889 blocks (16.7%), 0 events +2026-02-04T19:00:05.020761Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22350/133889 blocks (16.7%), 0 events +2026-02-04T19:00:05.210151Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22360/133889 blocks (16.7%), 0 events +2026-02-04T19:00:05.410415Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22370/133889 blocks (16.7%), 0 events +2026-02-04T19:00:05.578179Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22380/133889 blocks (16.7%), 0 events +2026-02-04T19:00:05.805116Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22390/133889 blocks (16.7%), 0 events +2026-02-04T19:00:06.059682Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22400/133889 blocks (16.7%), 0 events +2026-02-04T19:00:06.267307Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22410/133889 blocks (16.7%), 0 events +2026-02-04T19:00:06.420214Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22420/133889 blocks (16.7%), 0 events +2026-02-04T19:00:06.575302Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22430/133889 blocks (16.8%), 0 events +2026-02-04T19:00:06.846269Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22440/133889 blocks (16.8%), 0 events +2026-02-04T19:00:07.016063Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22450/133889 blocks (16.8%), 0 events +2026-02-04T19:00:07.309147Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22460/133889 blocks (16.8%), 0 events +2026-02-04T19:00:07.393073Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22470/133889 blocks (16.8%), 0 events +2026-02-04T19:00:07.632214Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22480/133889 blocks (16.8%), 0 events +2026-02-04T19:00:07.843685Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22490/133889 blocks (16.8%), 0 events +2026-02-04T19:00:08.027817Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22500/133889 blocks (16.8%), 0 events +2026-02-04T19:00:08.321795Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22510/133889 blocks (16.8%), 0 events +2026-02-04T19:00:08.357435Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22520/133889 blocks (16.8%), 0 events +2026-02-04T19:00:08.664356Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22530/133889 blocks (16.8%), 0 events +2026-02-04T19:00:08.846317Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22540/133889 blocks (16.8%), 0 events +2026-02-04T19:00:09.067590Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22550/133889 blocks (16.8%), 0 events +2026-02-04T19:00:09.197593Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22560/133889 blocks (16.8%), 0 events +2026-02-04T19:00:09.470091Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22570/133889 blocks (16.9%), 0 events +2026-02-04T19:00:09.605909Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22580/133889 blocks (16.9%), 0 events +2026-02-04T19:00:09.926796Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22590/133889 blocks (16.9%), 0 events +2026-02-04T19:00:09.965861Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22600/133889 blocks (16.9%), 0 events +2026-02-04T19:00:10.255462Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22610/133889 blocks (16.9%), 0 events +2026-02-04T19:00:10.451938Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22620/133889 blocks (16.9%), 0 events +2026-02-04T19:00:10.649527Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22630/133889 blocks (16.9%), 0 events +2026-02-04T19:00:10.787529Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22640/133889 blocks (16.9%), 0 events +2026-02-04T19:00:11.045890Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22650/133889 blocks (16.9%), 0 events +2026-02-04T19:00:11.251455Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22660/133889 blocks (16.9%), 0 events +2026-02-04T19:00:11.373927Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22670/133889 blocks (16.9%), 0 events +2026-02-04T19:00:11.596454Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22680/133889 blocks (16.9%), 0 events +2026-02-04T19:00:11.802240Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22690/133889 blocks (16.9%), 0 events +2026-02-04T19:00:12.044694Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22700/133889 blocks (17.0%), 0 events +2026-02-04T19:00:12.213827Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22710/133889 blocks (17.0%), 0 events +2026-02-04T19:00:12.515685Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22720/133889 blocks (17.0%), 0 events +2026-02-04T19:00:12.594544Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22730/133889 blocks (17.0%), 0 events +2026-02-04T19:00:12.812933Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22740/133889 blocks (17.0%), 0 events +2026-02-04T19:00:13.040357Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22750/133889 blocks (17.0%), 0 events +2026-02-04T19:00:13.186024Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22760/133889 blocks (17.0%), 0 events +2026-02-04T19:00:13.565389Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22770/133889 blocks (17.0%), 0 events +2026-02-04T19:00:13.607115Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22780/133889 blocks (17.0%), 0 events +2026-02-04T19:00:13.789606Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22790/133889 blocks (17.0%), 0 events +2026-02-04T19:00:13.994762Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22800/133889 blocks (17.0%), 0 events +2026-02-04T19:00:14.229943Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22810/133889 blocks (17.0%), 0 events +2026-02-04T19:00:14.397292Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22820/133889 blocks (17.0%), 0 events +2026-02-04T19:00:14.648756Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22830/133889 blocks (17.1%), 0 events +2026-02-04T19:00:14.793741Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22840/133889 blocks (17.1%), 0 events +2026-02-04T19:00:15.011693Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22850/133889 blocks (17.1%), 0 events +2026-02-04T19:00:15.228834Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22860/133889 blocks (17.1%), 0 events +2026-02-04T19:00:15.426485Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22870/133889 blocks (17.1%), 0 events +2026-02-04T19:00:15.710183Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22880/133889 blocks (17.1%), 0 events +2026-02-04T19:00:15.771881Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22890/133889 blocks (17.1%), 0 events +2026-02-04T19:00:16.041188Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22900/133889 blocks (17.1%), 0 events +2026-02-04T19:00:16.218508Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22910/133889 blocks (17.1%), 0 events +2026-02-04T19:00:16.435440Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22920/133889 blocks (17.1%), 0 events +2026-02-04T19:00:16.612942Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22930/133889 blocks (17.1%), 0 events +2026-02-04T19:00:16.806656Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22940/133889 blocks (17.1%), 0 events +2026-02-04T19:00:17.072985Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22950/133889 blocks (17.1%), 0 events +2026-02-04T19:00:17.270930Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22960/133889 blocks (17.1%), 0 events +2026-02-04T19:00:17.451719Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22970/133889 blocks (17.2%), 0 events +2026-02-04T19:00:17.598758Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22980/133889 blocks (17.2%), 0 events +2026-02-04T19:00:17.838325Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22990/133889 blocks (17.2%), 0 events +2026-02-04T19:00:17.982993Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23000/133889 blocks (17.2%), 0 events +2026-02-04T19:00:18.187156Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23010/133889 blocks (17.2%), 0 events +2026-02-04T19:00:18.440316Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23020/133889 blocks (17.2%), 0 events +2026-02-04T19:00:18.661054Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23030/133889 blocks (17.2%), 0 events +2026-02-04T19:00:18.842916Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23040/133889 blocks (17.2%), 0 events +2026-02-04T19:00:18.982927Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23050/133889 blocks (17.2%), 0 events +2026-02-04T19:00:19.330118Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23060/133889 blocks (17.2%), 0 events +2026-02-04T19:00:19.373733Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23070/133889 blocks (17.2%), 0 events +2026-02-04T19:00:19.620456Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23080/133889 blocks (17.2%), 0 events +2026-02-04T19:00:19.889304Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23090/133889 blocks (17.2%), 0 events +2026-02-04T19:00:19.978681Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23100/133889 blocks (17.3%), 0 events +2026-02-04T19:00:20.190654Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23110/133889 blocks (17.3%), 0 events +2026-02-04T19:00:20.462557Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23120/133889 blocks (17.3%), 0 events +2026-02-04T19:00:20.602486Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23130/133889 blocks (17.3%), 0 events +2026-02-04T19:00:20.783927Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23140/133889 blocks (17.3%), 0 events +2026-02-04T19:00:20.978367Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23150/133889 blocks (17.3%), 0 events +2026-02-04T19:00:21.191797Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23160/133889 blocks (17.3%), 0 events +2026-02-04T19:00:21.466176Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23170/133889 blocks (17.3%), 0 events +2026-02-04T19:00:21.620223Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23180/133889 blocks (17.3%), 0 events +2026-02-04T19:00:21.953043Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23190/133889 blocks (17.3%), 0 events +2026-02-04T19:00:22.029286Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23200/133889 blocks (17.3%), 0 events +2026-02-04T19:00:22.237005Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23210/133889 blocks (17.3%), 0 events +2026-02-04T19:00:22.376222Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23220/133889 blocks (17.3%), 0 events +2026-02-04T19:00:22.639356Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23230/133889 blocks (17.3%), 0 events +2026-02-04T19:00:22.851607Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23240/133889 blocks (17.4%), 0 events +2026-02-04T19:00:23.042166Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23250/133889 blocks (17.4%), 0 events +2026-02-04T19:00:23.204344Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23260/133889 blocks (17.4%), 0 events +2026-02-04T19:00:23.526134Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23270/133889 blocks (17.4%), 0 events +2026-02-04T19:00:23.589898Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23280/133889 blocks (17.4%), 0 events +2026-02-04T19:00:23.819699Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23290/133889 blocks (17.4%), 0 events +2026-02-04T19:00:24.083788Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23300/133889 blocks (17.4%), 0 events +2026-02-04T19:00:24.200038Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23310/133889 blocks (17.4%), 0 events +2026-02-04T19:00:24.439312Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23320/133889 blocks (17.4%), 0 events +2026-02-04T19:00:24.608688Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23330/133889 blocks (17.4%), 0 events +2026-02-04T19:00:24.795209Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23340/133889 blocks (17.4%), 0 events +2026-02-04T19:00:25.131239Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23350/133889 blocks (17.4%), 0 events +2026-02-04T19:00:25.171933Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23360/133889 blocks (17.4%), 0 events +2026-02-04T19:00:25.372092Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23370/133889 blocks (17.5%), 0 events +2026-02-04T19:00:25.653292Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23380/133889 blocks (17.5%), 0 events +2026-02-04T19:00:25.847099Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23390/133889 blocks (17.5%), 0 events +2026-02-04T19:00:26.147176Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23400/133889 blocks (17.5%), 0 events +2026-02-04T19:00:26.184063Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23410/133889 blocks (17.5%), 0 events +2026-02-04T19:00:26.365702Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23420/133889 blocks (17.5%), 0 events +2026-02-04T19:00:26.573828Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23430/133889 blocks (17.5%), 0 events +2026-02-04T19:00:26.808406Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23440/133889 blocks (17.5%), 0 events +2026-02-04T19:00:26.988285Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23450/133889 blocks (17.5%), 0 events +2026-02-04T19:00:27.263299Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23460/133889 blocks (17.5%), 0 events +2026-02-04T19:00:27.386215Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23470/133889 blocks (17.5%), 0 events +2026-02-04T19:00:27.574313Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23480/133889 blocks (17.5%), 0 events +2026-02-04T19:00:27.774614Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23490/133889 blocks (17.5%), 0 events +2026-02-04T19:00:27.967059Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23500/133889 blocks (17.6%), 0 events +2026-02-04T19:00:28.277245Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23510/133889 blocks (17.6%), 0 events +2026-02-04T19:00:28.402160Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23520/133889 blocks (17.6%), 0 events +2026-02-04T19:00:28.629963Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23530/133889 blocks (17.6%), 0 events +2026-02-04T19:00:28.870544Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23540/133889 blocks (17.6%), 0 events +2026-02-04T19:00:29.015678Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23550/133889 blocks (17.6%), 0 events +2026-02-04T19:00:29.189881Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23560/133889 blocks (17.6%), 0 events +2026-02-04T19:00:29.379739Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23570/133889 blocks (17.6%), 0 events +2026-02-04T19:00:29.577809Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23580/133889 blocks (17.6%), 0 events +2026-02-04T19:00:29.848657Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23590/133889 blocks (17.6%), 0 events +2026-02-04T19:00:29.972600Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23600/133889 blocks (17.6%), 0 events +2026-02-04T19:00:30.242801Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23610/133889 blocks (17.6%), 0 events +2026-02-04T19:00:30.403960Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23620/133889 blocks (17.6%), 0 events +2026-02-04T19:00:30.613856Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23630/133889 blocks (17.6%), 0 events +2026-02-04T19:00:30.865527Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23640/133889 blocks (17.7%), 0 events +2026-02-04T19:00:30.974724Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23650/133889 blocks (17.7%), 0 events +2026-02-04T19:00:31.266725Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23660/133889 blocks (17.7%), 0 events +2026-02-04T19:00:31.423749Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23670/133889 blocks (17.7%), 0 events +2026-02-04T19:00:31.634514Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23680/133889 blocks (17.7%), 0 events +2026-02-04T19:00:31.915514Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23690/133889 blocks (17.7%), 0 events +2026-02-04T19:00:31.973085Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23700/133889 blocks (17.7%), 0 events +2026-02-04T19:00:32.190831Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23710/133889 blocks (17.7%), 0 events +2026-02-04T19:00:32.473411Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23720/133889 blocks (17.7%), 0 events +2026-02-04T19:00:32.580780Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23730/133889 blocks (17.7%), 0 events +2026-02-04T19:00:32.794507Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23740/133889 blocks (17.7%), 0 events +2026-02-04T19:00:33.034665Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23750/133889 blocks (17.7%), 0 events +2026-02-04T19:00:33.206768Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23760/133889 blocks (17.7%), 0 events +2026-02-04T19:00:33.487120Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23770/133889 blocks (17.8%), 0 events +2026-02-04T19:00:33.582504Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23780/133889 blocks (17.8%), 0 events +2026-02-04T19:00:33.796052Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23790/133889 blocks (17.8%), 0 events +2026-02-04T19:00:34.052494Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23800/133889 blocks (17.8%), 0 events +2026-02-04T19:00:34.176765Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23810/133889 blocks (17.8%), 0 events +2026-02-04T19:00:34.419769Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23820/133889 blocks (17.8%), 0 events +2026-02-04T19:00:34.639073Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23830/133889 blocks (17.8%), 0 events +2026-02-04T19:00:34.776305Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23840/133889 blocks (17.8%), 0 events +2026-02-04T19:00:35.099007Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23850/133889 blocks (17.8%), 0 events +2026-02-04T19:00:35.261141Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23860/133889 blocks (17.8%), 0 events +2026-02-04T19:00:35.397939Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23870/133889 blocks (17.8%), 0 events +2026-02-04T19:00:35.667056Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23880/133889 blocks (17.8%), 0 events +2026-02-04T19:00:35.828892Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23890/133889 blocks (17.8%), 0 events +2026-02-04T19:00:35.981044Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23900/133889 blocks (17.8%), 0 events +2026-02-04T19:00:36.179357Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23910/133889 blocks (17.9%), 0 events +2026-02-04T19:00:36.421857Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23920/133889 blocks (17.9%), 0 events +2026-02-04T19:00:36.665827Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23930/133889 blocks (17.9%), 0 events +2026-02-04T19:00:36.846136Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23940/133889 blocks (17.9%), 0 events +2026-02-04T19:00:37.060225Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23950/133889 blocks (17.9%), 0 events +2026-02-04T19:00:37.207936Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23960/133889 blocks (17.9%), 0 events +2026-02-04T19:00:37.399581Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23970/133889 blocks (17.9%), 0 events +2026-02-04T19:00:37.583051Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23980/133889 blocks (17.9%), 0 events +2026-02-04T19:00:37.785226Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23990/133889 blocks (17.9%), 0 events +2026-02-04T19:00:38.035225Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24000/133889 blocks (17.9%), 0 events +2026-02-04T19:00:38.235293Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24010/133889 blocks (17.9%), 0 events +2026-02-04T19:00:38.416382Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24020/133889 blocks (17.9%), 0 events +2026-02-04T19:00:38.609284Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24030/133889 blocks (17.9%), 0 events +2026-02-04T19:00:38.791302Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24040/133889 blocks (18.0%), 0 events +2026-02-04T19:00:39.042500Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24050/133889 blocks (18.0%), 0 events +2026-02-04T19:00:39.253509Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24060/133889 blocks (18.0%), 0 events +2026-02-04T19:00:39.373715Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24070/133889 blocks (18.0%), 0 events +2026-02-04T19:00:39.607200Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24080/133889 blocks (18.0%), 0 events +2026-02-04T19:00:39.815932Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24090/133889 blocks (18.0%), 0 events +2026-02-04T19:00:40.030775Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24100/133889 blocks (18.0%), 0 events +2026-02-04T19:00:40.347159Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24110/133889 blocks (18.0%), 0 events +2026-02-04T19:00:40.384150Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24120/133889 blocks (18.0%), 0 events +2026-02-04T19:00:40.641686Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24130/133889 blocks (18.0%), 0 events +2026-02-04T19:00:40.900284Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24140/133889 blocks (18.0%), 0 events +2026-02-04T19:00:41.049832Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24150/133889 blocks (18.0%), 0 events +2026-02-04T19:00:41.240249Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24160/133889 blocks (18.0%), 0 events +2026-02-04T19:00:41.453844Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24170/133889 blocks (18.1%), 0 events +2026-02-04T19:00:41.595027Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24180/133889 blocks (18.1%), 0 events +2026-02-04T19:00:41.874450Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24190/133889 blocks (18.1%), 0 events +2026-02-04T19:00:42.010537Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24200/133889 blocks (18.1%), 0 events +2026-02-04T19:00:42.261926Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24210/133889 blocks (18.1%), 0 events +2026-02-04T19:00:42.427034Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24220/133889 blocks (18.1%), 0 events +2026-02-04T19:00:42.625064Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24230/133889 blocks (18.1%), 0 events +2026-02-04T19:00:42.777817Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24240/133889 blocks (18.1%), 0 events +2026-02-04T19:00:43.020944Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24250/133889 blocks (18.1%), 0 events +2026-02-04T19:00:43.187981Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24260/133889 blocks (18.1%), 0 events +2026-02-04T19:00:43.490985Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24270/133889 blocks (18.1%), 0 events +2026-02-04T19:00:43.608419Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24280/133889 blocks (18.1%), 0 events +2026-02-04T19:00:43.864176Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24290/133889 blocks (18.1%), 0 events +2026-02-04T19:00:44.039694Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24300/133889 blocks (18.1%), 0 events +2026-02-04T19:00:44.267967Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24310/133889 blocks (18.2%), 0 events +2026-02-04T19:00:44.495742Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24320/133889 blocks (18.2%), 0 events +2026-02-04T19:00:44.585059Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24330/133889 blocks (18.2%), 0 events +2026-02-04T19:00:44.779816Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24340/133889 blocks (18.2%), 0 events +2026-02-04T19:00:45.062352Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24350/133889 blocks (18.2%), 0 events +2026-02-04T19:00:45.250323Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24360/133889 blocks (18.2%), 0 events +2026-02-04T19:00:45.381258Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24370/133889 blocks (18.2%), 0 events +2026-02-04T19:00:45.633238Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24380/133889 blocks (18.2%), 0 events +2026-02-04T19:00:45.782796Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24390/133889 blocks (18.2%), 0 events +2026-02-04T19:00:46.099746Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24400/133889 blocks (18.2%), 0 events +2026-02-04T19:00:46.226094Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24410/133889 blocks (18.2%), 0 events +2026-02-04T19:00:46.360745Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24420/133889 blocks (18.2%), 0 events +2026-02-04T19:00:46.661473Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24430/133889 blocks (18.2%), 0 events +2026-02-04T19:00:46.831928Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24440/133889 blocks (18.3%), 0 events +2026-02-04T19:00:47.025689Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24450/133889 blocks (18.3%), 0 events +2026-02-04T19:00:47.191080Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24460/133889 blocks (18.3%), 0 events +2026-02-04T19:00:47.476486Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24470/133889 blocks (18.3%), 0 events +2026-02-04T19:00:47.640287Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24480/133889 blocks (18.3%), 0 events +2026-02-04T19:00:47.872899Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24490/133889 blocks (18.3%), 0 events +2026-02-04T19:00:48.044387Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24500/133889 blocks (18.3%), 0 events +2026-02-04T19:00:48.227006Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24510/133889 blocks (18.3%), 0 events +2026-02-04T19:00:48.429234Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24520/133889 blocks (18.3%), 0 events +2026-02-04T19:00:48.581893Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24530/133889 blocks (18.3%), 0 events +2026-02-04T19:00:48.792090Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24540/133889 blocks (18.3%), 0 events +2026-02-04T19:00:49.015280Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24550/133889 blocks (18.3%), 0 events +2026-02-04T19:00:49.246953Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24560/133889 blocks (18.3%), 0 events +2026-02-04T19:00:49.452346Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24570/133889 blocks (18.4%), 0 events +2026-02-04T19:00:49.634573Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24580/133889 blocks (18.4%), 0 events +2026-02-04T19:00:49.771561Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24590/133889 blocks (18.4%), 0 events +2026-02-04T19:00:50.020874Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24600/133889 blocks (18.4%), 0 events +2026-02-04T19:00:50.296415Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24610/133889 blocks (18.4%), 0 events +2026-02-04T19:00:50.429069Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24620/133889 blocks (18.4%), 0 events +2026-02-04T19:00:50.626578Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24630/133889 blocks (18.4%), 0 events +2026-02-04T19:00:50.857671Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24640/133889 blocks (18.4%), 0 events +2026-02-04T19:00:51.051373Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24650/133889 blocks (18.4%), 0 events +2026-02-04T19:00:51.196831Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24660/133889 blocks (18.4%), 0 events +2026-02-04T19:00:51.404139Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24670/133889 blocks (18.4%), 0 events +2026-02-04T19:00:51.651882Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24680/133889 blocks (18.4%), 0 events +2026-02-04T19:00:51.836647Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24690/133889 blocks (18.4%), 0 events +2026-02-04T19:00:52.039657Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24700/133889 blocks (18.4%), 0 events +2026-02-04T19:00:52.206948Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24710/133889 blocks (18.5%), 0 events +2026-02-04T19:00:52.404487Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24720/133889 blocks (18.5%), 0 events +2026-02-04T19:00:52.621348Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24730/133889 blocks (18.5%), 0 events +2026-02-04T19:00:52.917614Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24740/133889 blocks (18.5%), 0 events +2026-02-04T19:00:52.970361Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24750/133889 blocks (18.5%), 0 events +2026-02-04T19:00:53.262473Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24760/133889 blocks (18.5%), 0 events +2026-02-04T19:00:53.441319Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24770/133889 blocks (18.5%), 0 events +2026-02-04T19:00:53.588349Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24780/133889 blocks (18.5%), 0 events +2026-02-04T19:00:53.771331Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24790/133889 blocks (18.5%), 0 events +2026-02-04T19:00:54.038395Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24800/133889 blocks (18.5%), 0 events +2026-02-04T19:00:54.499899Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24810/133889 blocks (18.5%), 0 events +2026-02-04T19:00:54.537844Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24820/133889 blocks (18.5%), 0 events +2026-02-04T19:00:54.572690Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24830/133889 blocks (18.5%), 0 events +2026-02-04T19:00:54.812043Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24840/133889 blocks (18.6%), 0 events +2026-02-04T19:00:55.019581Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24850/133889 blocks (18.6%), 0 events +2026-02-04T19:00:55.505641Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24860/133889 blocks (18.6%), 0 events +2026-02-04T19:00:55.545373Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24870/133889 blocks (18.6%), 0 events +2026-02-04T19:00:55.582164Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24880/133889 blocks (18.6%), 0 events +2026-02-04T19:00:55.840239Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24890/133889 blocks (18.6%), 0 events +2026-02-04T19:00:56.062397Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24900/133889 blocks (18.6%), 0 events +2026-02-04T19:00:56.214893Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24910/133889 blocks (18.6%), 0 events +2026-02-04T19:00:56.363732Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24920/133889 blocks (18.6%), 0 events +2026-02-04T19:00:56.638560Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24930/133889 blocks (18.6%), 0 events +2026-02-04T19:00:56.845541Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24940/133889 blocks (18.6%), 0 events +2026-02-04T19:00:57.079344Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24950/133889 blocks (18.6%), 0 events +2026-02-04T19:00:57.221786Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24960/133889 blocks (18.6%), 0 events +2026-02-04T19:00:57.373352Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24970/133889 blocks (18.6%), 0 events +2026-02-04T19:00:57.638572Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24980/133889 blocks (18.7%), 0 events +2026-02-04T19:00:57.767874Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24990/133889 blocks (18.7%), 0 events +2026-02-04T19:00:58.000942Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25000/133889 blocks (18.7%), 0 events +2026-02-04T19:00:58.257843Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25010/133889 blocks (18.7%), 0 events +2026-02-04T19:00:58.462430Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25020/133889 blocks (18.7%), 0 events +2026-02-04T19:00:58.688120Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25030/133889 blocks (18.7%), 0 events +2026-02-04T19:00:58.853122Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25040/133889 blocks (18.7%), 0 events +2026-02-04T19:00:59.003631Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25050/133889 blocks (18.7%), 0 events +2026-02-04T19:00:59.240520Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25060/133889 blocks (18.7%), 0 events +2026-02-04T19:00:59.403241Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25070/133889 blocks (18.7%), 0 events +2026-02-04T19:00:59.588805Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25080/133889 blocks (18.7%), 0 events +2026-02-04T19:00:59.844753Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25090/133889 blocks (18.7%), 0 events +2026-02-04T19:01:00.038937Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25100/133889 blocks (18.7%), 0 events +2026-02-04T19:01:00.256312Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25110/133889 blocks (18.8%), 0 events +2026-02-04T19:01:00.444055Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25120/133889 blocks (18.8%), 0 events +2026-02-04T19:01:00.651550Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25130/133889 blocks (18.8%), 0 events +2026-02-04T19:01:00.849150Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25140/133889 blocks (18.8%), 0 events +2026-02-04T19:01:01.047799Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25150/133889 blocks (18.8%), 0 events +2026-02-04T19:01:01.509972Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25160/133889 blocks (18.8%), 0 events +2026-02-04T19:01:01.556953Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25170/133889 blocks (18.8%), 0 events +2026-02-04T19:01:01.604130Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25180/133889 blocks (18.8%), 0 events +2026-02-04T19:01:02.029542Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25190/133889 blocks (18.8%), 0 events +2026-02-04T19:01:02.087263Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25200/133889 blocks (18.8%), 0 events +2026-02-04T19:01:02.555433Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25210/133889 blocks (18.8%), 0 events +2026-02-04T19:01:02.591602Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25220/133889 blocks (18.8%), 0 events +2026-02-04T19:01:02.647012Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25230/133889 blocks (18.8%), 0 events +2026-02-04T19:01:03.092143Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25240/133889 blocks (18.9%), 0 events +2026-02-04T19:01:03.131702Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25250/133889 blocks (18.9%), 0 events +2026-02-04T19:01:03.570747Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25260/133889 blocks (18.9%), 0 events +2026-02-04T19:01:03.614823Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25270/133889 blocks (18.9%), 0 events +2026-02-04T19:01:03.654157Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25280/133889 blocks (18.9%), 0 events +2026-02-04T19:01:04.125304Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25290/133889 blocks (18.9%), 0 events +2026-02-04T19:01:04.161862Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25300/133889 blocks (18.9%), 0 events +2026-02-04T19:01:04.618801Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25310/133889 blocks (18.9%), 0 events +2026-02-04T19:01:04.656241Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25320/133889 blocks (18.9%), 0 events +2026-02-04T19:01:04.692598Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25330/133889 blocks (18.9%), 0 events +2026-02-04T19:01:05.140761Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25340/133889 blocks (18.9%), 0 events +2026-02-04T19:01:05.177404Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25350/133889 blocks (18.9%), 0 events +2026-02-04T19:01:05.220169Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25360/133889 blocks (18.9%), 0 events +2026-02-04T19:01:05.502321Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25370/133889 blocks (18.9%), 0 events +2026-02-04T19:01:05.565035Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25380/133889 blocks (19.0%), 0 events +2026-02-04T19:01:05.992883Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25390/133889 blocks (19.0%), 0 events +2026-02-04T19:01:06.057608Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25400/133889 blocks (19.0%), 0 events +2026-02-04T19:01:06.205373Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25410/133889 blocks (19.0%), 0 events +2026-02-04T19:01:06.551593Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25420/133889 blocks (19.0%), 0 events +2026-02-04T19:01:06.587003Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25430/133889 blocks (19.0%), 0 events +2026-02-04T19:01:06.846955Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25440/133889 blocks (19.0%), 0 events +2026-02-04T19:01:07.075546Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25450/133889 blocks (19.0%), 0 events +2026-02-04T19:01:07.225530Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25460/133889 blocks (19.0%), 0 events +2026-02-04T19:01:07.440476Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25470/133889 blocks (19.0%), 0 events +2026-02-04T19:01:07.598637Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25480/133889 blocks (19.0%), 0 events +2026-02-04T19:01:07.846724Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25490/133889 blocks (19.0%), 0 events +2026-02-04T19:01:08.091295Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25500/133889 blocks (19.0%), 0 events +2026-02-04T19:01:08.287097Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25510/133889 blocks (19.1%), 0 events +2026-02-04T19:01:08.406995Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25520/133889 blocks (19.1%), 0 events +2026-02-04T19:01:08.651647Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25530/133889 blocks (19.1%), 0 events +2026-02-04T19:01:08.846083Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25540/133889 blocks (19.1%), 0 events +2026-02-04T19:01:09.137546Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25550/133889 blocks (19.1%), 0 events +2026-02-04T19:01:09.181855Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25560/133889 blocks (19.1%), 0 events +2026-02-04T19:01:09.442196Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25570/133889 blocks (19.1%), 0 events +2026-02-04T19:01:09.697562Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25580/133889 blocks (19.1%), 0 events +2026-02-04T19:01:09.863393Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25590/133889 blocks (19.1%), 0 events +2026-02-04T19:01:10.024947Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25600/133889 blocks (19.1%), 0 events +2026-02-04T19:01:10.228879Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25610/133889 blocks (19.1%), 0 events +2026-02-04T19:01:10.462622Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25620/133889 blocks (19.1%), 0 events +2026-02-04T19:01:10.579555Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25630/133889 blocks (19.1%), 0 events +2026-02-04T19:01:10.864931Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25640/133889 blocks (19.1%), 0 events +2026-02-04T19:01:11.043151Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25650/133889 blocks (19.2%), 0 events +2026-02-04T19:01:11.279255Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25660/133889 blocks (19.2%), 0 events +2026-02-04T19:01:11.460120Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25670/133889 blocks (19.2%), 0 events +2026-02-04T19:01:11.614936Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25680/133889 blocks (19.2%), 0 events +2026-02-04T19:01:11.864117Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25690/133889 blocks (19.2%), 0 events +2026-02-04T19:01:11.998132Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25700/133889 blocks (19.2%), 0 events +2026-02-04T19:01:12.313554Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25710/133889 blocks (19.2%), 0 events +2026-02-04T19:01:12.390460Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25720/133889 blocks (19.2%), 0 events +2026-02-04T19:01:12.641060Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25730/133889 blocks (19.2%), 0 events +2026-02-04T19:01:12.846817Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25740/133889 blocks (19.2%), 0 events +2026-02-04T19:01:13.047175Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25750/133889 blocks (19.2%), 0 events +2026-02-04T19:01:13.332717Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25760/133889 blocks (19.2%), 0 events +2026-02-04T19:01:13.376297Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25770/133889 blocks (19.2%), 0 events +2026-02-04T19:01:13.632422Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25780/133889 blocks (19.3%), 0 events +2026-02-04T19:01:13.857690Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25790/133889 blocks (19.3%), 0 events +2026-02-04T19:01:13.981638Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25800/133889 blocks (19.3%), 0 events +2026-02-04T19:01:14.216389Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25810/133889 blocks (19.3%), 0 events +2026-02-04T19:01:14.418216Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25820/133889 blocks (19.3%), 0 events +2026-02-04T19:01:14.668868Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25830/133889 blocks (19.3%), 0 events +2026-02-04T19:01:14.939070Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25840/133889 blocks (19.3%), 0 events +2026-02-04T19:01:14.979082Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25850/133889 blocks (19.3%), 0 events +2026-02-04T19:01:15.200565Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25860/133889 blocks (19.3%), 0 events +2026-02-04T19:01:15.490118Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25870/133889 blocks (19.3%), 0 events +2026-02-04T19:01:15.677297Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25880/133889 blocks (19.3%), 0 events +2026-02-04T19:01:15.999227Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25890/133889 blocks (19.3%), 0 events +2026-02-04T19:01:16.051771Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25900/133889 blocks (19.3%), 0 events +2026-02-04T19:01:16.277511Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25910/133889 blocks (19.4%), 0 events +2026-02-04T19:01:16.512782Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25920/133889 blocks (19.4%), 0 events +2026-02-04T19:01:16.645956Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25930/133889 blocks (19.4%), 0 events +2026-02-04T19:01:16.778053Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25940/133889 blocks (19.4%), 0 events +2026-02-04T19:01:17.040645Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25950/133889 blocks (19.4%), 0 events +2026-02-04T19:01:17.191169Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25960/133889 blocks (19.4%), 0 events +2026-02-04T19:01:17.558131Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25970/133889 blocks (19.4%), 0 events +2026-02-04T19:01:17.598866Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25980/133889 blocks (19.4%), 0 events +2026-02-04T19:01:17.881534Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25990/133889 blocks (19.4%), 0 events +2026-02-04T19:01:18.089985Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26000/133889 blocks (19.4%), 0 events +2026-02-04T19:01:18.240145Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26010/133889 blocks (19.4%), 0 events +2026-02-04T19:01:18.456923Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26020/133889 blocks (19.4%), 0 events +2026-02-04T19:01:18.611730Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26030/133889 blocks (19.4%), 0 events +2026-02-04T19:01:18.785110Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26040/133889 blocks (19.4%), 0 events +2026-02-04T19:01:19.098253Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26050/133889 blocks (19.5%), 0 events +2026-02-04T19:01:19.268664Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26060/133889 blocks (19.5%), 0 events +2026-02-04T19:01:19.391966Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26070/133889 blocks (19.5%), 0 events +2026-02-04T19:01:19.661550Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26080/133889 blocks (19.5%), 0 events +2026-02-04T19:01:19.824243Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26090/133889 blocks (19.5%), 0 events +2026-02-04T19:01:20.042127Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26100/133889 blocks (19.5%), 0 events +2026-02-04T19:01:20.219689Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26110/133889 blocks (19.5%), 0 events +2026-02-04T19:01:20.420069Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26120/133889 blocks (19.5%), 0 events +2026-02-04T19:01:20.712180Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26130/133889 blocks (19.5%), 0 events +2026-02-04T19:01:20.855814Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26140/133889 blocks (19.5%), 0 events +2026-02-04T19:01:21.035450Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26150/133889 blocks (19.5%), 0 events +2026-02-04T19:01:21.251838Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26160/133889 blocks (19.5%), 0 events +2026-02-04T19:01:21.390195Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26170/133889 blocks (19.5%), 0 events +2026-02-04T19:01:21.618957Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26180/133889 blocks (19.6%), 0 events +2026-02-04T19:01:21.822982Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26190/133889 blocks (19.6%), 0 events +2026-02-04T19:01:22.018722Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26200/133889 blocks (19.6%), 0 events +2026-02-04T19:01:22.279181Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26210/133889 blocks (19.6%), 0 events +2026-02-04T19:01:22.420670Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26220/133889 blocks (19.6%), 0 events +2026-02-04T19:01:22.631094Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26230/133889 blocks (19.6%), 0 events +2026-02-04T19:01:22.833377Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26240/133889 blocks (19.6%), 0 events +2026-02-04T19:01:23.015042Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26250/133889 blocks (19.6%), 0 events +2026-02-04T19:01:23.182213Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26260/133889 blocks (19.6%), 0 events +2026-02-04T19:01:23.447679Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26270/133889 blocks (19.6%), 0 events +2026-02-04T19:01:23.652246Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26280/133889 blocks (19.6%), 0 events +2026-02-04T19:01:23.851683Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26290/133889 blocks (19.6%), 0 events +2026-02-04T19:01:24.040083Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26300/133889 blocks (19.6%), 0 events +2026-02-04T19:01:24.340084Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26310/133889 blocks (19.7%), 0 events +2026-02-04T19:01:24.439020Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26320/133889 blocks (19.7%), 0 events +2026-02-04T19:01:24.904134Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26330/133889 blocks (19.7%), 0 events +2026-02-04T19:01:24.958001Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26340/133889 blocks (19.7%), 0 events +2026-02-04T19:01:24.996056Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26350/133889 blocks (19.7%), 0 events +2026-02-04T19:01:25.434871Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26360/133889 blocks (19.7%), 0 events +2026-02-04T19:01:25.481523Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26370/133889 blocks (19.7%), 0 events +2026-02-04T19:01:25.641512Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26380/133889 blocks (19.7%), 0 events +2026-02-04T19:01:25.972603Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26390/133889 blocks (19.7%), 0 events +2026-02-04T19:01:26.022000Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26400/133889 blocks (19.7%), 0 events +2026-02-04T19:01:26.200592Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26410/133889 blocks (19.7%), 0 events +2026-02-04T19:01:26.473177Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26420/133889 blocks (19.7%), 0 events +2026-02-04T19:01:26.646967Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26430/133889 blocks (19.7%), 0 events +2026-02-04T19:01:26.965344Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26440/133889 blocks (19.7%), 0 events +2026-02-04T19:01:27.029707Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26450/133889 blocks (19.8%), 0 events +2026-02-04T19:01:27.228717Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26460/133889 blocks (19.8%), 0 events +2026-02-04T19:01:27.524470Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26470/133889 blocks (19.8%), 0 events +2026-02-04T19:01:27.582766Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26480/133889 blocks (19.8%), 0 events +2026-02-04T19:01:27.840382Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26490/133889 blocks (19.8%), 0 events +2026-02-04T19:01:28.045612Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26500/133889 blocks (19.8%), 0 events +2026-02-04T19:01:28.192342Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26510/133889 blocks (19.8%), 0 events +2026-02-04T19:01:28.580844Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26520/133889 blocks (19.8%), 0 events +2026-02-04T19:01:28.626386Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26530/133889 blocks (19.8%), 0 events +2026-02-04T19:01:28.836281Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26540/133889 blocks (19.8%), 0 events +2026-02-04T19:01:29.097535Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26550/133889 blocks (19.8%), 0 events +2026-02-04T19:01:29.228503Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26560/133889 blocks (19.8%), 0 events +2026-02-04T19:01:29.618534Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26570/133889 blocks (19.8%), 0 events +2026-02-04T19:01:29.660350Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26580/133889 blocks (19.9%), 0 events +2026-02-04T19:01:29.820914Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26590/133889 blocks (19.9%), 0 events +2026-02-04T19:01:30.153268Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26600/133889 blocks (19.9%), 0 events +2026-02-04T19:01:30.193305Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26610/133889 blocks (19.9%), 0 events +2026-02-04T19:01:30.437646Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26620/133889 blocks (19.9%), 0 events +2026-02-04T19:01:30.663735Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26630/133889 blocks (19.9%), 0 events +2026-02-04T19:01:30.868627Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26640/133889 blocks (19.9%), 0 events +2026-02-04T19:01:31.055963Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26650/133889 blocks (19.9%), 0 events +2026-02-04T19:01:31.192416Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26660/133889 blocks (19.9%), 0 events +2026-02-04T19:01:31.464008Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26670/133889 blocks (19.9%), 0 events +2026-02-04T19:01:31.682835Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26680/133889 blocks (19.9%), 0 events +2026-02-04T19:01:31.808880Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26690/133889 blocks (19.9%), 0 events +2026-02-04T19:01:31.990328Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26700/133889 blocks (19.9%), 0 events +2026-02-04T19:01:32.240283Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26710/133889 blocks (19.9%), 0 events +2026-02-04T19:01:32.402628Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26720/133889 blocks (20.0%), 0 events +2026-02-04T19:01:32.730523Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26730/133889 blocks (20.0%), 0 events +2026-02-04T19:01:32.808923Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26740/133889 blocks (20.0%), 0 events +2026-02-04T19:01:33.036070Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26750/133889 blocks (20.0%), 0 events +2026-02-04T19:01:33.287145Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26760/133889 blocks (20.0%), 0 events +2026-02-04T19:01:33.470517Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26770/133889 blocks (20.0%), 0 events +2026-02-04T19:01:33.667156Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26780/133889 blocks (20.0%), 0 events +2026-02-04T19:01:33.838356Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26790/133889 blocks (20.0%), 0 events +2026-02-04T19:01:34.054620Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26800/133889 blocks (20.0%), 0 events +2026-02-04T19:01:34.303583Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26810/133889 blocks (20.0%), 0 events +2026-02-04T19:01:34.416335Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26820/133889 blocks (20.0%), 0 events +2026-02-04T19:01:34.827366Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26830/133889 blocks (20.0%), 0 events +2026-02-04T19:01:34.864571Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26840/133889 blocks (20.0%), 0 events +2026-02-04T19:01:35.047785Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26850/133889 blocks (20.1%), 0 events +2026-02-04T19:01:35.187209Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26860/133889 blocks (20.1%), 0 events +2026-02-04T19:01:35.398767Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26870/133889 blocks (20.1%), 0 events +2026-02-04T19:01:35.620842Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26880/133889 blocks (20.1%), 0 events +2026-02-04T19:01:35.914735Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26890/133889 blocks (20.1%), 0 events +2026-02-04T19:01:36.028386Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26900/133889 blocks (20.1%), 0 events +2026-02-04T19:01:36.183645Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26910/133889 blocks (20.1%), 0 events +2026-02-04T19:01:36.431725Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26920/133889 blocks (20.1%), 0 events +2026-02-04T19:01:36.720892Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26930/133889 blocks (20.1%), 0 events +2026-02-04T19:01:36.772512Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26940/133889 blocks (20.1%), 0 events +2026-02-04T19:01:36.990759Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26950/133889 blocks (20.1%), 0 events +2026-02-04T19:01:37.204380Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26960/133889 blocks (20.1%), 0 events +2026-02-04T19:01:37.494224Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26970/133889 blocks (20.1%), 0 events +2026-02-04T19:01:37.618336Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26980/133889 blocks (20.2%), 0 events +2026-02-04T19:01:37.766633Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26990/133889 blocks (20.2%), 0 events +2026-02-04T19:01:38.009787Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27000/133889 blocks (20.2%), 0 events +2026-02-04T19:01:38.250608Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27010/133889 blocks (20.2%), 0 events +2026-02-04T19:01:38.401376Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27020/133889 blocks (20.2%), 0 events +2026-02-04T19:01:38.571083Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27030/133889 blocks (20.2%), 0 events +2026-02-04T19:01:38.831575Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27040/133889 blocks (20.2%), 0 events +2026-02-04T19:01:39.070280Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27050/133889 blocks (20.2%), 0 events +2026-02-04T19:01:39.239116Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27060/133889 blocks (20.2%), 0 events +2026-02-04T19:01:39.454071Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27070/133889 blocks (20.2%), 0 events +2026-02-04T19:01:39.612614Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27080/133889 blocks (20.2%), 0 events +2026-02-04T19:01:39.870100Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27090/133889 blocks (20.2%), 0 events +2026-02-04T19:01:40.071890Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27100/133889 blocks (20.2%), 0 events +2026-02-04T19:01:40.228096Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27110/133889 blocks (20.2%), 0 events +2026-02-04T19:01:40.390570Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27120/133889 blocks (20.3%), 0 events +2026-02-04T19:01:40.649983Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27130/133889 blocks (20.3%), 0 events +2026-02-04T19:01:40.808471Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27140/133889 blocks (20.3%), 0 events +2026-02-04T19:01:40.993894Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27150/133889 blocks (20.3%), 0 events +2026-02-04T19:01:41.257813Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27160/133889 blocks (20.3%), 0 events +2026-02-04T19:01:41.415479Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27170/133889 blocks (20.3%), 0 events +2026-02-04T19:01:41.673420Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27180/133889 blocks (20.3%), 0 events +2026-02-04T19:01:41.815455Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27190/133889 blocks (20.3%), 0 events +2026-02-04T19:01:41.972979Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27200/133889 blocks (20.3%), 0 events +2026-02-04T19:01:42.228039Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27210/133889 blocks (20.3%), 0 events +2026-02-04T19:01:42.409365Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27220/133889 blocks (20.3%), 0 events +2026-02-04T19:01:42.691269Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27230/133889 blocks (20.3%), 0 events +2026-02-04T19:01:42.823752Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27240/133889 blocks (20.3%), 0 events +2026-02-04T19:01:43.055442Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27250/133889 blocks (20.4%), 0 events +2026-02-04T19:01:43.253946Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27260/133889 blocks (20.4%), 0 events +2026-02-04T19:01:43.457617Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27270/133889 blocks (20.4%), 0 events +2026-02-04T19:01:43.608457Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27280/133889 blocks (20.4%), 0 events +2026-02-04T19:01:43.855252Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27290/133889 blocks (20.4%), 0 events +2026-02-04T19:01:44.002669Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27300/133889 blocks (20.4%), 0 events +2026-02-04T19:01:44.264204Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27310/133889 blocks (20.4%), 0 events +2026-02-04T19:01:44.462938Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27320/133889 blocks (20.4%), 0 events +2026-02-04T19:01:44.570568Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27330/133889 blocks (20.4%), 0 events +2026-02-04T19:01:44.860413Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27340/133889 blocks (20.4%), 0 events +2026-02-04T19:01:45.055380Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27350/133889 blocks (20.4%), 0 events +2026-02-04T19:01:45.311368Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27360/133889 blocks (20.4%), 0 events +2026-02-04T19:01:45.403963Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27370/133889 blocks (20.4%), 0 events +2026-02-04T19:01:45.684735Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27380/133889 blocks (20.4%), 0 events +2026-02-04T19:01:45.872341Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27390/133889 blocks (20.5%), 0 events +2026-02-04T19:01:45.999706Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27400/133889 blocks (20.5%), 0 events +2026-02-04T19:01:46.247030Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27410/133889 blocks (20.5%), 0 events +2026-02-04T19:01:46.433260Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27420/133889 blocks (20.5%), 0 events +2026-02-04T19:01:46.616964Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27430/133889 blocks (20.5%), 0 events +2026-02-04T19:01:46.886061Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27440/133889 blocks (20.5%), 0 events +2026-02-04T19:01:47.006016Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27450/133889 blocks (20.5%), 0 events +2026-02-04T19:01:47.243207Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27460/133889 blocks (20.5%), 0 events +2026-02-04T19:01:47.454600Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27470/133889 blocks (20.5%), 0 events +2026-02-04T19:01:47.611049Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27480/133889 blocks (20.5%), 0 events +2026-02-04T19:01:47.822466Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27490/133889 blocks (20.5%), 0 events +2026-02-04T19:01:47.999266Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27500/133889 blocks (20.5%), 0 events +2026-02-04T19:01:48.196137Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27510/133889 blocks (20.5%), 0 events +2026-02-04T19:01:48.364499Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27520/133889 blocks (20.6%), 0 events +2026-02-04T19:01:48.608606Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27530/133889 blocks (20.6%), 0 events +2026-02-04T19:01:48.771478Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27540/133889 blocks (20.6%), 0 events +2026-02-04T19:01:49.241644Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27550/133889 blocks (20.6%), 0 events +2026-02-04T19:01:49.278386Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27560/133889 blocks (20.6%), 0 events +2026-02-04T19:01:49.383836Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27570/133889 blocks (20.6%), 0 events +2026-02-04T19:01:49.644625Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27580/133889 blocks (20.6%), 0 events +2026-02-04T19:01:49.800688Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27590/133889 blocks (20.6%), 0 events +2026-02-04T19:01:50.061682Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27600/133889 blocks (20.6%), 0 events +2026-02-04T19:01:50.197329Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27610/133889 blocks (20.6%), 0 events +2026-02-04T19:01:50.372441Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27620/133889 blocks (20.6%), 0 events +2026-02-04T19:01:50.645709Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27630/133889 blocks (20.6%), 0 events +2026-02-04T19:01:50.792875Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27640/133889 blocks (20.6%), 0 events +2026-02-04T19:01:50.983320Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27650/133889 blocks (20.7%), 0 events +2026-02-04T19:01:51.268878Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27660/133889 blocks (20.7%), 0 events +2026-02-04T19:01:51.403062Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27670/133889 blocks (20.7%), 0 events +2026-02-04T19:01:51.638095Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27680/133889 blocks (20.7%), 0 events +2026-02-04T19:01:51.803778Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27690/133889 blocks (20.7%), 0 events +2026-02-04T19:01:51.997545Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27700/133889 blocks (20.7%), 0 events +2026-02-04T19:01:52.238225Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27710/133889 blocks (20.7%), 0 events +2026-02-04T19:01:52.424355Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27720/133889 blocks (20.7%), 0 events +2026-02-04T19:01:52.684429Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27730/133889 blocks (20.7%), 0 events +2026-02-04T19:01:52.847850Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27740/133889 blocks (20.7%), 0 events +2026-02-04T19:01:53.055644Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27750/133889 blocks (20.7%), 0 events +2026-02-04T19:01:53.211956Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27760/133889 blocks (20.7%), 0 events +2026-02-04T19:01:53.415702Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27770/133889 blocks (20.7%), 0 events +2026-02-04T19:01:53.702382Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27780/133889 blocks (20.7%), 0 events +2026-02-04T19:01:53.792884Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27790/133889 blocks (20.8%), 0 events +2026-02-04T19:01:53.991687Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27800/133889 blocks (20.8%), 0 events +2026-02-04T19:01:54.258235Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27810/133889 blocks (20.8%), 0 events +2026-02-04T19:01:54.362321Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27820/133889 blocks (20.8%), 0 events +2026-02-04T19:01:54.573124Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27830/133889 blocks (20.8%), 0 events +2026-02-04T19:01:54.784204Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27840/133889 blocks (20.8%), 0 events +2026-02-04T19:01:55.055721Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27850/133889 blocks (20.8%), 0 events +2026-02-04T19:01:55.309359Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27860/133889 blocks (20.8%), 0 events +2026-02-04T19:01:55.407131Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27870/133889 blocks (20.8%), 0 events +2026-02-04T19:01:55.598917Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27880/133889 blocks (20.8%), 0 events +2026-02-04T19:01:55.830957Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27890/133889 blocks (20.8%), 0 events +2026-02-04T19:01:56.011814Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27900/133889 blocks (20.8%), 0 events +2026-02-04T19:01:56.322812Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27910/133889 blocks (20.8%), 0 events +2026-02-04T19:01:56.363826Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27920/133889 blocks (20.9%), 0 events +2026-02-04T19:01:56.597350Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27930/133889 blocks (20.9%), 0 events +2026-02-04T19:01:56.878991Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27940/133889 blocks (20.9%), 0 events +2026-02-04T19:01:57.003357Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27950/133889 blocks (20.9%), 0 events +2026-02-04T19:01:57.230780Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27960/133889 blocks (20.9%), 0 events +2026-02-04T19:01:57.453282Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27970/133889 blocks (20.9%), 0 events +2026-02-04T19:01:57.618419Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27980/133889 blocks (20.9%), 0 events +2026-02-04T19:01:57.772119Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27990/133889 blocks (20.9%), 0 events +2026-02-04T19:01:58.018711Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28000/133889 blocks (20.9%), 0 events +2026-02-04T19:01:58.219417Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28010/133889 blocks (20.9%), 0 events +2026-02-04T19:01:58.466329Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28020/133889 blocks (20.9%), 0 events +2026-02-04T19:01:58.623024Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28030/133889 blocks (20.9%), 0 events +2026-02-04T19:01:58.797938Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28040/133889 blocks (20.9%), 0 events +2026-02-04T19:01:59.055030Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28050/133889 blocks (20.9%), 0 events +2026-02-04T19:01:59.206865Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28060/133889 blocks (21.0%), 0 events +2026-02-04T19:01:59.378204Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28070/133889 blocks (21.0%), 0 events +2026-02-04T19:01:59.661337Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28080/133889 blocks (21.0%), 0 events +2026-02-04T19:01:59.840354Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28090/133889 blocks (21.0%), 0 events +2026-02-04T19:02:00.030388Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28100/133889 blocks (21.0%), 0 events +2026-02-04T19:02:00.205920Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28110/133889 blocks (21.0%), 0 events +2026-02-04T19:02:00.367530Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28120/133889 blocks (21.0%), 0 events +2026-02-04T19:02:00.631839Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28130/133889 blocks (21.0%), 0 events +2026-02-04T19:02:00.801557Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28140/133889 blocks (21.0%), 0 events +2026-02-04T19:02:01.078774Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28150/133889 blocks (21.0%), 0 events +2026-02-04T19:02:01.168311Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28160/133889 blocks (21.0%), 0 events +2026-02-04T19:02:01.436853Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28170/133889 blocks (21.0%), 0 events +2026-02-04T19:02:01.638817Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28180/133889 blocks (21.0%), 0 events +2026-02-04T19:02:01.819031Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28190/133889 blocks (21.1%), 0 events +2026-02-04T19:02:02.089337Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28200/133889 blocks (21.1%), 0 events +2026-02-04T19:02:02.199380Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28210/133889 blocks (21.1%), 0 events +2026-02-04T19:02:02.390205Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28220/133889 blocks (21.1%), 0 events +2026-02-04T19:02:02.643465Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28230/133889 blocks (21.1%), 0 events +2026-02-04T19:02:02.864654Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28240/133889 blocks (21.1%), 0 events +2026-02-04T19:02:02.997372Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28250/133889 blocks (21.1%), 0 events +2026-02-04T19:02:03.170362Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28260/133889 blocks (21.1%), 0 events +2026-02-04T19:02:03.445872Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28270/133889 blocks (21.1%), 0 events +2026-02-04T19:02:03.702513Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28280/133889 blocks (21.1%), 0 events +2026-02-04T19:02:03.866249Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28290/133889 blocks (21.1%), 0 events +2026-02-04T19:02:04.063944Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28300/133889 blocks (21.1%), 0 events +2026-02-04T19:02:04.231709Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28310/133889 blocks (21.1%), 0 events +2026-02-04T19:02:04.378331Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28320/133889 blocks (21.2%), 0 events +2026-02-04T19:02:04.579460Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28330/133889 blocks (21.2%), 0 events +2026-02-04T19:02:04.797606Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28340/133889 blocks (21.2%), 0 events +2026-02-04T19:02:05.059811Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28350/133889 blocks (21.2%), 0 events +2026-02-04T19:02:05.294149Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28360/133889 blocks (21.2%), 0 events +2026-02-04T19:02:05.375796Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28370/133889 blocks (21.2%), 0 events +2026-02-04T19:02:05.613765Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28380/133889 blocks (21.2%), 0 events +2026-02-04T19:02:05.857386Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28390/133889 blocks (21.2%), 0 events +2026-02-04T19:02:05.973859Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28400/133889 blocks (21.2%), 0 events +2026-02-04T19:02:06.314823Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28410/133889 blocks (21.2%), 0 events +2026-02-04T19:02:06.394831Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28420/133889 blocks (21.2%), 0 events +2026-02-04T19:02:06.580033Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28430/133889 blocks (21.2%), 0 events +2026-02-04T19:02:06.844401Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28440/133889 blocks (21.2%), 0 events +2026-02-04T19:02:06.989619Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28450/133889 blocks (21.2%), 0 events +2026-02-04T19:02:07.202434Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28460/133889 blocks (21.3%), 0 events +2026-02-04T19:02:07.393043Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28470/133889 blocks (21.3%), 0 events +2026-02-04T19:02:07.573931Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28480/133889 blocks (21.3%), 0 events +2026-02-04T19:02:07.890863Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28490/133889 blocks (21.3%), 0 events +2026-02-04T19:02:07.986059Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28500/133889 blocks (21.3%), 0 events +2026-02-04T19:02:08.231935Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28510/133889 blocks (21.3%), 0 events +2026-02-04T19:02:08.414710Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28520/133889 blocks (21.3%), 0 events +2026-02-04T19:02:08.642976Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28530/133889 blocks (21.3%), 0 events +2026-02-04T19:02:08.758870Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28540/133889 blocks (21.3%), 0 events +2026-02-04T19:02:09.029417Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28550/133889 blocks (21.3%), 0 events +2026-02-04T19:02:09.218347Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28560/133889 blocks (21.3%), 0 events +2026-02-04T19:02:09.467172Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28570/133889 blocks (21.3%), 0 events +2026-02-04T19:02:09.586031Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28580/133889 blocks (21.3%), 0 events +2026-02-04T19:02:09.822798Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28590/133889 blocks (21.4%), 0 events +2026-02-04T19:02:10.009071Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28600/133889 blocks (21.4%), 0 events +2026-02-04T19:02:10.184175Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28610/133889 blocks (21.4%), 0 events +2026-02-04T19:02:10.510582Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28620/133889 blocks (21.4%), 0 events +2026-02-04T19:02:10.614793Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28630/133889 blocks (21.4%), 0 events +2026-02-04T19:02:10.825796Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28640/133889 blocks (21.4%), 0 events +2026-02-04T19:02:11.040634Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28650/133889 blocks (21.4%), 0 events +2026-02-04T19:02:11.238509Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28660/133889 blocks (21.4%), 0 events +2026-02-04T19:02:11.393827Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28670/133889 blocks (21.4%), 0 events +2026-02-04T19:02:11.612142Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28680/133889 blocks (21.4%), 0 events +2026-02-04T19:02:11.838187Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28690/133889 blocks (21.4%), 0 events +2026-02-04T19:02:12.086614Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28700/133889 blocks (21.4%), 0 events +2026-02-04T19:02:12.265117Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28710/133889 blocks (21.4%), 0 events +2026-02-04T19:02:12.396965Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28720/133889 blocks (21.5%), 0 events +2026-02-04T19:02:12.607599Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28730/133889 blocks (21.5%), 0 events +2026-02-04T19:02:12.799504Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28740/133889 blocks (21.5%), 0 events +2026-02-04T19:02:13.098340Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28750/133889 blocks (21.5%), 0 events +2026-02-04T19:02:13.176399Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28760/133889 blocks (21.5%), 0 events +2026-02-04T19:02:13.417914Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28770/133889 blocks (21.5%), 0 events +2026-02-04T19:02:13.655944Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28780/133889 blocks (21.5%), 0 events +2026-02-04T19:02:13.829936Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28790/133889 blocks (21.5%), 0 events +2026-02-04T19:02:13.978056Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28800/133889 blocks (21.5%), 0 events +2026-02-04T19:02:14.247001Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28810/133889 blocks (21.5%), 0 events +2026-02-04T19:02:14.457378Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28820/133889 blocks (21.5%), 0 events +2026-02-04T19:02:14.705162Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28830/133889 blocks (21.5%), 0 events +2026-02-04T19:02:14.811561Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28840/133889 blocks (21.5%), 0 events +2026-02-04T19:02:15.045240Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28850/133889 blocks (21.5%), 0 events +2026-02-04T19:02:15.234032Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28860/133889 blocks (21.6%), 0 events +2026-02-04T19:02:15.399771Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28870/133889 blocks (21.6%), 0 events +2026-02-04T19:02:15.752214Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28880/133889 blocks (21.6%), 0 events +2026-02-04T19:02:15.790660Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28890/133889 blocks (21.6%), 0 events +2026-02-04T19:02:15.987773Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28900/133889 blocks (21.6%), 0 events +2026-02-04T19:02:16.277932Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28910/133889 blocks (21.6%), 0 events +2026-02-04T19:02:16.406259Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28920/133889 blocks (21.6%), 0 events +2026-02-04T19:02:16.568487Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28930/133889 blocks (21.6%), 0 events +2026-02-04T19:02:16.857713Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28940/133889 blocks (21.6%), 0 events +2026-02-04T19:02:17.002111Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28950/133889 blocks (21.6%), 0 events +2026-02-04T19:02:17.291660Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28960/133889 blocks (21.6%), 0 events +2026-02-04T19:02:17.417597Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28970/133889 blocks (21.6%), 0 events +2026-02-04T19:02:17.630889Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28980/133889 blocks (21.6%), 0 events +2026-02-04T19:02:17.848111Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28990/133889 blocks (21.7%), 0 events +2026-02-04T19:02:17.980873Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29000/133889 blocks (21.7%), 0 events +2026-02-04T19:02:18.174950Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29010/133889 blocks (21.7%), 0 events +2026-02-04T19:02:18.457301Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29020/133889 blocks (21.7%), 0 events +2026-02-04T19:02:18.638458Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29030/133889 blocks (21.7%), 0 events +2026-02-04T19:02:18.898420Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29040/133889 blocks (21.7%), 0 events +2026-02-04T19:02:19.054136Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29050/133889 blocks (21.7%), 0 events +2026-02-04T19:02:19.217679Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29060/133889 blocks (21.7%), 0 events +2026-02-04T19:02:19.432977Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29070/133889 blocks (21.7%), 0 events +2026-02-04T19:02:19.641619Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29080/133889 blocks (21.7%), 0 events +2026-02-04T19:02:19.914026Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29090/133889 blocks (21.7%), 0 events +2026-02-04T19:02:19.971624Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29100/133889 blocks (21.7%), 0 events +2026-02-04T19:02:20.205132Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29110/133889 blocks (21.7%), 0 events +2026-02-04T19:02:20.481565Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29120/133889 blocks (21.7%), 0 events +2026-02-04T19:02:20.616627Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29130/133889 blocks (21.8%), 0 events +2026-02-04T19:02:20.830442Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29140/133889 blocks (21.8%), 0 events +2026-02-04T19:02:21.032767Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29150/133889 blocks (21.8%), 0 events +2026-02-04T19:02:21.181109Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29160/133889 blocks (21.8%), 0 events +2026-02-04T19:02:21.372996Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29170/133889 blocks (21.8%), 0 events +2026-02-04T19:02:21.646530Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29180/133889 blocks (21.8%), 0 events +2026-02-04T19:02:21.760688Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29190/133889 blocks (21.8%), 0 events +2026-02-04T19:02:22.058932Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29200/133889 blocks (21.8%), 0 events +2026-02-04T19:02:22.229304Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29210/133889 blocks (21.8%), 0 events +2026-02-04T19:02:22.386384Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29220/133889 blocks (21.8%), 0 events +2026-02-04T19:02:22.572011Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29230/133889 blocks (21.8%), 0 events +2026-02-04T19:02:22.770198Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29240/133889 blocks (21.8%), 0 events +2026-02-04T19:02:23.092443Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29250/133889 blocks (21.8%), 0 events +2026-02-04T19:02:23.174963Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29260/133889 blocks (21.9%), 0 events +2026-02-04T19:02:23.371581Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29270/133889 blocks (21.9%), 0 events +2026-02-04T19:02:23.617346Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29280/133889 blocks (21.9%), 0 events +2026-02-04T19:02:23.853115Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29290/133889 blocks (21.9%), 0 events +2026-02-04T19:02:24.108776Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29300/133889 blocks (21.9%), 0 events +2026-02-04T19:02:24.218663Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29310/133889 blocks (21.9%), 0 events +2026-02-04T19:02:24.439458Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29320/133889 blocks (21.9%), 0 events +2026-02-04T19:02:24.665260Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29330/133889 blocks (21.9%), 0 events +2026-02-04T19:02:24.812990Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29340/133889 blocks (21.9%), 0 events +2026-02-04T19:02:25.064772Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29350/133889 blocks (21.9%), 0 events +2026-02-04T19:02:25.228325Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29360/133889 blocks (21.9%), 0 events +2026-02-04T19:02:25.388878Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29370/133889 blocks (21.9%), 0 events +2026-02-04T19:02:25.682165Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29380/133889 blocks (21.9%), 0 events +2026-02-04T19:02:25.831268Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29390/133889 blocks (22.0%), 0 events +2026-02-04T19:02:25.981054Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29400/133889 blocks (22.0%), 0 events +2026-02-04T19:02:26.240603Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29410/133889 blocks (22.0%), 0 events +2026-02-04T19:02:26.370983Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29420/133889 blocks (22.0%), 0 events +2026-02-04T19:02:26.585962Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29430/133889 blocks (22.0%), 0 events +2026-02-04T19:02:26.776010Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29440/133889 blocks (22.0%), 0 events +2026-02-04T19:02:26.999141Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29450/133889 blocks (22.0%), 0 events +2026-02-04T19:02:27.289719Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29460/133889 blocks (22.0%), 0 events +2026-02-04T19:02:27.401940Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29470/133889 blocks (22.0%), 0 events +2026-02-04T19:02:27.629941Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29480/133889 blocks (22.0%), 0 events +2026-02-04T19:02:27.862958Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29490/133889 blocks (22.0%), 0 events +2026-02-04T19:02:28.043243Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29500/133889 blocks (22.0%), 0 events +2026-02-04T19:02:28.176395Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29510/133889 blocks (22.0%), 0 events +2026-02-04T19:02:28.427161Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29520/133889 blocks (22.0%), 0 events +2026-02-04T19:02:28.640400Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29530/133889 blocks (22.1%), 0 events +2026-02-04T19:02:28.861543Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29540/133889 blocks (22.1%), 0 events +2026-02-04T19:02:29.031505Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29550/133889 blocks (22.1%), 0 events +2026-02-04T19:02:29.245022Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29560/133889 blocks (22.1%), 0 events +2026-02-04T19:02:29.465357Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29570/133889 blocks (22.1%), 0 events +2026-02-04T19:02:29.654776Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29580/133889 blocks (22.1%), 0 events +2026-02-04T19:02:29.909396Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29590/133889 blocks (22.1%), 0 events +2026-02-04T19:02:30.056675Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29600/133889 blocks (22.1%), 0 events +2026-02-04T19:02:30.194962Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29610/133889 blocks (22.1%), 0 events +2026-02-04T19:02:30.432129Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29620/133889 blocks (22.1%), 0 events +2026-02-04T19:02:30.648686Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29630/133889 blocks (22.1%), 0 events +2026-02-04T19:02:30.830991Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29640/133889 blocks (22.1%), 0 events +2026-02-04T19:02:31.012320Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29650/133889 blocks (22.1%), 0 events +2026-02-04T19:02:31.254042Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29660/133889 blocks (22.2%), 0 events +2026-02-04T19:02:31.449011Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29670/133889 blocks (22.2%), 0 events +2026-02-04T19:02:31.578678Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29680/133889 blocks (22.2%), 0 events +2026-02-04T19:02:31.844862Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29690/133889 blocks (22.2%), 0 events +2026-02-04T19:02:32.012069Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29700/133889 blocks (22.2%), 0 events +2026-02-04T19:02:32.199945Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29710/133889 blocks (22.2%), 0 events +2026-02-04T19:02:32.531054Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29720/133889 blocks (22.2%), 0 events +2026-02-04T19:02:32.571960Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29730/133889 blocks (22.2%), 0 events +2026-02-04T19:02:32.824055Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29740/133889 blocks (22.2%), 0 events +2026-02-04T19:02:33.057175Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29750/133889 blocks (22.2%), 0 events +2026-02-04T19:02:33.188161Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29760/133889 blocks (22.2%), 0 events +2026-02-04T19:02:33.446679Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29770/133889 blocks (22.2%), 0 events +2026-02-04T19:02:33.627527Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29780/133889 blocks (22.2%), 0 events +2026-02-04T19:02:33.779769Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29790/133889 blocks (22.2%), 0 events +2026-02-04T19:02:34.070865Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29800/133889 blocks (22.3%), 0 events +2026-02-04T19:02:34.173608Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29810/133889 blocks (22.3%), 0 events +2026-02-04T19:02:34.459322Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29820/133889 blocks (22.3%), 0 events +2026-02-04T19:02:34.648212Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29830/133889 blocks (22.3%), 0 events +2026-02-04T19:02:34.827173Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29840/133889 blocks (22.3%), 0 events +2026-02-04T19:02:35.027372Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29850/133889 blocks (22.3%), 0 events +2026-02-04T19:02:35.260283Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29860/133889 blocks (22.3%), 0 events +2026-02-04T19:02:35.411739Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29870/133889 blocks (22.3%), 0 events +2026-02-04T19:02:35.640778Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29880/133889 blocks (22.3%), 0 events +2026-02-04T19:02:35.869245Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29890/133889 blocks (22.3%), 0 events +2026-02-04T19:02:36.041166Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29900/133889 blocks (22.3%), 0 events +2026-02-04T19:02:36.217301Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29910/133889 blocks (22.3%), 0 events +2026-02-04T19:02:36.374752Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29920/133889 blocks (22.3%), 0 events +2026-02-04T19:02:36.690745Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29930/133889 blocks (22.4%), 0 events +2026-02-04T19:02:36.835422Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29940/133889 blocks (22.4%), 0 events +2026-02-04T19:02:37.035571Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29950/133889 blocks (22.4%), 0 events +2026-02-04T19:02:37.248343Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29960/133889 blocks (22.4%), 0 events +2026-02-04T19:02:37.404541Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29970/133889 blocks (22.4%), 0 events +2026-02-04T19:02:37.587981Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29980/133889 blocks (22.4%), 0 events +2026-02-04T19:02:37.778855Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29990/133889 blocks (22.4%), 0 events +2026-02-04T19:02:37.975379Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30000/133889 blocks (22.4%), 0 events +2026-02-04T19:02:38.306228Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30010/133889 blocks (22.4%), 0 events +2026-02-04T19:02:38.392775Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30020/133889 blocks (22.4%), 0 events +2026-02-04T19:02:38.642053Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30030/133889 blocks (22.4%), 0 events +2026-02-04T19:02:38.820005Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30040/133889 blocks (22.4%), 0 events +2026-02-04T19:02:38.980891Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30050/133889 blocks (22.4%), 0 events +2026-02-04T19:02:39.206807Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30060/133889 blocks (22.5%), 0 events +2026-02-04T19:02:39.406275Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30070/133889 blocks (22.5%), 0 events +2026-02-04T19:02:39.626430Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30080/133889 blocks (22.5%), 0 events +2026-02-04T19:02:39.865819Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30090/133889 blocks (22.5%), 0 events +2026-02-04T19:02:40.064079Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30100/133889 blocks (22.5%), 0 events +2026-02-04T19:02:40.213910Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30110/133889 blocks (22.5%), 0 events +2026-02-04T19:02:40.403720Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30120/133889 blocks (22.5%), 0 events +2026-02-04T19:02:40.630917Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30130/133889 blocks (22.5%), 0 events +2026-02-04T19:02:40.923456Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30140/133889 blocks (22.5%), 0 events +2026-02-04T19:02:40.973513Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30150/133889 blocks (22.5%), 0 events +2026-02-04T19:02:41.213264Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30160/133889 blocks (22.5%), 0 events +2026-02-04T19:02:41.452053Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30170/133889 blocks (22.5%), 0 events +2026-02-04T19:02:41.668915Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30180/133889 blocks (22.5%), 0 events +2026-02-04T19:02:41.840930Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30190/133889 blocks (22.5%), 0 events +2026-02-04T19:02:41.964042Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30200/133889 blocks (22.6%), 0 events +2026-02-04T19:02:42.224291Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30210/133889 blocks (22.6%), 0 events +2026-02-04T19:02:42.489818Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30220/133889 blocks (22.6%), 0 events +2026-02-04T19:02:42.683776Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30230/133889 blocks (22.6%), 0 events +2026-02-04T19:02:42.833217Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30240/133889 blocks (22.6%), 0 events +2026-02-04T19:02:43.059523Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30250/133889 blocks (22.6%), 0 events +2026-02-04T19:02:43.215893Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30260/133889 blocks (22.6%), 0 events +2026-02-04T19:02:43.504412Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30270/133889 blocks (22.6%), 0 events +2026-02-04T19:02:43.566190Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30280/133889 blocks (22.6%), 0 events +2026-02-04T19:02:43.827755Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30290/133889 blocks (22.6%), 0 events +2026-02-04T19:02:44.063774Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30300/133889 blocks (22.6%), 0 events +2026-02-04T19:02:44.166381Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30310/133889 blocks (22.6%), 0 events +2026-02-04T19:02:44.460805Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30320/133889 blocks (22.6%), 0 events +2026-02-04T19:02:44.648532Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30330/133889 blocks (22.7%), 0 events +2026-02-04T19:02:44.813842Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30340/133889 blocks (22.7%), 0 events +2026-02-04T19:02:45.109585Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30350/133889 blocks (22.7%), 0 events +2026-02-04T19:02:45.193450Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30360/133889 blocks (22.7%), 0 events +2026-02-04T19:02:45.420347Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30370/133889 blocks (22.7%), 0 events +2026-02-04T19:02:45.634057Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30380/133889 blocks (22.7%), 0 events +2026-02-04T19:02:45.778246Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30390/133889 blocks (22.7%), 0 events +2026-02-04T19:02:46.126089Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30400/133889 blocks (22.7%), 0 events +2026-02-04T19:02:46.161849Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30410/133889 blocks (22.7%), 0 events +2026-02-04T19:02:46.379909Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30420/133889 blocks (22.7%), 0 events +2026-02-04T19:02:46.650061Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30430/133889 blocks (22.7%), 0 events +2026-02-04T19:02:46.847605Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30440/133889 blocks (22.7%), 0 events +2026-02-04T19:02:46.996496Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30450/133889 blocks (22.7%), 0 events +2026-02-04T19:02:47.204868Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30460/133889 blocks (22.7%), 0 events +2026-02-04T19:02:47.432440Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30470/133889 blocks (22.8%), 0 events +2026-02-04T19:02:47.699253Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30480/133889 blocks (22.8%), 0 events +2026-02-04T19:02:47.926862Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30490/133889 blocks (22.8%), 0 events +2026-02-04T19:02:47.965276Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30500/133889 blocks (22.8%), 0 events +2026-02-04T19:02:48.267074Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30510/133889 blocks (22.8%), 0 events +2026-02-04T19:02:48.458943Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30520/133889 blocks (22.8%), 0 events +2026-02-04T19:02:48.641989Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30530/133889 blocks (22.8%), 0 events +2026-02-04T19:02:48.807160Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30540/133889 blocks (22.8%), 0 events +2026-02-04T19:02:48.982779Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30550/133889 blocks (22.8%), 0 events +2026-02-04T19:02:49.272970Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30560/133889 blocks (22.8%), 0 events +2026-02-04T19:02:49.527732Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30570/133889 blocks (22.8%), 0 events +2026-02-04T19:02:49.579033Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30580/133889 blocks (22.8%), 0 events +2026-02-04T19:02:49.828745Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30590/133889 blocks (22.8%), 0 events +2026-02-04T19:02:50.061447Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30600/133889 blocks (22.9%), 0 events +2026-02-04T19:02:50.217890Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30610/133889 blocks (22.9%), 0 events +2026-02-04T19:02:50.405572Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30620/133889 blocks (22.9%), 0 events +2026-02-04T19:02:50.663472Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30630/133889 blocks (22.9%), 0 events +2026-02-04T19:02:50.883189Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30640/133889 blocks (22.9%), 0 events +2026-02-04T19:02:51.034197Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30650/133889 blocks (22.9%), 0 events +2026-02-04T19:02:51.175407Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30660/133889 blocks (22.9%), 0 events +2026-02-04T19:02:51.400090Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30670/133889 blocks (22.9%), 0 events +2026-02-04T19:02:51.603139Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30680/133889 blocks (22.9%), 0 events +2026-02-04T19:02:51.896121Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30690/133889 blocks (22.9%), 0 events +2026-02-04T19:02:52.027538Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30700/133889 blocks (22.9%), 0 events +2026-02-04T19:02:52.452813Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30710/133889 blocks (22.9%), 0 events +2026-02-04T19:02:52.492335Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30720/133889 blocks (22.9%), 0 events +2026-02-04T19:02:52.588558Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30730/133889 blocks (23.0%), 0 events +2026-02-04T19:02:52.810060Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30740/133889 blocks (23.0%), 0 events +2026-02-04T19:02:52.976198Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30750/133889 blocks (23.0%), 0 events +2026-02-04T19:02:53.232056Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30760/133889 blocks (23.0%), 0 events +2026-02-04T19:02:53.360874Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30770/133889 blocks (23.0%), 0 events +2026-02-04T19:02:53.659538Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30780/133889 blocks (23.0%), 0 events +2026-02-04T19:02:53.780081Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30790/133889 blocks (23.0%), 0 events +2026-02-04T19:02:54.046354Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30800/133889 blocks (23.0%), 0 events +2026-02-04T19:02:54.220123Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30810/133889 blocks (23.0%), 0 events +2026-02-04T19:02:54.518194Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30820/133889 blocks (23.0%), 0 events +2026-02-04T19:02:54.556390Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30830/133889 blocks (23.0%), 0 events +2026-02-04T19:02:54.846538Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30840/133889 blocks (23.0%), 0 events +2026-02-04T19:02:55.078413Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30850/133889 blocks (23.0%), 0 events +2026-02-04T19:02:55.211746Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30860/133889 blocks (23.0%), 0 events +2026-02-04T19:02:55.399451Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30870/133889 blocks (23.1%), 0 events +2026-02-04T19:02:55.651410Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30880/133889 blocks (23.1%), 0 events +2026-02-04T19:02:55.861198Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30890/133889 blocks (23.1%), 0 events +2026-02-04T19:02:56.131132Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30900/133889 blocks (23.1%), 0 events +2026-02-04T19:02:56.172973Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30910/133889 blocks (23.1%), 0 events +2026-02-04T19:02:56.416192Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30920/133889 blocks (23.1%), 0 events +2026-02-04T19:02:56.643761Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30930/133889 blocks (23.1%), 0 events +2026-02-04T19:02:56.867724Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30940/133889 blocks (23.1%), 0 events +2026-02-04T19:02:57.033436Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30950/133889 blocks (23.1%), 0 events +2026-02-04T19:02:57.255881Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30960/133889 blocks (23.1%), 0 events +2026-02-04T19:02:57.442471Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30970/133889 blocks (23.1%), 0 events +2026-02-04T19:02:57.690980Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30980/133889 blocks (23.1%), 0 events +2026-02-04T19:02:57.808679Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30990/133889 blocks (23.1%), 0 events +2026-02-04T19:02:58.032459Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31000/133889 blocks (23.2%), 0 events +2026-02-04T19:02:58.244478Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31010/133889 blocks (23.2%), 0 events +2026-02-04T19:02:58.445504Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31020/133889 blocks (23.2%), 0 events +2026-02-04T19:02:58.739739Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31030/133889 blocks (23.2%), 0 events +2026-02-04T19:02:58.778296Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31040/133889 blocks (23.2%), 0 events +2026-02-04T19:02:59.061808Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31050/133889 blocks (23.2%), 0 events +2026-02-04T19:02:59.265573Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31060/133889 blocks (23.2%), 0 events +2026-02-04T19:02:59.375674Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31070/133889 blocks (23.2%), 0 events +2026-02-04T19:02:59.574771Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31080/133889 blocks (23.2%), 0 events +2026-02-04T19:02:59.799922Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31090/133889 blocks (23.2%), 0 events +2026-02-04T19:02:59.998485Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31100/133889 blocks (23.2%), 0 events +2026-02-04T19:03:00.188647Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31110/133889 blocks (23.2%), 0 events +2026-02-04T19:03:00.432810Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31120/133889 blocks (23.2%), 0 events +2026-02-04T19:03:00.659764Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31130/133889 blocks (23.3%), 0 events +2026-02-04T19:03:00.866965Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31140/133889 blocks (23.3%), 0 events +2026-02-04T19:03:01.033609Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31150/133889 blocks (23.3%), 0 events +2026-02-04T19:03:01.225553Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31160/133889 blocks (23.3%), 0 events +2026-02-04T19:03:01.419631Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31170/133889 blocks (23.3%), 0 events +2026-02-04T19:03:01.617484Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31180/133889 blocks (23.3%), 0 events +2026-02-04T19:03:01.856095Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31190/133889 blocks (23.3%), 0 events +2026-02-04T19:03:02.000554Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31200/133889 blocks (23.3%), 0 events +2026-02-04T19:03:02.248654Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31210/133889 blocks (23.3%), 0 events +2026-02-04T19:03:02.460991Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31220/133889 blocks (23.3%), 0 events +2026-02-04T19:03:02.629286Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31230/133889 blocks (23.3%), 0 events +2026-02-04T19:03:02.783951Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31240/133889 blocks (23.3%), 0 events +2026-02-04T19:03:03.004252Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31250/133889 blocks (23.3%), 0 events +2026-02-04T19:03:03.192225Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31260/133889 blocks (23.3%), 0 events +2026-02-04T19:03:03.465912Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31270/133889 blocks (23.4%), 0 events +2026-02-04T19:03:03.611571Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31280/133889 blocks (23.4%), 0 events +2026-02-04T19:03:03.860344Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31290/133889 blocks (23.4%), 0 events +2026-02-04T19:03:03.999132Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31300/133889 blocks (23.4%), 0 events +2026-02-04T19:03:04.225338Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31310/133889 blocks (23.4%), 0 events +2026-02-04T19:03:04.476374Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31320/133889 blocks (23.4%), 0 events +2026-02-04T19:03:04.578135Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31330/133889 blocks (23.4%), 0 events +2026-02-04T19:03:04.841668Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31340/133889 blocks (23.4%), 0 events +2026-02-04T19:03:05.034397Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31350/133889 blocks (23.4%), 0 events +2026-02-04T19:03:05.230829Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31360/133889 blocks (23.4%), 0 events +2026-02-04T19:03:05.402916Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31370/133889 blocks (23.4%), 0 events +2026-02-04T19:03:05.807427Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31380/133889 blocks (23.4%), 0 events +2026-02-04T19:03:05.844750Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31390/133889 blocks (23.4%), 0 events +2026-02-04T19:03:06.094285Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31400/133889 blocks (23.5%), 0 events +2026-02-04T19:03:06.186442Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31410/133889 blocks (23.5%), 0 events +2026-02-04T19:03:06.437486Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31420/133889 blocks (23.5%), 0 events +2026-02-04T19:03:06.602779Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31430/133889 blocks (23.5%), 0 events +2026-02-04T19:03:06.773156Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31440/133889 blocks (23.5%), 0 events +2026-02-04T19:03:06.984498Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31450/133889 blocks (23.5%), 0 events +2026-02-04T19:03:07.253159Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31460/133889 blocks (23.5%), 0 events +2026-02-04T19:03:07.412513Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31470/133889 blocks (23.5%), 0 events +2026-02-04T19:03:07.667550Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31480/133889 blocks (23.5%), 0 events +2026-02-04T19:03:07.780128Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31490/133889 blocks (23.5%), 0 events +2026-02-04T19:03:08.038528Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31500/133889 blocks (23.5%), 0 events +2026-02-04T19:03:08.177316Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31510/133889 blocks (23.5%), 0 events +2026-02-04T19:03:08.414584Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31520/133889 blocks (23.5%), 0 events +2026-02-04T19:03:08.574592Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31530/133889 blocks (23.5%), 0 events +2026-02-04T19:03:08.857668Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31540/133889 blocks (23.6%), 0 events +2026-02-04T19:03:09.004694Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31550/133889 blocks (23.6%), 0 events +2026-02-04T19:03:09.263571Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31560/133889 blocks (23.6%), 0 events +2026-02-04T19:03:09.407998Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31570/133889 blocks (23.6%), 0 events +2026-02-04T19:03:09.613948Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31580/133889 blocks (23.6%), 0 events +2026-02-04T19:03:09.813244Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31590/133889 blocks (23.6%), 0 events +2026-02-04T19:03:10.037207Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31600/133889 blocks (23.6%), 0 events +2026-02-04T19:03:10.276618Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31610/133889 blocks (23.6%), 0 events +2026-02-04T19:03:10.433006Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31620/133889 blocks (23.6%), 0 events +2026-02-04T19:03:10.585764Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31630/133889 blocks (23.6%), 0 events +2026-02-04T19:03:10.806760Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31640/133889 blocks (23.6%), 0 events +2026-02-04T19:03:10.992097Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31650/133889 blocks (23.6%), 0 events +2026-02-04T19:03:11.338422Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31660/133889 blocks (23.6%), 0 events +2026-02-04T19:03:11.380964Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31670/133889 blocks (23.7%), 0 events +2026-02-04T19:03:11.587352Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31680/133889 blocks (23.7%), 0 events +2026-02-04T19:03:11.852782Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31690/133889 blocks (23.7%), 0 events +2026-02-04T19:03:11.994240Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31700/133889 blocks (23.7%), 0 events +2026-02-04T19:03:12.217427Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31710/133889 blocks (23.7%), 0 events +2026-02-04T19:03:12.446568Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31720/133889 blocks (23.7%), 0 events +2026-02-04T19:03:12.646929Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31730/133889 blocks (23.7%), 0 events +2026-02-04T19:03:12.899123Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31740/133889 blocks (23.7%), 0 events +2026-02-04T19:03:13.045521Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31750/133889 blocks (23.7%), 0 events +2026-02-04T19:03:13.198948Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31760/133889 blocks (23.7%), 0 events +2026-02-04T19:03:13.418263Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31770/133889 blocks (23.7%), 0 events +2026-02-04T19:03:13.584849Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31780/133889 blocks (23.7%), 0 events +2026-02-04T19:03:13.913075Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31790/133889 blocks (23.7%), 0 events +2026-02-04T19:03:14.043936Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31800/133889 blocks (23.8%), 0 events +2026-02-04T19:03:14.181314Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31810/133889 blocks (23.8%), 0 events +2026-02-04T19:03:14.467493Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31820/133889 blocks (23.8%), 0 events +2026-02-04T19:03:14.605714Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31830/133889 blocks (23.8%), 0 events +2026-02-04T19:03:14.845254Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31840/133889 blocks (23.8%), 0 events +2026-02-04T19:03:15.000710Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31850/133889 blocks (23.8%), 0 events +2026-02-04T19:03:15.274790Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31860/133889 blocks (23.8%), 0 events +2026-02-04T19:03:15.484764Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31870/133889 blocks (23.8%), 0 events +2026-02-04T19:03:15.601617Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31880/133889 blocks (23.8%), 0 events +2026-02-04T19:03:15.868333Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31890/133889 blocks (23.8%), 0 events +2026-02-04T19:03:16.045094Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31900/133889 blocks (23.8%), 0 events +2026-02-04T19:03:16.192770Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31910/133889 blocks (23.8%), 0 events +2026-02-04T19:03:16.440725Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31920/133889 blocks (23.8%), 0 events +2026-02-04T19:03:16.609455Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31930/133889 blocks (23.8%), 0 events +2026-02-04T19:03:16.870360Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31940/133889 blocks (23.9%), 0 events +2026-02-04T19:03:17.094403Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31950/133889 blocks (23.9%), 0 events +2026-02-04T19:03:17.202879Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31960/133889 blocks (23.9%), 0 events +2026-02-04T19:03:17.367912Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31970/133889 blocks (23.9%), 0 events +2026-02-04T19:03:17.654917Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31980/133889 blocks (23.9%), 0 events +2026-02-04T19:03:17.821148Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31990/133889 blocks (23.9%), 0 events +2026-02-04T19:03:18.137949Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32000/133889 blocks (23.9%), 0 events +2026-02-04T19:03:18.176632Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32010/133889 blocks (23.9%), 0 events +2026-02-04T19:03:18.457435Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32020/133889 blocks (23.9%), 0 events +2026-02-04T19:03:18.662909Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32030/133889 blocks (23.9%), 0 events +2026-02-04T19:03:18.851754Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32040/133889 blocks (23.9%), 0 events +2026-02-04T19:03:19.053762Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32050/133889 blocks (23.9%), 0 events +2026-02-04T19:03:19.232723Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32060/133889 blocks (23.9%), 0 events +2026-02-04T19:03:19.444431Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32070/133889 blocks (24.0%), 0 events +2026-02-04T19:03:19.714120Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32080/133889 blocks (24.0%), 0 events +2026-02-04T19:03:19.836293Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32090/133889 blocks (24.0%), 0 events +2026-02-04T19:03:20.027063Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32100/133889 blocks (24.0%), 0 events +2026-02-04T19:03:20.237967Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32110/133889 blocks (24.0%), 0 events +2026-02-04T19:03:20.434372Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32120/133889 blocks (24.0%), 0 events +2026-02-04T19:03:20.585404Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32130/133889 blocks (24.0%), 0 events +2026-02-04T19:03:20.847526Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32140/133889 blocks (24.0%), 0 events +2026-02-04T19:03:20.993930Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32150/133889 blocks (24.0%), 0 events +2026-02-04T19:03:21.288397Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32160/133889 blocks (24.0%), 0 events +2026-02-04T19:03:21.433260Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32170/133889 blocks (24.0%), 0 events +2026-02-04T19:03:21.645936Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32180/133889 blocks (24.0%), 0 events +2026-02-04T19:03:21.809984Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32190/133889 blocks (24.0%), 0 events +2026-02-04T19:03:21.998041Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32200/133889 blocks (24.0%), 0 events +2026-02-04T19:03:22.193776Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32210/133889 blocks (24.1%), 0 events +2026-02-04T19:03:22.457035Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32220/133889 blocks (24.1%), 0 events +2026-02-04T19:03:22.638231Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32230/133889 blocks (24.1%), 0 events +2026-02-04T19:03:22.860514Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32240/133889 blocks (24.1%), 0 events +2026-02-04T19:03:23.014701Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32250/133889 blocks (24.1%), 0 events +2026-02-04T19:03:23.218089Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32260/133889 blocks (24.1%), 0 events +2026-02-04T19:03:23.446778Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32270/133889 blocks (24.1%), 0 events +2026-02-04T19:03:23.636363Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32280/133889 blocks (24.1%), 0 events +2026-02-04T19:03:23.873838Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32290/133889 blocks (24.1%), 0 events +2026-02-04T19:03:24.028833Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32300/133889 blocks (24.1%), 0 events +2026-02-04T19:03:24.211600Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32310/133889 blocks (24.1%), 0 events +2026-02-04T19:03:24.427785Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32320/133889 blocks (24.1%), 0 events +2026-02-04T19:03:24.635818Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32330/133889 blocks (24.1%), 0 events +2026-02-04T19:03:24.766461Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32340/133889 blocks (24.2%), 0 events +2026-02-04T19:03:25.008951Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32350/133889 blocks (24.2%), 0 events +2026-02-04T19:03:25.168732Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32360/133889 blocks (24.2%), 0 events +2026-02-04T19:03:25.447246Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32370/133889 blocks (24.2%), 0 events +2026-02-04T19:03:25.642792Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32380/133889 blocks (24.2%), 0 events +2026-02-04T19:03:25.809208Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32390/133889 blocks (24.2%), 0 events +2026-02-04T19:03:26.008771Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32400/133889 blocks (24.2%), 0 events +2026-02-04T19:03:26.180565Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32410/133889 blocks (24.2%), 0 events +2026-02-04T19:03:26.495027Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32420/133889 blocks (24.2%), 0 events +2026-02-04T19:03:26.659428Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32430/133889 blocks (24.2%), 0 events +2026-02-04T19:03:26.791271Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32440/133889 blocks (24.2%), 0 events +2026-02-04T19:03:27.051769Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32450/133889 blocks (24.2%), 0 events +2026-02-04T19:03:27.249269Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32460/133889 blocks (24.2%), 0 events +2026-02-04T19:03:27.383064Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32470/133889 blocks (24.3%), 0 events +2026-02-04T19:03:27.629347Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32480/133889 blocks (24.3%), 0 events +2026-02-04T19:03:27.868017Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32490/133889 blocks (24.3%), 0 events +2026-02-04T19:03:27.975203Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32500/133889 blocks (24.3%), 0 events +2026-02-04T19:03:28.197803Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32510/133889 blocks (24.3%), 0 events +2026-02-04T19:03:28.412018Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32520/133889 blocks (24.3%), 0 events +2026-02-04T19:03:28.661718Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32530/133889 blocks (24.3%), 0 events +2026-02-04T19:03:28.845878Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32540/133889 blocks (24.3%), 0 events +2026-02-04T19:03:29.149165Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32550/133889 blocks (24.3%), 0 events +2026-02-04T19:03:29.199266Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32560/133889 blocks (24.3%), 0 events +2026-02-04T19:03:29.450277Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32570/133889 blocks (24.3%), 0 events +2026-02-04T19:03:29.675349Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32580/133889 blocks (24.3%), 0 events +2026-02-04T19:03:29.804436Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32590/133889 blocks (24.3%), 0 events +2026-02-04T19:03:30.009481Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32600/133889 blocks (24.3%), 0 events +2026-02-04T19:03:30.264893Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32610/133889 blocks (24.4%), 0 events +2026-02-04T19:03:30.384595Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32620/133889 blocks (24.4%), 0 events +2026-02-04T19:03:30.597190Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32630/133889 blocks (24.4%), 0 events +2026-02-04T19:03:30.832343Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32640/133889 blocks (24.4%), 0 events +2026-02-04T19:03:31.010430Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32650/133889 blocks (24.4%), 0 events +2026-02-04T19:03:31.255524Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32660/133889 blocks (24.4%), 0 events +2026-02-04T19:03:31.382534Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32670/133889 blocks (24.4%), 0 events +2026-02-04T19:03:31.738622Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32680/133889 blocks (24.4%), 0 events +2026-02-04T19:03:31.778618Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32690/133889 blocks (24.4%), 0 events +2026-02-04T19:03:32.053298Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32700/133889 blocks (24.4%), 0 events +2026-02-04T19:03:32.300807Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32710/133889 blocks (24.4%), 0 events +2026-02-04T19:03:32.433554Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32720/133889 blocks (24.4%), 0 events +2026-02-04T19:03:32.626830Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32730/133889 blocks (24.4%), 0 events +2026-02-04T19:03:32.823151Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32740/133889 blocks (24.5%), 0 events +2026-02-04T19:03:33.017036Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32750/133889 blocks (24.5%), 0 events +2026-02-04T19:03:33.346922Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32760/133889 blocks (24.5%), 0 events +2026-02-04T19:03:33.385665Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32770/133889 blocks (24.5%), 0 events +2026-02-04T19:03:33.636797Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32780/133889 blocks (24.5%), 0 events +2026-02-04T19:03:33.866495Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32790/133889 blocks (24.5%), 0 events +2026-02-04T19:03:33.977536Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32800/133889 blocks (24.5%), 0 events +2026-02-04T19:03:34.197641Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32810/133889 blocks (24.5%), 0 events +2026-02-04T19:03:34.421167Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32820/133889 blocks (24.5%), 0 events +2026-02-04T19:03:34.658718Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32830/133889 blocks (24.5%), 0 events +2026-02-04T19:03:34.884130Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32840/133889 blocks (24.5%), 0 events +2026-02-04T19:03:35.000529Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32850/133889 blocks (24.5%), 0 events +2026-02-04T19:03:35.218482Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32860/133889 blocks (24.5%), 0 events +2026-02-04T19:03:35.450000Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32870/133889 blocks (24.5%), 0 events +2026-02-04T19:03:35.600167Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32880/133889 blocks (24.6%), 0 events +2026-02-04T19:03:35.823045Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32890/133889 blocks (24.6%), 0 events +2026-02-04T19:03:36.058162Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32900/133889 blocks (24.6%), 0 events +2026-02-04T19:03:36.170268Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32910/133889 blocks (24.6%), 0 events +2026-02-04T19:03:36.455833Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32920/133889 blocks (24.6%), 0 events +2026-02-04T19:03:36.563461Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32930/133889 blocks (24.6%), 0 events +2026-02-04T19:03:36.864563Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32940/133889 blocks (24.6%), 0 events +2026-02-04T19:03:37.022530Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32950/133889 blocks (24.6%), 0 events +2026-02-04T19:03:37.211074Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32960/133889 blocks (24.6%), 0 events +2026-02-04T19:03:37.370155Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32970/133889 blocks (24.6%), 0 events +2026-02-04T19:03:37.620737Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32980/133889 blocks (24.6%), 0 events +2026-02-04T19:03:37.824024Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32990/133889 blocks (24.6%), 0 events +2026-02-04T19:03:38.062409Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33000/133889 blocks (24.6%), 0 events +2026-02-04T19:03:38.253342Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33010/133889 blocks (24.7%), 0 events +2026-02-04T19:03:38.557044Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33020/133889 blocks (24.7%), 0 events +2026-02-04T19:03:38.601244Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33030/133889 blocks (24.7%), 0 events +2026-02-04T19:03:38.833812Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33040/133889 blocks (24.7%), 0 events +2026-02-04T19:03:39.120329Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33050/133889 blocks (24.7%), 0 events +2026-02-04T19:03:39.165830Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33060/133889 blocks (24.7%), 0 events +2026-02-04T19:03:39.404724Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33070/133889 blocks (24.7%), 0 events +2026-02-04T19:03:39.633995Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33080/133889 blocks (24.7%), 0 events +2026-02-04T19:03:39.803211Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33090/133889 blocks (24.7%), 0 events +2026-02-04T19:03:39.967882Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33100/133889 blocks (24.7%), 0 events +2026-02-04T19:03:40.252346Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33110/133889 blocks (24.7%), 0 events +2026-02-04T19:03:40.419574Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33120/133889 blocks (24.7%), 0 events +2026-02-04T19:03:40.650192Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33130/133889 blocks (24.7%), 0 events +2026-02-04T19:03:40.778317Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33140/133889 blocks (24.8%), 0 events +2026-02-04T19:03:40.994771Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33150/133889 blocks (24.8%), 0 events +2026-02-04T19:03:41.249196Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33160/133889 blocks (24.8%), 0 events +2026-02-04T19:03:41.400944Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33170/133889 blocks (24.8%), 0 events +2026-02-04T19:03:41.584816Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33180/133889 blocks (24.8%), 0 events +2026-02-04T19:03:41.849432Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33190/133889 blocks (24.8%), 0 events +2026-02-04T19:03:42.055208Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33200/133889 blocks (24.8%), 0 events +2026-02-04T19:03:42.256260Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33210/133889 blocks (24.8%), 0 events +2026-02-04T19:03:42.442354Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33220/133889 blocks (24.8%), 0 events +2026-02-04T19:03:42.627590Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33230/133889 blocks (24.8%), 0 events +2026-02-04T19:03:42.850783Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33240/133889 blocks (24.8%), 0 events +2026-02-04T19:03:43.012385Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33250/133889 blocks (24.8%), 0 events +2026-02-04T19:03:43.302095Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33260/133889 blocks (24.8%), 0 events +2026-02-04T19:03:43.430522Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33270/133889 blocks (24.8%), 0 events +2026-02-04T19:03:43.660048Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33280/133889 blocks (24.9%), 0 events +2026-02-04T19:03:43.841034Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33290/133889 blocks (24.9%), 0 events +2026-02-04T19:03:44.043378Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33300/133889 blocks (24.9%), 0 events +2026-02-04T19:03:44.323857Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33310/133889 blocks (24.9%), 0 events +2026-02-04T19:03:44.363429Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33320/133889 blocks (24.9%), 0 events +2026-02-04T19:03:44.586146Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33330/133889 blocks (24.9%), 0 events +2026-02-04T19:03:44.878636Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33340/133889 blocks (24.9%), 0 events +2026-02-04T19:03:44.990110Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33350/133889 blocks (24.9%), 0 events +2026-02-04T19:03:45.196912Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33360/133889 blocks (24.9%), 0 events +2026-02-04T19:03:45.406762Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33370/133889 blocks (24.9%), 0 events +2026-02-04T19:03:45.667279Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33380/133889 blocks (24.9%), 0 events +2026-02-04T19:03:45.921171Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33390/133889 blocks (24.9%), 0 events +2026-02-04T19:03:45.959048Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33400/133889 blocks (24.9%), 0 events +2026-02-04T19:03:46.216090Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33410/133889 blocks (25.0%), 0 events +2026-02-04T19:03:46.452991Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33420/133889 blocks (25.0%), 0 events +2026-02-04T19:03:46.637236Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33430/133889 blocks (25.0%), 0 events +2026-02-04T19:03:46.769444Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33440/133889 blocks (25.0%), 0 events +2026-02-04T19:03:46.976937Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33450/133889 blocks (25.0%), 0 events +2026-02-04T19:03:47.204399Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33460/133889 blocks (25.0%), 0 events +2026-02-04T19:03:47.499628Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33470/133889 blocks (25.0%), 0 events +2026-02-04T19:03:47.580729Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33480/133889 blocks (25.0%), 0 events +2026-02-04T19:03:47.771322Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33490/133889 blocks (25.0%), 0 events +2026-02-04T19:03:48.018154Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33500/133889 blocks (25.0%), 0 events +2026-02-04T19:03:48.225002Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33510/133889 blocks (25.0%), 0 events +2026-02-04T19:03:48.382223Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33520/133889 blocks (25.0%), 0 events +2026-02-04T19:03:48.568788Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33530/133889 blocks (25.0%), 0 events +2026-02-04T19:03:48.847523Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33540/133889 blocks (25.1%), 0 events +2026-02-04T19:03:49.077541Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33550/133889 blocks (25.1%), 0 events +2026-02-04T19:03:49.229338Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33560/133889 blocks (25.1%), 0 events +2026-02-04T19:03:49.447235Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33570/133889 blocks (25.1%), 0 events +2026-02-04T19:03:49.596100Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33580/133889 blocks (25.1%), 0 events +2026-02-04T19:03:49.836803Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33590/133889 blocks (25.1%), 0 events +2026-02-04T19:03:50.087220Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33600/133889 blocks (25.1%), 0 events +2026-02-04T19:03:50.234340Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33610/133889 blocks (25.1%), 0 events +2026-02-04T19:03:50.384298Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33620/133889 blocks (25.1%), 0 events +2026-02-04T19:03:50.647595Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33630/133889 blocks (25.1%), 0 events +2026-02-04T19:03:50.858681Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33640/133889 blocks (25.1%), 0 events +2026-02-04T19:03:50.990239Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33650/133889 blocks (25.1%), 0 events +2026-02-04T19:03:51.225833Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33660/133889 blocks (25.1%), 0 events +2026-02-04T19:03:51.392545Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33670/133889 blocks (25.1%), 0 events +2026-02-04T19:03:51.659168Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33680/133889 blocks (25.2%), 0 events +2026-02-04T19:03:51.789307Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33690/133889 blocks (25.2%), 0 events +2026-02-04T19:03:52.069098Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33700/133889 blocks (25.2%), 0 events +2026-02-04T19:03:52.230717Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33710/133889 blocks (25.2%), 0 events +2026-02-04T19:03:52.422989Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33720/133889 blocks (25.2%), 0 events +2026-02-04T19:03:52.710744Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33730/133889 blocks (25.2%), 0 events +2026-02-04T19:03:52.778674Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33740/133889 blocks (25.2%), 0 events +2026-02-04T19:03:53.058078Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33750/133889 blocks (25.2%), 0 events +2026-02-04T19:03:53.232606Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33760/133889 blocks (25.2%), 0 events +2026-02-04T19:03:53.437207Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33770/133889 blocks (25.2%), 0 events +2026-02-04T19:03:53.580585Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33780/133889 blocks (25.2%), 0 events +2026-02-04T19:03:53.836861Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33790/133889 blocks (25.2%), 0 events +2026-02-04T19:03:54.000039Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33800/133889 blocks (25.2%), 0 events +2026-02-04T19:03:54.420897Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33810/133889 blocks (25.3%), 0 events +2026-02-04T19:03:54.457963Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33820/133889 blocks (25.3%), 0 events +2026-02-04T19:03:54.601888Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33830/133889 blocks (25.3%), 0 events +2026-02-04T19:03:54.868785Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33840/133889 blocks (25.3%), 0 events +2026-02-04T19:03:54.994664Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33850/133889 blocks (25.3%), 0 events +2026-02-04T19:03:55.202779Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33860/133889 blocks (25.3%), 0 events +2026-02-04T19:03:55.419163Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33870/133889 blocks (25.3%), 0 events +2026-02-04T19:03:55.573671Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33880/133889 blocks (25.3%), 0 events +2026-02-04T19:03:55.885226Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33890/133889 blocks (25.3%), 0 events +2026-02-04T19:03:56.019584Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33900/133889 blocks (25.3%), 0 events +2026-02-04T19:03:56.201313Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33910/133889 blocks (25.3%), 0 events +2026-02-04T19:03:56.409554Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33920/133889 blocks (25.3%), 0 events +2026-02-04T19:03:56.653389Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33930/133889 blocks (25.3%), 0 events +2026-02-04T19:03:56.901398Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33940/133889 blocks (25.3%), 0 events +2026-02-04T19:03:56.996256Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33950/133889 blocks (25.4%), 0 events +2026-02-04T19:03:57.175711Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33960/133889 blocks (25.4%), 0 events +2026-02-04T19:03:57.456391Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33970/133889 blocks (25.4%), 0 events +2026-02-04T19:03:57.663668Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33980/133889 blocks (25.4%), 0 events +2026-02-04T19:03:57.853679Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33990/133889 blocks (25.4%), 0 events +2026-02-04T19:03:57.997668Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34000/133889 blocks (25.4%), 0 events +2026-02-04T19:03:58.181825Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34010/133889 blocks (25.4%), 0 events +2026-02-04T19:03:58.474801Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34020/133889 blocks (25.4%), 0 events +2026-02-04T19:03:59.001563Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34030/133889 blocks (25.4%), 0 events +2026-02-04T19:03:59.043036Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34040/133889 blocks (25.4%), 0 events +2026-02-04T19:03:59.088574Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34050/133889 blocks (25.4%), 0 events +2026-02-04T19:03:59.244317Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34060/133889 blocks (25.4%), 0 events +2026-02-04T19:03:59.521973Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34070/133889 blocks (25.4%), 0 events +2026-02-04T19:03:59.563565Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34080/133889 blocks (25.5%), 0 events +2026-02-04T19:03:59.838317Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34090/133889 blocks (25.5%), 0 events +2026-02-04T19:04:00.081821Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34100/133889 blocks (25.5%), 0 events +2026-02-04T19:04:00.240049Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34110/133889 blocks (25.5%), 0 events +2026-02-04T19:04:00.390260Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34120/133889 blocks (25.5%), 0 events +2026-02-04T19:04:00.614694Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34130/133889 blocks (25.5%), 0 events +2026-02-04T19:04:00.846991Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34140/133889 blocks (25.5%), 0 events +2026-02-04T19:04:01.096010Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34150/133889 blocks (25.5%), 0 events +2026-02-04T19:04:01.209385Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34160/133889 blocks (25.5%), 0 events +2026-02-04T19:04:01.443156Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34170/133889 blocks (25.5%), 0 events +2026-02-04T19:04:01.657496Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34180/133889 blocks (25.5%), 0 events +2026-02-04T19:04:01.864463Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34190/133889 blocks (25.5%), 0 events +2026-02-04T19:04:02.031174Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34200/133889 blocks (25.5%), 0 events +2026-02-04T19:04:02.247744Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34210/133889 blocks (25.6%), 0 events +2026-02-04T19:04:02.398965Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34220/133889 blocks (25.6%), 0 events +2026-02-04T19:04:02.706952Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34230/133889 blocks (25.6%), 0 events +2026-02-04T19:04:02.829122Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34240/133889 blocks (25.6%), 0 events +2026-02-04T19:04:02.974589Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34250/133889 blocks (25.6%), 0 events +2026-02-04T19:04:03.273806Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34260/133889 blocks (25.6%), 0 events +2026-02-04T19:04:03.434182Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34270/133889 blocks (25.6%), 0 events +2026-02-04T19:04:03.754873Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34280/133889 blocks (25.6%), 0 events +2026-02-04T19:04:03.808571Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34290/133889 blocks (25.6%), 0 events +2026-02-04T19:04:04.064108Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34300/133889 blocks (25.6%), 0 events +2026-02-04T19:04:04.277972Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34310/133889 blocks (25.6%), 0 events +2026-02-04T19:04:04.375153Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34320/133889 blocks (25.6%), 0 events +2026-02-04T19:04:04.641886Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34330/133889 blocks (25.6%), 0 events +2026-02-04T19:04:04.847786Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34340/133889 blocks (25.6%), 0 events +2026-02-04T19:04:04.991931Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34350/133889 blocks (25.7%), 0 events +2026-02-04T19:04:05.326015Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34360/133889 blocks (25.7%), 0 events +2026-02-04T19:04:05.372640Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34370/133889 blocks (25.7%), 0 events +2026-02-04T19:04:05.574940Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34380/133889 blocks (25.7%), 0 events +2026-02-04T19:04:05.856492Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34390/133889 blocks (25.7%), 0 events +2026-02-04T19:04:06.032895Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34400/133889 blocks (25.7%), 0 events +2026-02-04T19:04:06.337296Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34410/133889 blocks (25.7%), 0 events +2026-02-04T19:04:06.398227Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34420/133889 blocks (25.7%), 0 events +2026-02-04T19:04:06.577792Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34430/133889 blocks (25.7%), 0 events +2026-02-04T19:04:06.904804Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34440/133889 blocks (25.7%), 0 events +2026-02-04T19:04:07.051900Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34450/133889 blocks (25.7%), 0 events +2026-02-04T19:04:07.171967Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34460/133889 blocks (25.7%), 0 events +2026-02-04T19:04:07.426767Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34470/133889 blocks (25.7%), 0 events +2026-02-04T19:04:07.590970Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34480/133889 blocks (25.8%), 0 events +2026-02-04T19:04:07.943933Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34490/133889 blocks (25.8%), 0 events +2026-02-04T19:04:07.983073Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34500/133889 blocks (25.8%), 0 events +2026-02-04T19:04:08.181090Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34510/133889 blocks (25.8%), 0 events +2026-02-04T19:04:08.476102Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34520/133889 blocks (25.8%), 0 events +2026-02-04T19:04:08.591845Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34530/133889 blocks (25.8%), 0 events +2026-02-04T19:04:08.829816Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34540/133889 blocks (25.8%), 0 events +2026-02-04T19:04:09.019609Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34550/133889 blocks (25.8%), 0 events +2026-02-04T19:04:09.206814Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34560/133889 blocks (25.8%), 0 events +2026-02-04T19:04:09.485122Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34570/133889 blocks (25.8%), 0 events +2026-02-04T19:04:09.659536Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34580/133889 blocks (25.8%), 0 events +2026-02-04T19:04:09.794538Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34590/133889 blocks (25.8%), 0 events +2026-02-04T19:04:10.070448Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34600/133889 blocks (25.8%), 0 events +2026-02-04T19:04:10.184297Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34610/133889 blocks (25.8%), 0 events +2026-02-04T19:04:10.430056Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34620/133889 blocks (25.9%), 0 events +2026-02-04T19:04:10.568138Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34630/133889 blocks (25.9%), 0 events +2026-02-04T19:04:10.801283Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34640/133889 blocks (25.9%), 0 events +2026-02-04T19:04:11.097297Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34650/133889 blocks (25.9%), 0 events +2026-02-04T19:04:11.181162Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34660/133889 blocks (25.9%), 0 events +2026-02-04T19:04:11.415300Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34670/133889 blocks (25.9%), 0 events +2026-02-04T19:04:11.669960Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34680/133889 blocks (25.9%), 0 events +2026-02-04T19:04:11.825366Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34690/133889 blocks (25.9%), 0 events +2026-02-04T19:04:12.107000Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34700/133889 blocks (25.9%), 0 events +2026-02-04T19:04:12.270152Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34710/133889 blocks (25.9%), 0 events +2026-02-04T19:04:12.360563Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34720/133889 blocks (25.9%), 0 events +2026-02-04T19:04:12.669454Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34730/133889 blocks (25.9%), 0 events +2026-02-04T19:04:12.819220Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34740/133889 blocks (25.9%), 0 events +2026-02-04T19:04:13.064386Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34750/133889 blocks (26.0%), 0 events +2026-02-04T19:04:13.281900Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34760/133889 blocks (26.0%), 0 events +2026-02-04T19:04:13.469983Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34770/133889 blocks (26.0%), 0 events +2026-02-04T19:04:13.679238Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34780/133889 blocks (26.0%), 0 events +2026-02-04T19:04:13.880458Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34790/133889 blocks (26.0%), 0 events +2026-02-04T19:04:14.059856Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34800/133889 blocks (26.0%), 0 events +2026-02-04T19:04:14.234217Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34810/133889 blocks (26.0%), 0 events +2026-02-04T19:04:14.372563Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34820/133889 blocks (26.0%), 0 events +2026-02-04T19:04:14.617565Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34830/133889 blocks (26.0%), 0 events +2026-02-04T19:04:14.834113Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34840/133889 blocks (26.0%), 0 events +2026-02-04T19:04:14.999368Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34850/133889 blocks (26.0%), 0 events +2026-02-04T19:04:15.289664Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34860/133889 blocks (26.0%), 0 events +2026-02-04T19:04:15.459002Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34870/133889 blocks (26.0%), 0 events +2026-02-04T19:04:15.589391Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34880/133889 blocks (26.1%), 0 events +2026-02-04T19:04:15.870535Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34890/133889 blocks (26.1%), 0 events +2026-02-04T19:04:15.988030Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34900/133889 blocks (26.1%), 0 events +2026-02-04T19:04:16.203283Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34910/133889 blocks (26.1%), 0 events +2026-02-04T19:04:16.433812Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34920/133889 blocks (26.1%), 0 events +2026-02-04T19:04:16.594148Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34930/133889 blocks (26.1%), 0 events +2026-02-04T19:04:16.861033Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34940/133889 blocks (26.1%), 0 events +2026-02-04T19:04:16.992268Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34950/133889 blocks (26.1%), 0 events +2026-02-04T19:04:17.218247Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34960/133889 blocks (26.1%), 0 events +2026-02-04T19:04:17.381433Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34970/133889 blocks (26.1%), 0 events +2026-02-04T19:04:17.590081Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34980/133889 blocks (26.1%), 0 events +2026-02-04T19:04:17.911640Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34990/133889 blocks (26.1%), 0 events +2026-02-04T19:04:18.005679Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35000/133889 blocks (26.1%), 0 events +2026-02-04T19:04:18.168625Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35010/133889 blocks (26.1%), 0 events +2026-02-04T19:04:18.430571Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35020/133889 blocks (26.2%), 0 events +2026-02-04T19:04:18.641414Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35030/133889 blocks (26.2%), 0 events +2026-02-04T19:04:18.810671Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35040/133889 blocks (26.2%), 0 events +2026-02-04T19:04:19.032741Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35050/133889 blocks (26.2%), 0 events +2026-02-04T19:04:19.229496Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35060/133889 blocks (26.2%), 0 events +2026-02-04T19:04:19.482606Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35070/133889 blocks (26.2%), 0 events +2026-02-04T19:04:19.588815Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35080/133889 blocks (26.2%), 0 events +2026-02-04T19:04:19.824088Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35090/133889 blocks (26.2%), 0 events +2026-02-04T19:04:20.012980Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35100/133889 blocks (26.2%), 0 events +2026-02-04T19:04:20.237378Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35110/133889 blocks (26.2%), 0 events +2026-02-04T19:04:20.494370Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35120/133889 blocks (26.2%), 0 events +2026-02-04T19:04:20.663208Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35130/133889 blocks (26.2%), 0 events +2026-02-04T19:04:20.814992Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35140/133889 blocks (26.2%), 0 events +2026-02-04T19:04:21.062525Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35150/133889 blocks (26.3%), 0 events +2026-02-04T19:04:21.241539Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35160/133889 blocks (26.3%), 0 events +2026-02-04T19:04:21.409453Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35170/133889 blocks (26.3%), 0 events +2026-02-04T19:04:21.649847Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35180/133889 blocks (26.3%), 0 events +2026-02-04T19:04:21.822106Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35190/133889 blocks (26.3%), 0 events +2026-02-04T19:04:22.098744Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35200/133889 blocks (26.3%), 0 events +2026-02-04T19:04:22.181749Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35210/133889 blocks (26.3%), 0 events +2026-02-04T19:04:22.451114Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35220/133889 blocks (26.3%), 0 events +2026-02-04T19:04:22.653051Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35230/133889 blocks (26.3%), 0 events +2026-02-04T19:04:22.819872Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35240/133889 blocks (26.3%), 0 events +2026-02-04T19:04:23.116524Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35250/133889 blocks (26.3%), 0 events +2026-02-04T19:04:23.205107Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35260/133889 blocks (26.3%), 0 events +2026-02-04T19:04:23.425400Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35270/133889 blocks (26.3%), 0 events +2026-02-04T19:04:23.682300Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35280/133889 blocks (26.3%), 0 events +2026-02-04T19:04:23.828817Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35290/133889 blocks (26.4%), 0 events +2026-02-04T19:04:24.016103Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35300/133889 blocks (26.4%), 0 events +2026-02-04T19:04:24.264977Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35310/133889 blocks (26.4%), 0 events +2026-02-04T19:04:24.689233Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35320/133889 blocks (26.4%), 0 events +2026-02-04T19:04:24.730720Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35330/133889 blocks (26.4%), 0 events +2026-02-04T19:04:24.768195Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35340/133889 blocks (26.4%), 0 events +2026-02-04T19:04:25.039615Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35350/133889 blocks (26.4%), 0 events +2026-02-04T19:04:25.266834Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35360/133889 blocks (26.4%), 0 events +2026-02-04T19:04:25.464739Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35370/133889 blocks (26.4%), 0 events +2026-02-04T19:04:25.635758Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35380/133889 blocks (26.4%), 0 events +2026-02-04T19:04:25.864330Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35390/133889 blocks (26.4%), 0 events +2026-02-04T19:04:26.013841Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35400/133889 blocks (26.4%), 0 events +2026-02-04T19:04:26.293682Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35410/133889 blocks (26.4%), 0 events +2026-02-04T19:04:26.425997Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35420/133889 blocks (26.5%), 0 events +2026-02-04T19:04:26.664812Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35430/133889 blocks (26.5%), 0 events +2026-02-04T19:04:26.821495Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35440/133889 blocks (26.5%), 0 events +2026-02-04T19:04:27.036920Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35450/133889 blocks (26.5%), 0 events +2026-02-04T19:04:27.193890Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35460/133889 blocks (26.5%), 0 events +2026-02-04T19:04:27.404420Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35470/133889 blocks (26.5%), 0 events +2026-02-04T19:04:27.663472Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35480/133889 blocks (26.5%), 0 events +2026-02-04T19:04:27.870123Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35490/133889 blocks (26.5%), 0 events +2026-02-04T19:04:28.024628Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35500/133889 blocks (26.5%), 0 events +2026-02-04T19:04:28.233676Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35510/133889 blocks (26.5%), 0 events +2026-02-04T19:04:28.413985Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35520/133889 blocks (26.5%), 0 events +2026-02-04T19:04:28.571329Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35530/133889 blocks (26.5%), 0 events +2026-02-04T19:04:28.883255Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35540/133889 blocks (26.5%), 0 events +2026-02-04T19:04:29.018212Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35550/133889 blocks (26.6%), 0 events +2026-02-04T19:04:29.279028Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35560/133889 blocks (26.6%), 0 events +2026-02-04T19:04:29.445814Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35570/133889 blocks (26.6%), 0 events +2026-02-04T19:04:29.587390Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35580/133889 blocks (26.6%), 0 events +2026-02-04T19:04:29.931636Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35590/133889 blocks (26.6%), 0 events +2026-02-04T19:04:29.995488Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35600/133889 blocks (26.6%), 0 events +2026-02-04T19:04:30.266688Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35610/133889 blocks (26.6%), 0 events +2026-02-04T19:04:30.457321Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35620/133889 blocks (26.6%), 0 events +2026-02-04T19:04:30.657030Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35630/133889 blocks (26.6%), 0 events +2026-02-04T19:04:30.836383Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35640/133889 blocks (26.6%), 0 events +2026-02-04T19:04:31.014905Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35650/133889 blocks (26.6%), 0 events +2026-02-04T19:04:31.176557Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35660/133889 blocks (26.6%), 0 events +2026-02-04T19:04:31.408308Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35670/133889 blocks (26.6%), 0 events +2026-02-04T19:04:31.624560Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35680/133889 blocks (26.6%), 0 events +2026-02-04T19:04:31.816542Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35690/133889 blocks (26.7%), 0 events +2026-02-04T19:04:32.072870Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35700/133889 blocks (26.7%), 0 events +2026-02-04T19:04:32.219965Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35710/133889 blocks (26.7%), 0 events +2026-02-04T19:04:32.393851Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35720/133889 blocks (26.7%), 0 events +2026-02-04T19:04:32.619020Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35730/133889 blocks (26.7%), 0 events +2026-02-04T19:04:32.836031Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35740/133889 blocks (26.7%), 0 events +2026-02-04T19:04:33.110751Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35750/133889 blocks (26.7%), 0 events +2026-02-04T19:04:33.265001Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35760/133889 blocks (26.7%), 0 events +2026-02-04T19:04:33.464078Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35770/133889 blocks (26.7%), 0 events +2026-02-04T19:04:33.744825Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35780/133889 blocks (26.7%), 0 events +2026-02-04T19:04:33.788029Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35790/133889 blocks (26.7%), 0 events +2026-02-04T19:04:33.999178Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35800/133889 blocks (26.7%), 0 events +2026-02-04T19:04:34.187363Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35810/133889 blocks (26.7%), 0 events +2026-02-04T19:04:34.423437Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35820/133889 blocks (26.8%), 0 events +2026-02-04T19:04:34.685334Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35830/133889 blocks (26.8%), 0 events +2026-02-04T19:04:34.788967Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35840/133889 blocks (26.8%), 0 events +2026-02-04T19:04:34.998869Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35850/133889 blocks (26.8%), 0 events +2026-02-04T19:04:35.372769Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35860/133889 blocks (26.8%), 0 events +2026-02-04T19:04:35.418769Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35870/133889 blocks (26.8%), 0 events +2026-02-04T19:04:35.699777Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35880/133889 blocks (26.8%), 0 events +2026-02-04T19:04:35.872781Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35890/133889 blocks (26.8%), 0 events +2026-02-04T19:04:36.001450Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35900/133889 blocks (26.8%), 0 events +2026-02-04T19:04:36.255230Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35910/133889 blocks (26.8%), 0 events +2026-02-04T19:04:36.408421Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35920/133889 blocks (26.8%), 0 events +2026-02-04T19:04:36.586536Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35930/133889 blocks (26.8%), 0 events +2026-02-04T19:04:36.804317Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35940/133889 blocks (26.8%), 0 events +2026-02-04T19:04:37.051417Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35950/133889 blocks (26.9%), 0 events +2026-02-04T19:04:37.306606Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35960/133889 blocks (26.9%), 0 events +2026-02-04T19:04:37.380479Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35970/133889 blocks (26.9%), 0 events +2026-02-04T19:04:37.648342Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35980/133889 blocks (26.9%), 0 events +2026-02-04T19:04:37.845345Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35990/133889 blocks (26.9%), 0 events +2026-02-04T19:04:38.037326Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36000/133889 blocks (26.9%), 0 events +2026-02-04T19:04:38.319403Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36010/133889 blocks (26.9%), 0 events +2026-02-04T19:04:38.366516Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36020/133889 blocks (26.9%), 0 events +2026-02-04T19:04:38.649718Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36030/133889 blocks (26.9%), 0 events +2026-02-04T19:04:38.875210Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36040/133889 blocks (26.9%), 0 events +2026-02-04T19:04:39.012016Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36050/133889 blocks (26.9%), 0 events +2026-02-04T19:04:39.214372Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36060/133889 blocks (26.9%), 0 events +2026-02-04T19:04:39.405081Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36070/133889 blocks (26.9%), 0 events +2026-02-04T19:04:39.606396Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36080/133889 blocks (26.9%), 0 events +2026-02-04T19:04:39.892909Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36090/133889 blocks (27.0%), 0 events +2026-02-04T19:04:40.077995Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36100/133889 blocks (27.0%), 0 events +2026-02-04T19:04:40.210261Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36110/133889 blocks (27.0%), 0 events +2026-02-04T19:04:40.460570Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36120/133889 blocks (27.0%), 0 events +2026-02-04T19:04:40.630721Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36130/133889 blocks (27.0%), 0 events +2026-02-04T19:04:40.821521Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36140/133889 blocks (27.0%), 0 events +2026-02-04T19:04:41.031186Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36150/133889 blocks (27.0%), 0 events +2026-02-04T19:04:41.238802Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36160/133889 blocks (27.0%), 0 events +2026-02-04T19:04:41.496131Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36170/133889 blocks (27.0%), 0 events +2026-02-04T19:04:41.565177Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36180/133889 blocks (27.0%), 0 events +2026-02-04T19:04:41.764696Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36190/133889 blocks (27.0%), 0 events +2026-02-04T19:04:42.020873Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36200/133889 blocks (27.0%), 0 events +2026-02-04T19:04:42.243695Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36210/133889 blocks (27.0%), 0 events +2026-02-04T19:04:42.412697Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36220/133889 blocks (27.1%), 0 events +2026-02-04T19:04:42.584017Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36230/133889 blocks (27.1%), 0 events +2026-02-04T19:04:42.808059Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36240/133889 blocks (27.1%), 0 events +2026-02-04T19:04:43.075160Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36250/133889 blocks (27.1%), 0 events +2026-02-04T19:04:43.183532Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36260/133889 blocks (27.1%), 0 events +2026-02-04T19:04:43.451246Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36270/133889 blocks (27.1%), 0 events +2026-02-04T19:04:43.653830Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36280/133889 blocks (27.1%), 0 events +2026-02-04T19:04:43.806988Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36290/133889 blocks (27.1%), 0 events +2026-02-04T19:04:44.087782Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36300/133889 blocks (27.1%), 0 events +2026-02-04T19:04:44.266575Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36310/133889 blocks (27.1%), 0 events +2026-02-04T19:04:44.376981Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36320/133889 blocks (27.1%), 0 events +2026-02-04T19:04:44.642327Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36330/133889 blocks (27.1%), 0 events +2026-02-04T19:04:44.807178Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36340/133889 blocks (27.1%), 0 events +2026-02-04T19:04:44.967646Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36350/133889 blocks (27.1%), 0 events +2026-02-04T19:04:45.220981Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36360/133889 blocks (27.2%), 0 events +2026-02-04T19:04:45.443388Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36370/133889 blocks (27.2%), 0 events +2026-02-04T19:04:45.661563Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36380/133889 blocks (27.2%), 0 events +2026-02-04T19:04:45.859128Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36390/133889 blocks (27.2%), 0 events +2026-02-04T19:04:46.011989Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36400/133889 blocks (27.2%), 0 events +2026-02-04T19:04:46.275164Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36410/133889 blocks (27.2%), 0 events +2026-02-04T19:04:46.459521Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36420/133889 blocks (27.2%), 0 events +2026-02-04T19:04:46.710395Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36430/133889 blocks (27.2%), 0 events +2026-02-04T19:04:46.780252Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36440/133889 blocks (27.2%), 0 events +2026-02-04T19:04:47.012633Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36450/133889 blocks (27.2%), 0 events +2026-02-04T19:04:47.265135Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36460/133889 blocks (27.2%), 0 events +2026-02-04T19:04:47.377631Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36470/133889 blocks (27.2%), 0 events +2026-02-04T19:04:47.667609Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36480/133889 blocks (27.2%), 0 events +2026-02-04T19:04:47.787571Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36490/133889 blocks (27.3%), 0 events +2026-02-04T19:04:48.059333Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36500/133889 blocks (27.3%), 0 events +2026-02-04T19:04:48.280410Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36510/133889 blocks (27.3%), 0 events +2026-02-04T19:04:48.379046Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36520/133889 blocks (27.3%), 0 events +2026-02-04T19:04:48.646599Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36530/133889 blocks (27.3%), 0 events +2026-02-04T19:04:48.834313Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36540/133889 blocks (27.3%), 0 events +2026-02-04T19:04:48.990834Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36550/133889 blocks (27.3%), 0 events +2026-02-04T19:04:49.229248Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36560/133889 blocks (27.3%), 0 events +2026-02-04T19:04:49.454695Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36570/133889 blocks (27.3%), 0 events +2026-02-04T19:04:49.651718Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36580/133889 blocks (27.3%), 0 events +2026-02-04T19:04:49.887398Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36590/133889 blocks (27.3%), 0 events +2026-02-04T19:04:49.987519Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36600/133889 blocks (27.3%), 0 events +2026-02-04T19:04:50.219479Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36610/133889 blocks (27.3%), 0 events +2026-02-04T19:04:50.452145Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36620/133889 blocks (27.4%), 0 events +2026-02-04T19:04:50.617787Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36630/133889 blocks (27.4%), 0 events +2026-02-04T19:04:50.936219Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36640/133889 blocks (27.4%), 0 events +2026-02-04T19:04:50.979153Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36650/133889 blocks (27.4%), 0 events +2026-02-04T19:04:51.195485Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36660/133889 blocks (27.4%), 0 events +2026-02-04T19:04:51.460401Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36670/133889 blocks (27.4%), 0 events +2026-02-04T19:04:51.653932Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36680/133889 blocks (27.4%), 0 events +2026-02-04T19:04:51.787009Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36690/133889 blocks (27.4%), 0 events +2026-02-04T19:04:51.987060Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36700/133889 blocks (27.4%), 0 events +2026-02-04T19:04:52.184428Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36710/133889 blocks (27.4%), 0 events +2026-02-04T19:04:52.508782Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36720/133889 blocks (27.4%), 0 events +2026-02-04T19:04:52.644743Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36730/133889 blocks (27.4%), 0 events +2026-02-04T19:04:52.821986Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36740/133889 blocks (27.4%), 0 events +2026-02-04T19:04:53.066217Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36750/133889 blocks (27.4%), 0 events +2026-02-04T19:04:53.185446Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36760/133889 blocks (27.5%), 0 events +2026-02-04T19:04:53.391898Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36770/133889 blocks (27.5%), 0 events +2026-02-04T19:04:53.640121Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36780/133889 blocks (27.5%), 0 events +2026-02-04T19:04:53.788411Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36790/133889 blocks (27.5%), 0 events +2026-02-04T19:04:54.084259Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36800/133889 blocks (27.5%), 0 events +2026-02-04T19:04:54.243813Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36810/133889 blocks (27.5%), 0 events +2026-02-04T19:04:54.383682Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36820/133889 blocks (27.5%), 0 events +2026-02-04T19:04:54.630416Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36830/133889 blocks (27.5%), 0 events +2026-02-04T19:04:54.827700Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36840/133889 blocks (27.5%), 0 events +2026-02-04T19:04:54.999378Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36850/133889 blocks (27.5%), 0 events +2026-02-04T19:04:55.187216Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36860/133889 blocks (27.5%), 0 events +2026-02-04T19:04:55.425241Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36870/133889 blocks (27.5%), 0 events +2026-02-04T19:04:55.651564Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36880/133889 blocks (27.5%), 0 events +2026-02-04T19:04:55.871924Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36890/133889 blocks (27.6%), 0 events +2026-02-04T19:04:56.011755Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36900/133889 blocks (27.6%), 0 events +2026-02-04T19:04:56.214242Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36910/133889 blocks (27.6%), 0 events +2026-02-04T19:04:56.443285Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36920/133889 blocks (27.6%), 0 events +2026-02-04T19:04:56.700318Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36930/133889 blocks (27.6%), 0 events +2026-02-04T19:04:56.846571Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36940/133889 blocks (27.6%), 0 events +2026-02-04T19:04:57.052633Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36950/133889 blocks (27.6%), 0 events +2026-02-04T19:04:57.229671Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36960/133889 blocks (27.6%), 0 events +2026-02-04T19:04:57.396395Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36970/133889 blocks (27.6%), 0 events +2026-02-04T19:04:57.718884Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36980/133889 blocks (27.6%), 0 events +2026-02-04T19:04:57.760440Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36990/133889 blocks (27.6%), 0 events +2026-02-04T19:04:58.018080Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37000/133889 blocks (27.6%), 0 events +2026-02-04T19:04:58.272431Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37010/133889 blocks (27.6%), 0 events +2026-02-04T19:04:58.448598Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37020/133889 blocks (27.6%), 0 events +2026-02-04T19:04:58.638599Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37030/133889 blocks (27.7%), 0 events +2026-02-04T19:04:58.857988Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37040/133889 blocks (27.7%), 0 events +2026-02-04T19:04:58.984188Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37050/133889 blocks (27.7%), 0 events +2026-02-04T19:04:59.169520Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37060/133889 blocks (27.7%), 0 events +2026-02-04T19:04:59.417099Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37070/133889 blocks (27.7%), 0 events +2026-02-04T19:04:59.605145Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37080/133889 blocks (27.7%), 0 events +2026-02-04T19:04:59.846044Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37090/133889 blocks (27.7%), 0 events +2026-02-04T19:05:00.012943Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37100/133889 blocks (27.7%), 0 events +2026-02-04T19:05:00.229096Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37110/133889 blocks (27.7%), 0 events +2026-02-04T19:05:00.465682Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37120/133889 blocks (27.7%), 0 events +2026-02-04T19:05:00.597120Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37130/133889 blocks (27.7%), 0 events +2026-02-04T19:05:00.912703Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37140/133889 blocks (27.7%), 0 events +2026-02-04T19:05:00.990207Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37150/133889 blocks (27.7%), 0 events +2026-02-04T19:05:01.289430Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37160/133889 blocks (27.8%), 0 events +2026-02-04T19:05:01.464353Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37170/133889 blocks (27.8%), 0 events +2026-02-04T19:05:01.582443Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37180/133889 blocks (27.8%), 0 events +2026-02-04T19:05:01.782829Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37190/133889 blocks (27.8%), 0 events +2026-02-04T19:05:02.009788Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37200/133889 blocks (27.8%), 0 events +2026-02-04T19:05:02.187470Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37210/133889 blocks (27.8%), 0 events +2026-02-04T19:05:02.472236Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37220/133889 blocks (27.8%), 0 events +2026-02-04T19:05:02.609469Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37230/133889 blocks (27.8%), 0 events +2026-02-04T19:05:02.810046Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37240/133889 blocks (27.8%), 0 events +2026-02-04T19:05:02.998905Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37250/133889 blocks (27.8%), 0 events +2026-02-04T19:05:03.223955Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37260/133889 blocks (27.8%), 0 events +2026-02-04T19:05:03.484205Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37270/133889 blocks (27.8%), 0 events +2026-02-04T19:05:03.646741Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37280/133889 blocks (27.8%), 0 events +2026-02-04T19:05:03.834554Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37290/133889 blocks (27.9%), 0 events +2026-02-04T19:05:04.041449Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37300/133889 blocks (27.9%), 0 events +2026-02-04T19:05:04.258682Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37310/133889 blocks (27.9%), 0 events +2026-02-04T19:05:04.419625Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37320/133889 blocks (27.9%), 0 events +2026-02-04T19:05:04.644486Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37330/133889 blocks (27.9%), 0 events +2026-02-04T19:05:04.842628Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37340/133889 blocks (27.9%), 0 events +2026-02-04T19:05:05.057915Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37350/133889 blocks (27.9%), 0 events +2026-02-04T19:05:05.231967Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37360/133889 blocks (27.9%), 0 events +2026-02-04T19:05:05.416360Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37370/133889 blocks (27.9%), 0 events +2026-02-04T19:05:05.625451Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37380/133889 blocks (27.9%), 0 events +2026-02-04T19:05:05.805548Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37390/133889 blocks (27.9%), 0 events +2026-02-04T19:05:06.105071Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37400/133889 blocks (27.9%), 0 events +2026-02-04T19:05:06.225993Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37410/133889 blocks (27.9%), 0 events +2026-02-04T19:05:06.425075Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37420/133889 blocks (27.9%), 0 events +2026-02-04T19:05:06.662735Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37430/133889 blocks (28.0%), 0 events +2026-02-04T19:05:06.767597Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37440/133889 blocks (28.0%), 0 events +2026-02-04T19:05:07.059547Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37450/133889 blocks (28.0%), 0 events +2026-02-04T19:05:07.187319Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37460/133889 blocks (28.0%), 0 events +2026-02-04T19:05:07.369787Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37470/133889 blocks (28.0%), 0 events +2026-02-04T19:05:07.722312Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37480/133889 blocks (28.0%), 0 events +2026-02-04T19:05:07.766679Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37490/133889 blocks (28.0%), 0 events +2026-02-04T19:05:08.023289Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37500/133889 blocks (28.0%), 0 events +2026-02-04T19:05:08.245099Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37510/133889 blocks (28.0%), 0 events +2026-02-04T19:05:08.406283Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37520/133889 blocks (28.0%), 0 events +2026-02-04T19:05:08.611880Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37530/133889 blocks (28.0%), 0 events +2026-02-04T19:05:08.786557Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37540/133889 blocks (28.0%), 0 events +2026-02-04T19:05:08.973353Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37550/133889 blocks (28.0%), 0 events +2026-02-04T19:05:09.280026Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37560/133889 blocks (28.1%), 0 events +2026-02-04T19:05:09.454104Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37570/133889 blocks (28.1%), 0 events +2026-02-04T19:05:09.579987Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37580/133889 blocks (28.1%), 0 events +2026-02-04T19:05:09.807432Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37590/133889 blocks (28.1%), 0 events +2026-02-04T19:05:10.030205Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37600/133889 blocks (28.1%), 0 events +2026-02-04T19:05:10.298759Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37610/133889 blocks (28.1%), 0 events +2026-02-04T19:05:10.393575Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37620/133889 blocks (28.1%), 0 events +2026-02-04T19:05:10.659346Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37630/133889 blocks (28.1%), 0 events +2026-02-04T19:05:10.858738Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37640/133889 blocks (28.1%), 0 events +2026-02-04T19:05:11.050849Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37650/133889 blocks (28.1%), 0 events +2026-02-04T19:05:11.230196Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37660/133889 blocks (28.1%), 0 events +2026-02-04T19:05:11.382214Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37670/133889 blocks (28.1%), 0 events +2026-02-04T19:05:11.659500Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37680/133889 blocks (28.1%), 0 events +2026-02-04T19:05:11.870845Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37690/133889 blocks (28.1%), 0 events +2026-02-04T19:05:12.097867Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37700/133889 blocks (28.2%), 0 events +2026-02-04T19:05:12.242881Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37710/133889 blocks (28.2%), 0 events +2026-02-04T19:05:12.446076Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37720/133889 blocks (28.2%), 0 events +2026-02-04T19:05:12.639214Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37730/133889 blocks (28.2%), 0 events +2026-02-04T19:05:12.781199Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37740/133889 blocks (28.2%), 0 events +2026-02-04T19:05:13.019969Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37750/133889 blocks (28.2%), 0 events +2026-02-04T19:05:13.236244Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37760/133889 blocks (28.2%), 0 events +2026-02-04T19:05:13.501962Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37770/133889 blocks (28.2%), 0 events +2026-02-04T19:05:13.615322Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37780/133889 blocks (28.2%), 0 events +2026-02-04T19:05:13.834507Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37790/133889 blocks (28.2%), 0 events +2026-02-04T19:05:14.012518Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37800/133889 blocks (28.2%), 0 events +2026-02-04T19:05:14.175140Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37810/133889 blocks (28.2%), 0 events +2026-02-04T19:05:14.529218Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37820/133889 blocks (28.2%), 0 events +2026-02-04T19:05:14.573200Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37830/133889 blocks (28.3%), 0 events +2026-02-04T19:05:14.852129Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37840/133889 blocks (28.3%), 0 events +2026-02-04T19:05:15.055911Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37850/133889 blocks (28.3%), 0 events +2026-02-04T19:05:15.210155Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37860/133889 blocks (28.3%), 0 events +2026-02-04T19:05:15.379561Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37870/133889 blocks (28.3%), 0 events +2026-02-04T19:05:15.650553Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37880/133889 blocks (28.3%), 0 events +2026-02-04T19:05:15.772114Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37890/133889 blocks (28.3%), 0 events +2026-02-04T19:05:16.066597Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37900/133889 blocks (28.3%), 0 events +2026-02-04T19:05:16.261607Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37910/133889 blocks (28.3%), 0 events +2026-02-04T19:05:16.466701Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37920/133889 blocks (28.3%), 0 events +2026-02-04T19:05:16.620908Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37930/133889 blocks (28.3%), 0 events +2026-02-04T19:05:16.810462Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37940/133889 blocks (28.3%), 0 events +2026-02-04T19:05:17.114063Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37950/133889 blocks (28.3%), 0 events +2026-02-04T19:05:17.310868Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37960/133889 blocks (28.4%), 0 events +2026-02-04T19:05:17.420699Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37970/133889 blocks (28.4%), 0 events +2026-02-04T19:05:17.694516Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37980/133889 blocks (28.4%), 0 events +2026-02-04T19:05:17.883900Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37990/133889 blocks (28.4%), 0 events +2026-02-04T19:05:18.022915Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38000/133889 blocks (28.4%), 0 events +2026-02-04T19:05:18.225136Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38010/133889 blocks (28.4%), 0 events +2026-02-04T19:05:18.432052Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38020/133889 blocks (28.4%), 0 events +2026-02-04T19:05:18.721724Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38030/133889 blocks (28.4%), 0 events +2026-02-04T19:05:18.760657Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38040/133889 blocks (28.4%), 0 events +2026-02-04T19:05:19.000178Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38050/133889 blocks (28.4%), 0 events +2026-02-04T19:05:19.243088Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38060/133889 blocks (28.4%), 0 events +2026-02-04T19:05:19.389233Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38070/133889 blocks (28.4%), 0 events +2026-02-04T19:05:19.735345Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38080/133889 blocks (28.4%), 0 events +2026-02-04T19:05:19.774845Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38090/133889 blocks (28.4%), 0 events +2026-02-04T19:05:20.046888Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38100/133889 blocks (28.5%), 0 events +2026-02-04T19:05:20.292176Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38110/133889 blocks (28.5%), 0 events +2026-02-04T19:05:20.418421Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38120/133889 blocks (28.5%), 0 events +2026-02-04T19:05:20.614544Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38130/133889 blocks (28.5%), 0 events +2026-02-04T19:05:20.843652Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38140/133889 blocks (28.5%), 0 events +2026-02-04T19:05:20.989916Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38150/133889 blocks (28.5%), 0 events +2026-02-04T19:05:21.308324Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38160/133889 blocks (28.5%), 0 events +2026-02-04T19:05:21.384743Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38170/133889 blocks (28.5%), 0 events +2026-02-04T19:05:21.615043Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38180/133889 blocks (28.5%), 0 events +2026-02-04T19:05:21.867529Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38190/133889 blocks (28.5%), 0 events +2026-02-04T19:05:21.995636Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38200/133889 blocks (28.5%), 0 events +2026-02-04T19:05:22.265012Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38210/133889 blocks (28.5%), 0 events +2026-02-04T19:05:22.397764Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38220/133889 blocks (28.5%), 0 events +2026-02-04T19:05:22.636403Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38230/133889 blocks (28.6%), 0 events +2026-02-04T19:05:22.916302Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38240/133889 blocks (28.6%), 0 events +2026-02-04T19:05:23.025949Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38250/133889 blocks (28.6%), 0 events +2026-02-04T19:05:23.175657Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38260/133889 blocks (28.6%), 0 events +2026-02-04T19:05:23.449780Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38270/133889 blocks (28.6%), 0 events +2026-02-04T19:05:23.637424Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38280/133889 blocks (28.6%), 0 events +2026-02-04T19:05:23.834169Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38290/133889 blocks (28.6%), 0 events +2026-02-04T19:05:24.000005Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38300/133889 blocks (28.6%), 0 events +2026-02-04T19:05:24.197579Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38310/133889 blocks (28.6%), 0 events +2026-02-04T19:05:24.484463Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38320/133889 blocks (28.6%), 0 events +2026-02-04T19:05:24.618460Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38330/133889 blocks (28.6%), 0 events +2026-02-04T19:05:24.774641Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38340/133889 blocks (28.6%), 0 events +2026-02-04T19:05:25.031066Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38350/133889 blocks (28.6%), 0 events +2026-02-04T19:05:25.217739Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38360/133889 blocks (28.7%), 0 events +2026-02-04T19:05:25.541657Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38370/133889 blocks (28.7%), 0 events +2026-02-04T19:05:25.612027Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38380/133889 blocks (28.7%), 0 events +2026-02-04T19:05:25.841901Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38390/133889 blocks (28.7%), 0 events +2026-02-04T19:05:26.063916Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38400/133889 blocks (28.7%), 0 events +2026-02-04T19:05:26.180315Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38410/133889 blocks (28.7%), 0 events +2026-02-04T19:05:26.394805Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38420/133889 blocks (28.7%), 0 events +2026-02-04T19:05:26.599148Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38430/133889 blocks (28.7%), 0 events +2026-02-04T19:05:26.795360Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38440/133889 blocks (28.7%), 0 events +2026-02-04T19:05:26.982534Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38450/133889 blocks (28.7%), 0 events +2026-02-04T19:05:27.266043Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38460/133889 blocks (28.7%), 0 events +2026-02-04T19:05:27.402128Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38470/133889 blocks (28.7%), 0 events +2026-02-04T19:05:27.653284Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38480/133889 blocks (28.7%), 0 events +2026-02-04T19:05:27.805998Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38490/133889 blocks (28.7%), 0 events +2026-02-04T19:05:27.997352Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38500/133889 blocks (28.8%), 0 events +2026-02-04T19:05:28.193386Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38510/133889 blocks (28.8%), 0 events +2026-02-04T19:05:28.417479Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38520/133889 blocks (28.8%), 0 events +2026-02-04T19:05:28.680822Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38530/133889 blocks (28.8%), 0 events +2026-02-04T19:05:28.847942Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38540/133889 blocks (28.8%), 0 events +2026-02-04T19:05:28.992630Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38550/133889 blocks (28.8%), 0 events +2026-02-04T19:05:29.212401Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38560/133889 blocks (28.8%), 0 events +2026-02-04T19:05:29.429862Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38570/133889 blocks (28.8%), 0 events +2026-02-04T19:05:29.600816Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38580/133889 blocks (28.8%), 0 events +2026-02-04T19:05:29.867416Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38590/133889 blocks (28.8%), 0 events +2026-02-04T19:05:29.988956Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38600/133889 blocks (28.8%), 0 events +2026-02-04T19:05:30.252019Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38610/133889 blocks (28.8%), 0 events +2026-02-04T19:05:30.434118Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38620/133889 blocks (28.8%), 0 events +2026-02-04T19:05:30.643122Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38630/133889 blocks (28.9%), 0 events +2026-02-04T19:05:30.784956Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38640/133889 blocks (28.9%), 0 events +2026-02-04T19:05:31.050159Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38650/133889 blocks (28.9%), 0 events +2026-02-04T19:05:31.467698Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38660/133889 blocks (28.9%), 0 events +2026-02-04T19:05:31.516748Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38670/133889 blocks (28.9%), 0 events +2026-02-04T19:05:31.564899Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38680/133889 blocks (28.9%), 0 events +2026-02-04T19:05:31.863127Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38690/133889 blocks (28.9%), 0 events +2026-02-04T19:05:32.034688Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38700/133889 blocks (28.9%), 0 events +2026-02-04T19:05:32.317907Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38710/133889 blocks (28.9%), 0 events +2026-02-04T19:05:32.363539Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38720/133889 blocks (28.9%), 0 events +2026-02-04T19:05:32.599038Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38730/133889 blocks (28.9%), 0 events +2026-02-04T19:05:32.877244Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38740/133889 blocks (28.9%), 0 events +2026-02-04T19:05:33.038010Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38750/133889 blocks (28.9%), 0 events +2026-02-04T19:05:33.240100Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38760/133889 blocks (28.9%), 0 events +2026-02-04T19:05:33.405534Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38770/133889 blocks (29.0%), 0 events +2026-02-04T19:05:33.595586Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38780/133889 blocks (29.0%), 0 events +2026-02-04T19:05:33.934768Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38790/133889 blocks (29.0%), 0 events +2026-02-04T19:05:34.016481Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38800/133889 blocks (29.0%), 0 events +2026-02-04T19:05:34.231752Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38810/133889 blocks (29.0%), 0 events +2026-02-04T19:05:34.456566Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38820/133889 blocks (29.0%), 0 events +2026-02-04T19:05:34.599174Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38830/133889 blocks (29.0%), 0 events +2026-02-04T19:05:34.820637Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38840/133889 blocks (29.0%), 0 events +2026-02-04T19:05:34.994729Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38850/133889 blocks (29.0%), 0 events +2026-02-04T19:05:35.267658Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38860/133889 blocks (29.0%), 0 events +2026-02-04T19:05:35.464440Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38870/133889 blocks (29.0%), 0 events +2026-02-04T19:05:35.668844Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38880/133889 blocks (29.0%), 0 events +2026-02-04T19:05:35.877449Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38890/133889 blocks (29.0%), 0 events +2026-02-04T19:05:36.066428Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38900/133889 blocks (29.1%), 0 events +2026-02-04T19:05:36.207767Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38910/133889 blocks (29.1%), 0 events +2026-02-04T19:05:36.550790Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38920/133889 blocks (29.1%), 0 events +2026-02-04T19:05:36.588099Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38930/133889 blocks (29.1%), 0 events +2026-02-04T19:05:36.793017Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38940/133889 blocks (29.1%), 0 events +2026-02-04T19:05:37.074436Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38950/133889 blocks (29.1%), 0 events +2026-02-04T19:05:37.223833Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38960/133889 blocks (29.1%), 0 events +2026-02-04T19:05:37.467042Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38970/133889 blocks (29.1%), 0 events +2026-02-04T19:05:37.594287Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38980/133889 blocks (29.1%), 0 events +2026-02-04T19:05:37.869435Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38990/133889 blocks (29.1%), 0 events +2026-02-04T19:05:38.118398Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39000/133889 blocks (29.1%), 0 events +2026-02-04T19:05:38.154935Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39010/133889 blocks (29.1%), 0 events +2026-02-04T19:05:38.430773Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39020/133889 blocks (29.1%), 0 events +2026-02-04T19:05:38.639884Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39030/133889 blocks (29.2%), 0 events +2026-02-04T19:05:38.866035Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39040/133889 blocks (29.2%), 0 events +2026-02-04T19:05:38.968689Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39050/133889 blocks (29.2%), 0 events +2026-02-04T19:05:39.235986Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39060/133889 blocks (29.2%), 0 events +2026-02-04T19:05:39.443557Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39070/133889 blocks (29.2%), 0 events +2026-02-04T19:05:39.657150Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39080/133889 blocks (29.2%), 0 events +2026-02-04T19:05:39.813108Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39090/133889 blocks (29.2%), 0 events +2026-02-04T19:05:40.016826Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39100/133889 blocks (29.2%), 0 events +2026-02-04T19:05:40.220697Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39110/133889 blocks (29.2%), 0 events +2026-02-04T19:05:40.371917Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39120/133889 blocks (29.2%), 0 events +2026-02-04T19:05:40.614317Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39130/133889 blocks (29.2%), 0 events +2026-02-04T19:05:40.852557Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39140/133889 blocks (29.2%), 0 events +2026-02-04T19:05:40.994538Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39150/133889 blocks (29.2%), 0 events +2026-02-04T19:05:41.275488Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39160/133889 blocks (29.2%), 0 events +2026-02-04T19:05:41.388021Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39170/133889 blocks (29.3%), 0 events +2026-02-04T19:05:41.590639Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39180/133889 blocks (29.3%), 0 events +2026-02-04T19:05:41.788730Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39190/133889 blocks (29.3%), 0 events +2026-02-04T19:05:42.066561Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39200/133889 blocks (29.3%), 0 events +2026-02-04T19:05:42.280189Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39210/133889 blocks (29.3%), 0 events +2026-02-04T19:05:42.366824Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39220/133889 blocks (29.3%), 0 events +2026-02-04T19:05:42.624257Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39230/133889 blocks (29.3%), 0 events +2026-02-04T19:05:42.838918Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39240/133889 blocks (29.3%), 0 events +2026-02-04T19:05:43.032211Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39250/133889 blocks (29.3%), 0 events +2026-02-04T19:05:43.182394Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39260/133889 blocks (29.3%), 0 events +2026-02-04T19:05:43.381406Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39270/133889 blocks (29.3%), 0 events +2026-02-04T19:05:43.617833Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39280/133889 blocks (29.3%), 0 events +2026-02-04T19:05:43.852829Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39290/133889 blocks (29.3%), 0 events +2026-02-04T19:05:44.026012Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39300/133889 blocks (29.4%), 0 events +2026-02-04T19:05:44.252661Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39310/133889 blocks (29.4%), 0 events +2026-02-04T19:05:44.431518Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39320/133889 blocks (29.4%), 0 events +2026-02-04T19:05:44.575082Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39330/133889 blocks (29.4%), 0 events +2026-02-04T19:05:44.899901Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39340/133889 blocks (29.4%), 0 events +2026-02-04T19:05:45.058668Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39350/133889 blocks (29.4%), 0 events +2026-02-04T19:05:45.226184Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39360/133889 blocks (29.4%), 0 events +2026-02-04T19:05:45.457950Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39370/133889 blocks (29.4%), 0 events +2026-02-04T19:05:45.624529Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39380/133889 blocks (29.4%), 0 events +2026-02-04T19:05:45.804997Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39390/133889 blocks (29.4%), 0 events +2026-02-04T19:05:45.984473Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39400/133889 blocks (29.4%), 0 events +2026-02-04T19:05:46.231331Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39410/133889 blocks (29.4%), 0 events +2026-02-04T19:05:46.372377Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39420/133889 blocks (29.4%), 0 events +2026-02-04T19:05:46.592238Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39430/133889 blocks (29.4%), 0 events +2026-02-04T19:05:46.842303Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39440/133889 blocks (29.5%), 0 events +2026-02-04T19:05:47.030406Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39450/133889 blocks (29.5%), 0 events +2026-02-04T19:05:47.234751Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39460/133889 blocks (29.5%), 0 events +2026-02-04T19:05:47.419194Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39470/133889 blocks (29.5%), 0 events +2026-02-04T19:05:47.612356Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39480/133889 blocks (29.5%), 0 events +2026-02-04T19:05:47.857896Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39490/133889 blocks (29.5%), 0 events +2026-02-04T19:05:48.080857Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39500/133889 blocks (29.5%), 0 events +2026-02-04T19:05:48.228378Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39510/133889 blocks (29.5%), 0 events +2026-02-04T19:05:48.375040Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39520/133889 blocks (29.5%), 0 events +2026-02-04T19:05:48.673587Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39530/133889 blocks (29.5%), 0 events +2026-02-04T19:05:48.853837Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39540/133889 blocks (29.5%), 0 events +2026-02-04T19:05:49.001401Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39550/133889 blocks (29.5%), 0 events +2026-02-04T19:05:49.190942Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39560/133889 blocks (29.5%), 0 events +2026-02-04T19:05:49.360328Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39570/133889 blocks (29.6%), 0 events +2026-02-04T19:05:49.649339Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39580/133889 blocks (29.6%), 0 events +2026-02-04T19:05:49.792761Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39590/133889 blocks (29.6%), 0 events +2026-02-04T19:05:50.025046Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39600/133889 blocks (29.6%), 0 events +2026-02-04T19:05:50.262478Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39610/133889 blocks (29.6%), 0 events +2026-02-04T19:05:50.418057Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39620/133889 blocks (29.6%), 0 events +2026-02-04T19:05:50.703294Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39630/133889 blocks (29.6%), 0 events +2026-02-04T19:05:50.813746Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39640/133889 blocks (29.6%), 0 events +2026-02-04T19:05:51.061416Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39650/133889 blocks (29.6%), 0 events +2026-02-04T19:05:51.265465Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39660/133889 blocks (29.6%), 0 events +2026-02-04T19:05:51.378921Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39670/133889 blocks (29.6%), 0 events +2026-02-04T19:05:51.604322Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39680/133889 blocks (29.6%), 0 events +2026-02-04T19:05:51.762686Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39690/133889 blocks (29.6%), 0 events +2026-02-04T19:05:51.986325Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39700/133889 blocks (29.7%), 0 events +2026-02-04T19:05:52.273994Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39710/133889 blocks (29.7%), 0 events +2026-02-04T19:05:52.392848Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39720/133889 blocks (29.7%), 0 events +2026-02-04T19:05:52.573483Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39730/133889 blocks (29.7%), 0 events +2026-02-04T19:05:52.868933Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39740/133889 blocks (29.7%), 0 events +2026-02-04T19:05:53.040252Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39750/133889 blocks (29.7%), 0 events +2026-02-04T19:05:53.190349Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39760/133889 blocks (29.7%), 0 events +2026-02-04T19:05:53.466677Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39770/133889 blocks (29.7%), 0 events +2026-02-04T19:05:53.628342Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39780/133889 blocks (29.7%), 0 events +2026-02-04T19:05:53.842802Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39790/133889 blocks (29.7%), 0 events +2026-02-04T19:05:53.969850Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39800/133889 blocks (29.7%), 0 events +2026-02-04T19:05:54.337894Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39810/133889 blocks (29.7%), 0 events +2026-02-04T19:05:54.380199Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39820/133889 blocks (29.7%), 0 events +2026-02-04T19:05:54.618409Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39830/133889 blocks (29.7%), 0 events +2026-02-04T19:05:54.861566Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39840/133889 blocks (29.8%), 0 events +2026-02-04T19:05:55.068799Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39850/133889 blocks (29.8%), 0 events +2026-02-04T19:05:55.239154Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39860/133889 blocks (29.8%), 0 events +2026-02-04T19:05:55.466736Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39870/133889 blocks (29.8%), 0 events +2026-02-04T19:05:55.578108Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39880/133889 blocks (29.8%), 0 events +2026-02-04T19:05:55.912153Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39890/133889 blocks (29.8%), 0 events +2026-02-04T19:05:56.025516Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39900/133889 blocks (29.8%), 0 events +2026-02-04T19:05:56.216331Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39910/133889 blocks (29.8%), 0 events +2026-02-04T19:05:56.468025Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39920/133889 blocks (29.8%), 0 events +2026-02-04T19:05:56.631403Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39930/133889 blocks (29.8%), 0 events +2026-02-04T19:05:56.843814Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39940/133889 blocks (29.8%), 0 events +2026-02-04T19:05:56.994781Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39950/133889 blocks (29.8%), 0 events +2026-02-04T19:05:57.253976Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39960/133889 blocks (29.8%), 0 events +2026-02-04T19:05:57.516426Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39970/133889 blocks (29.9%), 0 events +2026-02-04T19:05:57.599108Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39980/133889 blocks (29.9%), 0 events +2026-02-04T19:05:57.875348Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39990/133889 blocks (29.9%), 0 events +2026-02-04T19:05:58.037906Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40000/133889 blocks (29.9%), 0 events +2026-02-04T19:05:58.228778Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40010/133889 blocks (29.9%), 0 events +2026-02-04T19:05:58.433703Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40020/133889 blocks (29.9%), 0 events +2026-02-04T19:05:58.589694Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40030/133889 blocks (29.9%), 0 events +2026-02-04T19:05:58.811345Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40040/133889 blocks (29.9%), 0 events +2026-02-04T19:05:59.055190Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40050/133889 blocks (29.9%), 0 events +2026-02-04T19:05:59.211592Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40060/133889 blocks (29.9%), 0 events +2026-02-04T19:05:59.369826Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40070/133889 blocks (29.9%), 0 events +2026-02-04T19:05:59.660157Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40080/133889 blocks (29.9%), 0 events +2026-02-04T19:05:59.773729Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40090/133889 blocks (29.9%), 0 events +2026-02-04T19:05:59.990957Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40100/133889 blocks (29.9%), 0 events +2026-02-04T19:06:00.239641Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40110/133889 blocks (30.0%), 0 events +2026-02-04T19:06:00.403984Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40120/133889 blocks (30.0%), 0 events +2026-02-04T19:06:00.660869Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40130/133889 blocks (30.0%), 0 events +2026-02-04T19:06:00.832240Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40140/133889 blocks (30.0%), 0 events +2026-02-04T19:06:01.006401Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40150/133889 blocks (30.0%), 0 events +2026-02-04T19:06:01.188599Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40160/133889 blocks (30.0%), 0 events +2026-02-04T19:06:01.422802Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40170/133889 blocks (30.0%), 0 events +2026-02-04T19:06:01.715271Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40180/133889 blocks (30.0%), 0 events +2026-02-04T19:06:01.829309Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40190/133889 blocks (30.0%), 0 events +2026-02-04T19:06:02.021916Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40200/133889 blocks (30.0%), 0 events +2026-02-04T19:06:02.234694Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40210/133889 blocks (30.0%), 0 events +2026-02-04T19:06:02.409066Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40220/133889 blocks (30.0%), 0 events +2026-02-04T19:06:02.617390Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40230/133889 blocks (30.0%), 0 events +2026-02-04T19:06:02.865865Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40240/133889 blocks (30.1%), 0 events +2026-02-04T19:06:02.976893Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40250/133889 blocks (30.1%), 0 events +2026-02-04T19:06:03.282040Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40260/133889 blocks (30.1%), 0 events +2026-02-04T19:06:03.420056Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40270/133889 blocks (30.1%), 0 events +2026-02-04T19:06:03.660245Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40280/133889 blocks (30.1%), 0 events +2026-02-04T19:06:03.806864Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40290/133889 blocks (30.1%), 0 events +2026-02-04T19:06:04.008265Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40300/133889 blocks (30.1%), 0 events +2026-02-04T19:06:04.334446Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40310/133889 blocks (30.1%), 0 events +2026-02-04T19:06:04.374847Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40320/133889 blocks (30.1%), 0 events +2026-02-04T19:06:04.625559Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40330/133889 blocks (30.1%), 0 events +2026-02-04T19:06:04.854304Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40340/133889 blocks (30.1%), 0 events +2026-02-04T19:06:05.040169Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40350/133889 blocks (30.1%), 0 events +2026-02-04T19:06:05.347121Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40360/133889 blocks (30.1%), 0 events +2026-02-04T19:06:05.399679Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40370/133889 blocks (30.2%), 0 events +2026-02-04T19:06:05.571960Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40380/133889 blocks (30.2%), 0 events +2026-02-04T19:06:05.871002Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40390/133889 blocks (30.2%), 0 events +2026-02-04T19:06:05.999436Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40400/133889 blocks (30.2%), 0 events +2026-02-04T19:06:06.201791Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40410/133889 blocks (30.2%), 0 events +2026-02-04T19:06:06.433290Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40420/133889 blocks (30.2%), 0 events +2026-02-04T19:06:06.659894Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40430/133889 blocks (30.2%), 0 events +2026-02-04T19:06:06.920071Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40440/133889 blocks (30.2%), 0 events +2026-02-04T19:06:06.970910Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40450/133889 blocks (30.2%), 0 events +2026-02-04T19:06:07.164078Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40460/133889 blocks (30.2%), 0 events +2026-02-04T19:06:07.445188Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40470/133889 blocks (30.2%), 0 events +2026-02-04T19:06:07.654311Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40480/133889 blocks (30.2%), 0 events +2026-02-04T19:06:07.861666Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40490/133889 blocks (30.2%), 0 events +2026-02-04T19:06:08.002467Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40500/133889 blocks (30.2%), 0 events +2026-02-04T19:06:08.187641Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40510/133889 blocks (30.3%), 0 events +2026-02-04T19:06:08.529768Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40520/133889 blocks (30.3%), 0 events +2026-02-04T19:06:08.566037Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40530/133889 blocks (30.3%), 0 events +2026-02-04T19:06:08.838105Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40540/133889 blocks (30.3%), 0 events +2026-02-04T19:06:09.049590Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40550/133889 blocks (30.3%), 0 events +2026-02-04T19:06:09.249825Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40560/133889 blocks (30.3%), 0 events +2026-02-04T19:06:09.437456Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40570/133889 blocks (30.3%), 0 events +2026-02-04T19:06:09.579362Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40580/133889 blocks (30.3%), 0 events +2026-02-04T19:06:09.782193Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40590/133889 blocks (30.3%), 0 events +2026-02-04T19:06:10.065355Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40600/133889 blocks (30.3%), 0 events +2026-02-04T19:06:10.213256Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40610/133889 blocks (30.3%), 0 events +2026-02-04T19:06:10.386765Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40620/133889 blocks (30.3%), 0 events +2026-02-04T19:06:10.645042Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40630/133889 blocks (30.3%), 0 events +2026-02-04T19:06:10.852843Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40640/133889 blocks (30.4%), 0 events +2026-02-04T19:06:10.976210Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40650/133889 blocks (30.4%), 0 events +2026-02-04T19:06:11.243041Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40660/133889 blocks (30.4%), 0 events +2026-02-04T19:06:11.469816Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40670/133889 blocks (30.4%), 0 events +2026-02-04T19:06:11.671004Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40680/133889 blocks (30.4%), 0 events +2026-02-04T19:06:11.818283Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40690/133889 blocks (30.4%), 0 events +2026-02-04T19:06:12.049623Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40700/133889 blocks (30.4%), 0 events +2026-02-04T19:06:12.197485Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40710/133889 blocks (30.4%), 0 events +2026-02-04T19:06:12.426586Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40720/133889 blocks (30.4%), 0 events +2026-02-04T19:06:12.591592Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40730/133889 blocks (30.4%), 0 events +2026-02-04T19:06:12.870354Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40740/133889 blocks (30.4%), 0 events +2026-02-04T19:06:13.030391Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40750/133889 blocks (30.4%), 0 events +2026-02-04T19:06:13.245411Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40760/133889 blocks (30.4%), 0 events +2026-02-04T19:06:13.370825Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40770/133889 blocks (30.5%), 0 events +2026-02-04T19:06:13.737231Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40780/133889 blocks (30.5%), 0 events +2026-02-04T19:06:13.775240Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40790/133889 blocks (30.5%), 0 events +2026-02-04T19:06:13.979962Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40800/133889 blocks (30.5%), 0 events +2026-02-04T19:06:14.291350Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40810/133889 blocks (30.5%), 0 events +2026-02-04T19:06:14.429139Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40820/133889 blocks (30.5%), 0 events +2026-02-04T19:06:14.638457Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40830/133889 blocks (30.5%), 0 events +2026-02-04T19:06:14.827920Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40840/133889 blocks (30.5%), 0 events +2026-02-04T19:06:15.056612Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40850/133889 blocks (30.5%), 0 events +2026-02-04T19:06:15.309645Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40860/133889 blocks (30.5%), 0 events +2026-02-04T19:06:15.448635Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40870/133889 blocks (30.5%), 0 events +2026-02-04T19:06:15.590403Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40880/133889 blocks (30.5%), 0 events +2026-02-04T19:06:15.887248Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40890/133889 blocks (30.5%), 0 events +2026-02-04T19:06:15.968067Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40900/133889 blocks (30.5%), 0 events +2026-02-04T19:06:16.191944Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40910/133889 blocks (30.6%), 0 events +2026-02-04T19:06:16.407512Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40920/133889 blocks (30.6%), 0 events +2026-02-04T19:06:16.645023Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40930/133889 blocks (30.6%), 0 events +2026-02-04T19:06:16.926185Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40940/133889 blocks (30.6%), 0 events +2026-02-04T19:06:16.963642Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40950/133889 blocks (30.6%), 0 events +2026-02-04T19:06:17.250313Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40960/133889 blocks (30.6%), 0 events +2026-02-04T19:06:17.444759Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40970/133889 blocks (30.6%), 0 events +2026-02-04T19:06:17.584607Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40980/133889 blocks (30.6%), 0 events +2026-02-04T19:06:17.835944Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40990/133889 blocks (30.6%), 0 events +2026-02-04T19:06:18.016348Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41000/133889 blocks (30.6%), 0 events +2026-02-04T19:06:18.208555Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41010/133889 blocks (30.6%), 0 events +2026-02-04T19:06:18.484675Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41020/133889 blocks (30.6%), 0 events +2026-02-04T19:06:18.654598Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41030/133889 blocks (30.6%), 0 events +2026-02-04T19:06:18.833236Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41040/133889 blocks (30.7%), 0 events +2026-02-04T19:06:19.013899Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41050/133889 blocks (30.7%), 0 events +2026-02-04T19:06:19.267945Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41060/133889 blocks (30.7%), 0 events +2026-02-04T19:06:19.536601Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41070/133889 blocks (30.7%), 0 events +2026-02-04T19:06:19.576384Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41080/133889 blocks (30.7%), 0 events +2026-02-04T19:06:19.817007Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41090/133889 blocks (30.7%), 0 events +2026-02-04T19:06:20.057700Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41100/133889 blocks (30.7%), 0 events +2026-02-04T19:06:20.215392Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41110/133889 blocks (30.7%), 0 events +2026-02-04T19:06:20.387548Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41120/133889 blocks (30.7%), 0 events +2026-02-04T19:06:20.661169Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41130/133889 blocks (30.7%), 0 events +2026-02-04T19:06:20.806041Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41140/133889 blocks (30.7%), 0 events +2026-02-04T19:06:21.110257Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41150/133889 blocks (30.7%), 0 events +2026-02-04T19:06:21.201739Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41160/133889 blocks (30.7%), 0 events +2026-02-04T19:06:21.453322Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41170/133889 blocks (30.7%), 0 events +2026-02-04T19:06:21.645834Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41180/133889 blocks (30.8%), 0 events +2026-02-04T19:06:21.854753Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41190/133889 blocks (30.8%), 0 events +2026-02-04T19:06:21.985301Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41200/133889 blocks (30.8%), 0 events +2026-02-04T19:06:22.252103Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41210/133889 blocks (30.8%), 0 events +2026-02-04T19:06:22.450834Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41220/133889 blocks (30.8%), 0 events +2026-02-04T19:06:22.680499Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41230/133889 blocks (30.8%), 0 events +2026-02-04T19:06:22.796071Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41240/133889 blocks (30.8%), 0 events +2026-02-04T19:06:23.054577Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41250/133889 blocks (30.8%), 0 events +2026-02-04T19:06:23.253642Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41260/133889 blocks (30.8%), 0 events +2026-02-04T19:06:23.396629Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41270/133889 blocks (30.8%), 0 events +2026-02-04T19:06:23.576616Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41280/133889 blocks (30.8%), 0 events +2026-02-04T19:06:23.819362Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41290/133889 blocks (30.8%), 0 events +2026-02-04T19:06:23.978736Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41300/133889 blocks (30.8%), 0 events +2026-02-04T19:06:24.250945Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41310/133889 blocks (30.9%), 0 events +2026-02-04T19:06:24.428320Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41320/133889 blocks (30.9%), 0 events +2026-02-04T19:06:24.650714Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41330/133889 blocks (30.9%), 0 events +2026-02-04T19:06:24.839156Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41340/133889 blocks (30.9%), 0 events +2026-02-04T19:06:24.995397Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41350/133889 blocks (30.9%), 0 events +2026-02-04T19:06:25.269763Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41360/133889 blocks (30.9%), 0 events +2026-02-04T19:06:25.437901Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41370/133889 blocks (30.9%), 0 events +2026-02-04T19:06:25.624474Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41380/133889 blocks (30.9%), 0 events +2026-02-04T19:06:25.828727Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41390/133889 blocks (30.9%), 0 events +2026-02-04T19:06:25.987330Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41400/133889 blocks (30.9%), 0 events +2026-02-04T19:06:26.317040Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41410/133889 blocks (30.9%), 0 events +2026-02-04T19:06:26.409866Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41420/133889 blocks (30.9%), 0 events +2026-02-04T19:06:26.592546Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41430/133889 blocks (30.9%), 0 events +2026-02-04T19:06:26.883881Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41440/133889 blocks (31.0%), 0 events +2026-02-04T19:06:27.042952Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41450/133889 blocks (31.0%), 0 events +2026-02-04T19:06:27.243035Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41460/133889 blocks (31.0%), 0 events +2026-02-04T19:06:27.418556Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41470/133889 blocks (31.0%), 0 events +2026-02-04T19:06:27.571319Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41480/133889 blocks (31.0%), 0 events +2026-02-04T19:06:27.796607Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41490/133889 blocks (31.0%), 0 events +2026-02-04T19:06:28.105418Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41500/133889 blocks (31.0%), 0 events +2026-02-04T19:06:28.234295Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41510/133889 blocks (31.0%), 0 events +2026-02-04T19:06:28.465243Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41520/133889 blocks (31.0%), 0 events +2026-02-04T19:06:28.635596Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41530/133889 blocks (31.0%), 0 events +2026-02-04T19:06:28.836735Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41540/133889 blocks (31.0%), 0 events +2026-02-04T19:06:29.010915Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41550/133889 blocks (31.0%), 0 events +2026-02-04T19:06:29.181761Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41560/133889 blocks (31.0%), 0 events +2026-02-04T19:06:29.463981Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41570/133889 blocks (31.0%), 0 events +2026-02-04T19:06:29.600449Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41580/133889 blocks (31.1%), 0 events +2026-02-04T19:06:29.844963Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41590/133889 blocks (31.1%), 0 events +2026-02-04T19:06:30.061340Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41600/133889 blocks (31.1%), 0 events +2026-02-04T19:06:30.202092Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41610/133889 blocks (31.1%), 0 events +2026-02-04T19:06:30.409053Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41620/133889 blocks (31.1%), 0 events +2026-02-04T19:06:30.596370Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41630/133889 blocks (31.1%), 0 events +2026-02-04T19:06:30.846774Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41640/133889 blocks (31.1%), 0 events +2026-02-04T19:06:31.036422Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41650/133889 blocks (31.1%), 0 events +2026-02-04T19:06:31.183986Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41660/133889 blocks (31.1%), 0 events +2026-02-04T19:06:31.429552Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41670/133889 blocks (31.1%), 0 events +2026-02-04T19:06:31.622521Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41680/133889 blocks (31.1%), 0 events +2026-02-04T19:06:31.777216Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41690/133889 blocks (31.1%), 0 events +2026-02-04T19:06:32.123212Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41700/133889 blocks (31.1%), 0 events +2026-02-04T19:06:32.160803Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41710/133889 blocks (31.2%), 0 events +2026-02-04T19:06:32.401454Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41720/133889 blocks (31.2%), 0 events +2026-02-04T19:06:32.644402Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41730/133889 blocks (31.2%), 0 events +2026-02-04T19:06:32.791514Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41740/133889 blocks (31.2%), 0 events +2026-02-04T19:06:33.133011Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41750/133889 blocks (31.2%), 0 events +2026-02-04T19:06:33.181719Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41760/133889 blocks (31.2%), 0 events +2026-02-04T19:06:33.412635Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41770/133889 blocks (31.2%), 0 events +2026-02-04T19:06:33.659743Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41780/133889 blocks (31.2%), 0 events +2026-02-04T19:06:33.846548Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41790/133889 blocks (31.2%), 0 events +2026-02-04T19:06:34.003137Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41800/133889 blocks (31.2%), 0 events +2026-02-04T19:06:34.221440Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41810/133889 blocks (31.2%), 0 events +2026-02-04T19:06:34.462031Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41820/133889 blocks (31.2%), 0 events +2026-02-04T19:06:34.571267Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41830/133889 blocks (31.2%), 0 events +2026-02-04T19:06:34.902882Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41840/133889 blocks (31.2%), 0 events +2026-02-04T19:06:35.052082Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41850/133889 blocks (31.3%), 0 events +2026-02-04T19:06:35.270981Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41860/133889 blocks (31.3%), 0 events +2026-02-04T19:06:35.469848Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41870/133889 blocks (31.3%), 0 events +2026-02-04T19:06:35.623863Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41880/133889 blocks (31.3%), 0 events +2026-02-04T19:06:35.808264Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41890/133889 blocks (31.3%), 0 events +2026-02-04T19:06:36.051472Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41900/133889 blocks (31.3%), 0 events +2026-02-04T19:06:36.177999Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41910/133889 blocks (31.3%), 0 events +2026-02-04T19:06:36.363262Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41920/133889 blocks (31.3%), 0 events +2026-02-04T19:06:36.665293Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41930/133889 blocks (31.3%), 0 events +2026-02-04T19:06:36.857634Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41940/133889 blocks (31.3%), 0 events +2026-02-04T19:06:37.004892Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41950/133889 blocks (31.3%), 0 events +2026-02-04T19:06:37.178569Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41960/133889 blocks (31.3%), 0 events +2026-02-04T19:06:37.547536Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41970/133889 blocks (31.3%), 0 events +2026-02-04T19:06:37.591396Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41980/133889 blocks (31.4%), 0 events +2026-02-04T19:06:37.907778Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41990/133889 blocks (31.4%), 0 events +2026-02-04T19:06:38.083646Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42000/133889 blocks (31.4%), 0 events +2026-02-04T19:06:38.197454Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42010/133889 blocks (31.4%), 0 events +2026-02-04T19:06:38.408411Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42020/133889 blocks (31.4%), 0 events +2026-02-04T19:06:38.605093Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42030/133889 blocks (31.4%), 0 events +2026-02-04T19:06:38.770237Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42040/133889 blocks (31.4%), 0 events +2026-02-04T19:06:39.035778Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42050/133889 blocks (31.4%), 0 events +2026-02-04T19:06:39.217528Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42060/133889 blocks (31.4%), 0 events +2026-02-04T19:06:39.455969Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42070/133889 blocks (31.4%), 0 events +2026-02-04T19:06:39.653229Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42080/133889 blocks (31.4%), 0 events +2026-02-04T19:06:39.795838Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42090/133889 blocks (31.4%), 0 events +2026-02-04T19:06:40.064280Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42100/133889 blocks (31.4%), 0 events +2026-02-04T19:06:40.246466Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42110/133889 blocks (31.5%), 0 events +2026-02-04T19:06:40.506967Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42120/133889 blocks (31.5%), 0 events +2026-02-04T19:06:40.559145Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42130/133889 blocks (31.5%), 0 events +2026-02-04T19:06:40.770842Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42140/133889 blocks (31.5%), 0 events +2026-02-04T19:06:41.038178Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42150/133889 blocks (31.5%), 0 events +2026-02-04T19:06:41.215187Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42160/133889 blocks (31.5%), 0 events +2026-02-04T19:06:41.422146Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42170/133889 blocks (31.5%), 0 events +2026-02-04T19:06:41.630291Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42180/133889 blocks (31.5%), 0 events +2026-02-04T19:06:41.793156Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42190/133889 blocks (31.5%), 0 events +2026-02-04T19:06:42.094356Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42200/133889 blocks (31.5%), 0 events +2026-02-04T19:06:42.219156Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42210/133889 blocks (31.5%), 0 events +2026-02-04T19:06:42.405869Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42220/133889 blocks (31.5%), 0 events +2026-02-04T19:06:42.654703Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42230/133889 blocks (31.5%), 0 events +2026-02-04T19:06:42.846467Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42240/133889 blocks (31.5%), 0 events +2026-02-04T19:06:43.130050Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42250/133889 blocks (31.6%), 0 events +2026-02-04T19:06:43.171104Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42260/133889 blocks (31.6%), 0 events +2026-02-04T19:06:43.395398Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42270/133889 blocks (31.6%), 0 events +2026-02-04T19:06:43.667253Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42280/133889 blocks (31.6%), 0 events +2026-02-04T19:06:43.843549Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42290/133889 blocks (31.6%), 0 events +2026-02-04T19:06:44.142611Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42300/133889 blocks (31.6%), 0 events +2026-02-04T19:06:44.178222Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42310/133889 blocks (31.6%), 0 events +2026-02-04T19:06:44.451473Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42320/133889 blocks (31.6%), 0 events +2026-02-04T19:06:44.666122Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42330/133889 blocks (31.6%), 0 events +2026-02-04T19:06:44.861902Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42340/133889 blocks (31.6%), 0 events +2026-02-04T19:06:44.985434Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42350/133889 blocks (31.6%), 0 events +2026-02-04T19:06:45.228142Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42360/133889 blocks (31.6%), 0 events +2026-02-04T19:06:45.421758Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42370/133889 blocks (31.6%), 0 events +2026-02-04T19:06:45.579839Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42380/133889 blocks (31.7%), 0 events +2026-02-04T19:06:45.810075Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42390/133889 blocks (31.7%), 0 events +2026-02-04T19:06:46.047860Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42400/133889 blocks (31.7%), 0 events +2026-02-04T19:06:46.239002Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42410/133889 blocks (31.7%), 0 events +2026-02-04T19:06:46.411326Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42420/133889 blocks (31.7%), 0 events +2026-02-04T19:06:46.619511Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42430/133889 blocks (31.7%), 0 events +2026-02-04T19:06:46.803371Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42440/133889 blocks (31.7%), 0 events +2026-02-04T19:06:47.042701Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42450/133889 blocks (31.7%), 0 events +2026-02-04T19:06:47.333656Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42460/133889 blocks (31.7%), 0 events +2026-02-04T19:06:47.379177Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42470/133889 blocks (31.7%), 0 events +2026-02-04T19:06:47.629385Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42480/133889 blocks (31.7%), 0 events +2026-02-04T19:06:47.853397Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42490/133889 blocks (31.7%), 0 events +2026-02-04T19:06:47.979150Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42500/133889 blocks (31.7%), 0 events +2026-02-04T19:06:48.179287Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42510/133889 blocks (31.7%), 0 events +2026-02-04T19:06:48.460480Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42520/133889 blocks (31.8%), 0 events +2026-02-04T19:06:48.581826Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42530/133889 blocks (31.8%), 0 events +2026-02-04T19:06:48.891682Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42540/133889 blocks (31.8%), 0 events +2026-02-04T19:06:49.043912Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42550/133889 blocks (31.8%), 0 events +2026-02-04T19:06:49.187637Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42560/133889 blocks (31.8%), 0 events +2026-02-04T19:06:49.421270Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42570/133889 blocks (31.8%), 0 events +2026-02-04T19:06:49.633231Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42580/133889 blocks (31.8%), 0 events +2026-02-04T19:06:49.802916Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42590/133889 blocks (31.8%), 0 events +2026-02-04T19:06:49.996642Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42600/133889 blocks (31.8%), 0 events +2026-02-04T19:06:50.188155Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42610/133889 blocks (31.8%), 0 events +2026-02-04T19:06:50.466743Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42620/133889 blocks (31.8%), 0 events +2026-02-04T19:06:50.645197Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42630/133889 blocks (31.8%), 0 events +2026-02-04T19:06:50.773207Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42640/133889 blocks (31.8%), 0 events +2026-02-04T19:06:51.024492Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42650/133889 blocks (31.9%), 0 events +2026-02-04T19:06:51.220174Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42660/133889 blocks (31.9%), 0 events +2026-02-04T19:06:51.512781Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42670/133889 blocks (31.9%), 0 events +2026-02-04T19:06:51.664899Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42680/133889 blocks (31.9%), 0 events +2026-02-04T19:06:51.833736Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42690/133889 blocks (31.9%), 0 events +2026-02-04T19:06:52.040947Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42700/133889 blocks (31.9%), 0 events +2026-02-04T19:06:52.219213Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42710/133889 blocks (31.9%), 0 events +2026-02-04T19:06:52.531645Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42720/133889 blocks (31.9%), 0 events +2026-02-04T19:06:52.569520Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42730/133889 blocks (31.9%), 0 events +2026-02-04T19:06:52.782162Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42740/133889 blocks (31.9%), 0 events +2026-02-04T19:06:53.085721Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42750/133889 blocks (31.9%), 0 events +2026-02-04T19:06:53.197791Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42760/133889 blocks (31.9%), 0 events +2026-02-04T19:06:53.486422Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42770/133889 blocks (31.9%), 0 events +2026-02-04T19:06:53.637484Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42780/133889 blocks (32.0%), 0 events +2026-02-04T19:06:53.784323Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42790/133889 blocks (32.0%), 0 events +2026-02-04T19:06:53.981050Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42800/133889 blocks (32.0%), 0 events +2026-02-04T19:06:54.254324Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42810/133889 blocks (32.0%), 0 events +2026-02-04T19:06:54.431813Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42820/133889 blocks (32.0%), 0 events +2026-02-04T19:06:54.662383Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42830/133889 blocks (32.0%), 0 events +2026-02-04T19:06:54.830429Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42840/133889 blocks (32.0%), 0 events +2026-02-04T19:06:55.033589Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42850/133889 blocks (32.0%), 0 events +2026-02-04T19:06:55.216735Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42860/133889 blocks (32.0%), 0 events +2026-02-04T19:06:55.375539Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42870/133889 blocks (32.0%), 0 events +2026-02-04T19:06:55.723914Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42880/133889 blocks (32.0%), 0 events +2026-02-04T19:06:55.769375Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42890/133889 blocks (32.0%), 0 events +2026-02-04T19:06:55.969688Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42900/133889 blocks (32.0%), 0 events +2026-02-04T19:06:56.236735Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42910/133889 blocks (32.0%), 0 events +2026-02-04T19:06:56.367629Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42920/133889 blocks (32.1%), 0 events +2026-02-04T19:06:56.602223Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42930/133889 blocks (32.1%), 0 events +2026-02-04T19:06:56.844364Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42940/133889 blocks (32.1%), 0 events +2026-02-04T19:06:57.033979Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42950/133889 blocks (32.1%), 0 events +2026-02-04T19:06:57.283569Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42960/133889 blocks (32.1%), 0 events +2026-02-04T19:06:57.428412Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42970/133889 blocks (32.1%), 0 events +2026-02-04T19:06:57.628004Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42980/133889 blocks (32.1%), 0 events +2026-02-04T19:06:57.812332Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42990/133889 blocks (32.1%), 0 events +2026-02-04T19:06:58.064488Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43000/133889 blocks (32.1%), 0 events +2026-02-04T19:06:58.338679Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43010/133889 blocks (32.1%), 0 events +2026-02-04T19:06:58.378240Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43020/133889 blocks (32.1%), 0 events +2026-02-04T19:06:58.580983Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43030/133889 blocks (32.1%), 0 events +2026-02-04T19:06:58.854640Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43040/133889 blocks (32.1%), 0 events +2026-02-04T19:06:58.986503Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43050/133889 blocks (32.2%), 0 events +2026-02-04T19:06:59.230180Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43060/133889 blocks (32.2%), 0 events +2026-02-04T19:06:59.453976Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43070/133889 blocks (32.2%), 0 events +2026-02-04T19:06:59.571318Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43080/133889 blocks (32.2%), 0 events +2026-02-04T19:06:59.871142Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43090/133889 blocks (32.2%), 0 events +2026-02-04T19:07:00.024975Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43100/133889 blocks (32.2%), 0 events +2026-02-04T19:07:00.221603Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43110/133889 blocks (32.2%), 0 events +2026-02-04T19:07:00.439864Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43120/133889 blocks (32.2%), 0 events +2026-02-04T19:07:00.640022Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43130/133889 blocks (32.2%), 0 events +2026-02-04T19:07:00.789481Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43140/133889 blocks (32.2%), 0 events +2026-02-04T19:07:01.048720Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43150/133889 blocks (32.2%), 0 events +2026-02-04T19:07:01.212069Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43160/133889 blocks (32.2%), 0 events +2026-02-04T19:07:01.444368Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43170/133889 blocks (32.2%), 0 events +2026-02-04T19:07:01.577779Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43180/133889 blocks (32.3%), 0 events +2026-02-04T19:07:01.817052Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43190/133889 blocks (32.3%), 0 events +2026-02-04T19:07:01.998908Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43200/133889 blocks (32.3%), 0 events +2026-02-04T19:07:02.208426Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43210/133889 blocks (32.3%), 0 events +2026-02-04T19:07:02.525366Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43220/133889 blocks (32.3%), 0 events +2026-02-04T19:07:02.563396Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43230/133889 blocks (32.3%), 0 events +2026-02-04T19:07:02.848925Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43240/133889 blocks (32.3%), 0 events +2026-02-04T19:07:03.064116Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43250/133889 blocks (32.3%), 0 events +2026-02-04T19:07:03.241601Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43260/133889 blocks (32.3%), 0 events +2026-02-04T19:07:03.395210Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43270/133889 blocks (32.3%), 0 events +2026-02-04T19:07:03.589548Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43280/133889 blocks (32.3%), 0 events +2026-02-04T19:07:03.809792Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43290/133889 blocks (32.3%), 0 events +2026-02-04T19:07:04.100959Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43300/133889 blocks (32.3%), 0 events +2026-02-04T19:07:04.219392Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43310/133889 blocks (32.3%), 0 events +2026-02-04T19:07:04.405070Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43320/133889 blocks (32.4%), 0 events +2026-02-04T19:07:04.628894Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43330/133889 blocks (32.4%), 0 events +2026-02-04T19:07:04.806265Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43340/133889 blocks (32.4%), 0 events +2026-02-04T19:07:05.113254Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43350/133889 blocks (32.4%), 0 events +2026-02-04T19:07:05.189527Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43360/133889 blocks (32.4%), 0 events +2026-02-04T19:07:05.374957Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43370/133889 blocks (32.4%), 0 events +2026-02-04T19:07:05.674628Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43380/133889 blocks (32.4%), 0 events +2026-02-04T19:07:05.831907Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43390/133889 blocks (32.4%), 0 events +2026-02-04T19:07:05.979868Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43400/133889 blocks (32.4%), 0 events +2026-02-04T19:07:06.204997Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43410/133889 blocks (32.4%), 0 events +2026-02-04T19:07:06.382736Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43420/133889 blocks (32.4%), 0 events +2026-02-04T19:07:06.576317Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43430/133889 blocks (32.4%), 0 events +2026-02-04T19:07:06.793321Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43440/133889 blocks (32.4%), 0 events +2026-02-04T19:07:06.988058Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43450/133889 blocks (32.5%), 0 events +2026-02-04T19:07:07.269762Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43460/133889 blocks (32.5%), 0 events +2026-02-04T19:07:07.388532Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43470/133889 blocks (32.5%), 0 events +2026-02-04T19:07:07.567834Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43480/133889 blocks (32.5%), 0 events +2026-02-04T19:07:07.852867Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43490/133889 blocks (32.5%), 0 events +2026-02-04T19:07:07.986111Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43500/133889 blocks (32.5%), 0 events +2026-02-04T19:07:08.261224Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43510/133889 blocks (32.5%), 0 events +2026-02-04T19:07:08.379068Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43520/133889 blocks (32.5%), 0 events +2026-02-04T19:07:08.664454Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43530/133889 blocks (32.5%), 0 events +2026-02-04T19:07:08.855219Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43540/133889 blocks (32.5%), 0 events +2026-02-04T19:07:08.976298Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43550/133889 blocks (32.5%), 0 events +2026-02-04T19:07:09.180922Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43560/133889 blocks (32.5%), 0 events +2026-02-04T19:07:09.433188Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43570/133889 blocks (32.5%), 0 events +2026-02-04T19:07:09.662137Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43580/133889 blocks (32.5%), 0 events +2026-02-04T19:07:09.865206Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43590/133889 blocks (32.6%), 0 events +2026-02-04T19:07:10.017028Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43600/133889 blocks (32.6%), 0 events +2026-02-04T19:07:10.225899Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43610/133889 blocks (32.6%), 0 events +2026-02-04T19:07:10.387506Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43620/133889 blocks (32.6%), 0 events +2026-02-04T19:07:10.645367Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43630/133889 blocks (32.6%), 0 events +2026-02-04T19:07:10.879769Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43640/133889 blocks (32.6%), 0 events +2026-02-04T19:07:10.986660Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43650/133889 blocks (32.6%), 0 events +2026-02-04T19:07:11.206871Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43660/133889 blocks (32.6%), 0 events +2026-02-04T19:07:11.442385Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43670/133889 blocks (32.6%), 0 events +2026-02-04T19:07:11.633964Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43680/133889 blocks (32.6%), 0 events +2026-02-04T19:07:11.784329Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43690/133889 blocks (32.6%), 0 events +2026-02-04T19:07:12.015880Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43700/133889 blocks (32.6%), 0 events +2026-02-04T19:07:12.230790Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43710/133889 blocks (32.6%), 0 events +2026-02-04T19:07:12.499643Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43720/133889 blocks (32.7%), 0 events +2026-02-04T19:07:12.616031Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43730/133889 blocks (32.7%), 0 events +2026-02-04T19:07:12.811582Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43740/133889 blocks (32.7%), 0 events +2026-02-04T19:07:13.054649Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43750/133889 blocks (32.7%), 0 events +2026-02-04T19:07:13.201629Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43760/133889 blocks (32.7%), 0 events +2026-02-04T19:07:13.377109Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43770/133889 blocks (32.7%), 0 events +2026-02-04T19:07:13.621423Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43780/133889 blocks (32.7%), 0 events +2026-02-04T19:07:13.866875Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43790/133889 blocks (32.7%), 0 events +2026-02-04T19:07:14.060661Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43800/133889 blocks (32.7%), 0 events +2026-02-04T19:07:14.245350Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43810/133889 blocks (32.7%), 0 events +2026-02-04T19:07:14.435441Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43820/133889 blocks (32.7%), 0 events +2026-02-04T19:07:14.586490Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43830/133889 blocks (32.7%), 0 events +2026-02-04T19:07:14.861725Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43840/133889 blocks (32.7%), 0 events +2026-02-04T19:07:15.075243Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43850/133889 blocks (32.8%), 0 events +2026-02-04T19:07:15.183054Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43860/133889 blocks (32.8%), 0 events +2026-02-04T19:07:15.377012Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43870/133889 blocks (32.8%), 0 events +2026-02-04T19:07:15.654280Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43880/133889 blocks (32.8%), 0 events +2026-02-04T19:07:15.826100Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43890/133889 blocks (32.8%), 0 events +2026-02-04T19:07:15.983915Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43900/133889 blocks (32.8%), 0 events +2026-02-04T19:07:16.173996Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43910/133889 blocks (32.8%), 0 events +2026-02-04T19:07:16.385762Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43920/133889 blocks (32.8%), 0 events +2026-02-04T19:07:16.729809Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43930/133889 blocks (32.8%), 0 events +2026-02-04T19:07:16.768992Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43940/133889 blocks (32.8%), 0 events +2026-02-04T19:07:17.020703Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43950/133889 blocks (32.8%), 0 events +2026-02-04T19:07:17.205603Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43960/133889 blocks (32.8%), 0 events +2026-02-04T19:07:17.368037Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43970/133889 blocks (32.8%), 0 events +2026-02-04T19:07:17.596795Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43980/133889 blocks (32.8%), 0 events +2026-02-04T19:07:17.803599Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43990/133889 blocks (32.9%), 0 events +2026-02-04T19:07:18.011647Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44000/133889 blocks (32.9%), 0 events +2026-02-04T19:07:18.256697Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44010/133889 blocks (32.9%), 0 events +2026-02-04T19:07:18.454797Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44020/133889 blocks (32.9%), 0 events +2026-02-04T19:07:18.568235Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44030/133889 blocks (32.9%), 0 events +2026-02-04T19:07:18.816191Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44040/133889 blocks (32.9%), 0 events +2026-02-04T19:07:18.978428Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44050/133889 blocks (32.9%), 0 events +2026-02-04T19:07:19.268701Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44060/133889 blocks (32.9%), 0 events +2026-02-04T19:07:19.415355Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44070/133889 blocks (32.9%), 0 events +2026-02-04T19:07:19.637445Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44080/133889 blocks (32.9%), 0 events +2026-02-04T19:07:19.828373Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44090/133889 blocks (32.9%), 0 events +2026-02-04T19:07:20.024896Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44100/133889 blocks (32.9%), 0 events +2026-02-04T19:07:20.173426Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44110/133889 blocks (32.9%), 0 events +2026-02-04T19:07:20.427717Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44120/133889 blocks (33.0%), 0 events +2026-02-04T19:07:20.588748Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44130/133889 blocks (33.0%), 0 events +2026-02-04T19:07:20.879427Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44140/133889 blocks (33.0%), 0 events +2026-02-04T19:07:20.970274Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44150/133889 blocks (33.0%), 0 events +2026-02-04T19:07:21.183547Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44160/133889 blocks (33.0%), 0 events +2026-02-04T19:07:21.433687Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44170/133889 blocks (33.0%), 0 events +2026-02-04T19:07:21.571358Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44180/133889 blocks (33.0%), 0 events +2026-02-04T19:07:21.889833Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44190/133889 blocks (33.0%), 0 events +2026-02-04T19:07:21.975975Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44200/133889 blocks (33.0%), 0 events +2026-02-04T19:07:22.212188Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44210/133889 blocks (33.0%), 0 events +2026-02-04T19:07:22.445236Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44220/133889 blocks (33.0%), 0 events +2026-02-04T19:07:22.651221Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44230/133889 blocks (33.0%), 0 events +2026-02-04T19:07:22.940306Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44240/133889 blocks (33.0%), 0 events +2026-02-04T19:07:22.983637Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44250/133889 blocks (33.0%), 0 events +2026-02-04T19:07:23.215721Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44260/133889 blocks (33.1%), 0 events +2026-02-04T19:07:23.499183Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44270/133889 blocks (33.1%), 0 events +2026-02-04T19:07:23.641117Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44280/133889 blocks (33.1%), 0 events +2026-02-04T19:07:23.794009Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44290/133889 blocks (33.1%), 0 events +2026-02-04T19:07:24.053354Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44300/133889 blocks (33.1%), 0 events +2026-02-04T19:07:24.237101Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44310/133889 blocks (33.1%), 0 events +2026-02-04T19:07:24.418888Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44320/133889 blocks (33.1%), 0 events +2026-02-04T19:07:24.647196Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44330/133889 blocks (33.1%), 0 events +2026-02-04T19:07:24.807100Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44340/133889 blocks (33.1%), 0 events +2026-02-04T19:07:25.072913Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44350/133889 blocks (33.1%), 0 events +2026-02-04T19:07:25.241576Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44360/133889 blocks (33.1%), 0 events +2026-02-04T19:07:25.447028Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44370/133889 blocks (33.1%), 0 events +2026-02-04T19:07:25.626588Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44380/133889 blocks (33.1%), 0 events +2026-02-04T19:07:25.812823Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44390/133889 blocks (33.2%), 0 events +2026-02-04T19:07:25.986725Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44400/133889 blocks (33.2%), 0 events +2026-02-04T19:07:26.188127Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44410/133889 blocks (33.2%), 0 events +2026-02-04T19:07:26.412656Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44420/133889 blocks (33.2%), 0 events +2026-02-04T19:07:26.654212Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44430/133889 blocks (33.2%), 0 events +2026-02-04T19:07:26.819469Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44440/133889 blocks (33.2%), 0 events +2026-02-04T19:07:27.027131Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44450/133889 blocks (33.2%), 0 events +2026-02-04T19:07:27.262983Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44460/133889 blocks (33.2%), 0 events +2026-02-04T19:07:27.460068Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44470/133889 blocks (33.2%), 0 events +2026-02-04T19:07:27.686165Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44480/133889 blocks (33.2%), 0 events +2026-02-04T19:07:27.774409Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44490/133889 blocks (33.2%), 0 events +2026-02-04T19:07:28.043026Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44500/133889 blocks (33.2%), 0 events +2026-02-04T19:07:28.217140Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44510/133889 blocks (33.2%), 0 events +2026-02-04T19:07:28.377482Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44520/133889 blocks (33.3%), 0 events +2026-02-04T19:07:28.744371Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44530/133889 blocks (33.3%), 0 events +2026-02-04T19:07:28.786784Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44540/133889 blocks (33.3%), 0 events +2026-02-04T19:07:28.964933Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44550/133889 blocks (33.3%), 0 events +2026-02-04T19:07:29.228630Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44560/133889 blocks (33.3%), 0 events +2026-02-04T19:07:29.650441Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44570/133889 blocks (33.3%), 0 events +2026-02-04T19:07:29.754328Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44580/133889 blocks (33.3%), 0 events +2026-02-04T19:07:29.794172Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44590/133889 blocks (33.3%), 0 events +2026-02-04T19:07:29.995375Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44600/133889 blocks (33.3%), 0 events +2026-02-04T19:07:30.318843Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44610/133889 blocks (33.3%), 0 events +2026-02-04T19:07:30.358787Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44620/133889 blocks (33.3%), 0 events +2026-02-04T19:07:30.619104Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44630/133889 blocks (33.3%), 0 events +2026-02-04T19:07:30.860711Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44640/133889 blocks (33.3%), 0 events +2026-02-04T19:07:30.969701Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44650/133889 blocks (33.3%), 0 events +2026-02-04T19:07:31.210430Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44660/133889 blocks (33.4%), 0 events +2026-02-04T19:07:31.415726Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44670/133889 blocks (33.4%), 0 events +2026-02-04T19:07:31.596736Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44680/133889 blocks (33.4%), 0 events +2026-02-04T19:07:31.882280Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44690/133889 blocks (33.4%), 0 events +2026-02-04T19:07:32.015221Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44700/133889 blocks (33.4%), 0 events +2026-02-04T19:07:32.192371Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44710/133889 blocks (33.4%), 0 events +2026-02-04T19:07:32.476437Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44720/133889 blocks (33.4%), 0 events +2026-02-04T19:07:32.640282Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44730/133889 blocks (33.4%), 0 events +2026-02-04T19:07:32.787920Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44740/133889 blocks (33.4%), 0 events +2026-02-04T19:07:33.032968Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44750/133889 blocks (33.4%), 0 events +2026-02-04T19:07:33.203677Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44760/133889 blocks (33.4%), 0 events +2026-02-04T19:07:33.464393Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44770/133889 blocks (33.4%), 0 events +2026-02-04T19:07:33.559976Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44780/133889 blocks (33.4%), 0 events +2026-02-04T19:07:33.828956Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44790/133889 blocks (33.5%), 0 events +2026-02-04T19:07:33.980989Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44800/133889 blocks (33.5%), 0 events +2026-02-04T19:07:34.261897Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44810/133889 blocks (33.5%), 0 events +2026-02-04T19:07:34.376026Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44820/133889 blocks (33.5%), 0 events +2026-02-04T19:07:34.582314Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44830/133889 blocks (33.5%), 0 events +2026-02-04T19:07:34.770963Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44840/133889 blocks (33.5%), 0 events +2026-02-04T19:07:35.030731Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44850/133889 blocks (33.5%), 0 events +2026-02-04T19:07:35.186434Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44860/133889 blocks (33.5%), 0 events +2026-02-04T19:07:35.561950Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44870/133889 blocks (33.5%), 0 events +2026-02-04T19:07:35.602534Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44880/133889 blocks (33.5%), 0 events +2026-02-04T19:07:35.851825Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44890/133889 blocks (33.5%), 0 events +2026-02-04T19:07:36.084075Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44900/133889 blocks (33.5%), 0 events +2026-02-04T19:07:36.259798Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44910/133889 blocks (33.5%), 0 events +2026-02-04T19:07:36.425371Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44920/133889 blocks (33.5%), 0 events +2026-02-04T19:07:36.603072Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44930/133889 blocks (33.6%), 0 events +2026-02-04T19:07:36.804180Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44940/133889 blocks (33.6%), 0 events +2026-02-04T19:07:37.093670Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44950/133889 blocks (33.6%), 0 events +2026-02-04T19:07:37.193880Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44960/133889 blocks (33.6%), 0 events +2026-02-04T19:07:37.375794Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44970/133889 blocks (33.6%), 0 events +2026-02-04T19:07:37.649681Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44980/133889 blocks (33.6%), 0 events +2026-02-04T19:07:37.817738Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44990/133889 blocks (33.6%), 0 events +2026-02-04T19:07:37.977945Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45000/133889 blocks (33.6%), 0 events +2026-02-04T19:07:38.210067Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45010/133889 blocks (33.6%), 0 events +2026-02-04T19:07:38.388908Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45020/133889 blocks (33.6%), 0 events +2026-02-04T19:07:38.698959Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45030/133889 blocks (33.6%), 0 events +2026-02-04T19:07:38.768930Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45040/133889 blocks (33.6%), 0 events +2026-02-04T19:07:39.002913Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45050/133889 blocks (33.6%), 0 events +2026-02-04T19:07:39.222440Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45060/133889 blocks (33.7%), 0 events +2026-02-04T19:07:39.417509Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45070/133889 blocks (33.7%), 0 events +2026-02-04T19:07:39.714723Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45080/133889 blocks (33.7%), 0 events +2026-02-04T19:07:39.808261Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45090/133889 blocks (33.7%), 0 events +2026-02-04T19:07:40.012497Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45100/133889 blocks (33.7%), 0 events +2026-02-04T19:07:40.275598Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45110/133889 blocks (33.7%), 0 events +2026-02-04T19:07:40.437215Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45120/133889 blocks (33.7%), 0 events +2026-02-04T19:07:40.574687Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45130/133889 blocks (33.7%), 0 events +2026-02-04T19:07:40.804361Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45140/133889 blocks (33.7%), 0 events +2026-02-04T19:07:40.989224Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45150/133889 blocks (33.7%), 0 events +2026-02-04T19:07:41.290535Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45160/133889 blocks (33.7%), 0 events +2026-02-04T19:07:41.406022Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45170/133889 blocks (33.7%), 0 events +2026-02-04T19:07:41.592526Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45180/133889 blocks (33.7%), 0 events +2026-02-04T19:07:41.851005Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45190/133889 blocks (33.8%), 0 events +2026-02-04T19:07:42.034383Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45200/133889 blocks (33.8%), 0 events +2026-02-04T19:07:42.190339Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45210/133889 blocks (33.8%), 0 events +2026-02-04T19:07:42.372760Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45220/133889 blocks (33.8%), 0 events +2026-02-04T19:07:42.654007Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45230/133889 blocks (33.8%), 0 events +2026-02-04T19:07:42.859338Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45240/133889 blocks (33.8%), 0 events +2026-02-04T19:07:43.053995Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45250/133889 blocks (33.8%), 0 events +2026-02-04T19:07:43.170368Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45260/133889 blocks (33.8%), 0 events +2026-02-04T19:07:43.445590Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45270/133889 blocks (33.8%), 0 events +2026-02-04T19:07:43.578070Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45280/133889 blocks (33.8%), 0 events +2026-02-04T19:07:43.908876Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45290/133889 blocks (33.8%), 0 events +2026-02-04T19:07:44.103074Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45300/133889 blocks (33.8%), 0 events +2026-02-04T19:07:44.232976Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45310/133889 blocks (33.8%), 0 events +2026-02-04T19:07:44.468494Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45320/133889 blocks (33.8%), 0 events +2026-02-04T19:07:44.661807Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45330/133889 blocks (33.9%), 0 events +2026-02-04T19:07:44.806542Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45340/133889 blocks (33.9%), 0 events +2026-02-04T19:07:44.999873Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45350/133889 blocks (33.9%), 0 events +2026-02-04T19:07:45.224560Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45360/133889 blocks (33.9%), 0 events +2026-02-04T19:07:45.367922Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45370/133889 blocks (33.9%), 0 events +2026-02-04T19:07:45.567592Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45380/133889 blocks (33.9%), 0 events +2026-02-04T19:07:45.831848Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45390/133889 blocks (33.9%), 0 events +2026-02-04T19:07:46.038727Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45400/133889 blocks (33.9%), 0 events +2026-02-04T19:07:46.191552Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45410/133889 blocks (33.9%), 0 events +2026-02-04T19:07:46.381330Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45420/133889 blocks (33.9%), 0 events +2026-02-04T19:07:46.657957Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45430/133889 blocks (33.9%), 0 events +2026-02-04T19:07:46.839141Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45440/133889 blocks (33.9%), 0 events +2026-02-04T19:07:47.083672Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45450/133889 blocks (33.9%), 0 events +2026-02-04T19:07:47.289032Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45460/133889 blocks (34.0%), 0 events +2026-02-04T19:07:47.391716Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45470/133889 blocks (34.0%), 0 events +2026-02-04T19:07:47.625698Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45480/133889 blocks (34.0%), 0 events +2026-02-04T19:07:47.814166Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45490/133889 blocks (34.0%), 0 events +2026-02-04T19:07:47.985143Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45500/133889 blocks (34.0%), 0 events +2026-02-04T19:07:48.330592Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45510/133889 blocks (34.0%), 0 events +2026-02-04T19:07:48.367951Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45520/133889 blocks (34.0%), 0 events +2026-02-04T19:07:48.659744Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45530/133889 blocks (34.0%), 0 events +2026-02-04T19:07:48.851848Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45540/133889 blocks (34.0%), 0 events +2026-02-04T19:07:48.997996Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45550/133889 blocks (34.0%), 0 events +2026-02-04T19:07:49.211621Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45560/133889 blocks (34.0%), 0 events +2026-02-04T19:07:49.403832Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45570/133889 blocks (34.0%), 0 events +2026-02-04T19:07:49.710789Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45580/133889 blocks (34.0%), 0 events +2026-02-04T19:07:49.901544Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45590/133889 blocks (34.1%), 0 events +2026-02-04T19:07:49.996440Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45600/133889 blocks (34.1%), 0 events +2026-02-04T19:07:50.247826Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45610/133889 blocks (34.1%), 0 events +2026-02-04T19:07:50.429993Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45620/133889 blocks (34.1%), 0 events +2026-02-04T19:07:50.722773Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45630/133889 blocks (34.1%), 0 events +2026-02-04T19:07:50.815352Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45640/133889 blocks (34.1%), 0 events +2026-02-04T19:07:51.003868Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45650/133889 blocks (34.1%), 0 events +2026-02-04T19:07:51.288704Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45660/133889 blocks (34.1%), 0 events +2026-02-04T19:07:51.483039Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45670/133889 blocks (34.1%), 0 events +2026-02-04T19:07:51.605357Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45680/133889 blocks (34.1%), 0 events +2026-02-04T19:07:51.808286Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45690/133889 blocks (34.1%), 0 events +2026-02-04T19:07:52.021781Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45700/133889 blocks (34.1%), 0 events +2026-02-04T19:07:52.331788Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45710/133889 blocks (34.1%), 0 events +2026-02-04T19:07:52.367577Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45720/133889 blocks (34.1%), 0 events +2026-02-04T19:07:52.655455Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45730/133889 blocks (34.2%), 0 events +2026-02-04T19:07:52.851395Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45740/133889 blocks (34.2%), 0 events +2026-02-04T19:07:53.051347Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45750/133889 blocks (34.2%), 0 events +2026-02-04T19:07:53.246419Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45760/133889 blocks (34.2%), 0 events +2026-02-04T19:07:53.408198Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45770/133889 blocks (34.2%), 0 events +2026-02-04T19:07:53.620701Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45780/133889 blocks (34.2%), 0 events +2026-02-04T19:07:53.867694Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45790/133889 blocks (34.2%), 0 events +2026-02-04T19:07:54.065019Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45800/133889 blocks (34.2%), 0 events +2026-02-04T19:07:54.165579Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45810/133889 blocks (34.2%), 0 events +2026-02-04T19:07:54.428299Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45820/133889 blocks (34.2%), 0 events +2026-02-04T19:07:54.565883Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45830/133889 blocks (34.2%), 0 events +2026-02-04T19:07:54.822732Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45840/133889 blocks (34.2%), 0 events +2026-02-04T19:07:55.032129Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45850/133889 blocks (34.2%), 0 events +2026-02-04T19:07:55.256423Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45860/133889 blocks (34.3%), 0 events +2026-02-04T19:07:55.478249Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45870/133889 blocks (34.3%), 0 events +2026-02-04T19:07:55.657866Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45880/133889 blocks (34.3%), 0 events +2026-02-04T19:07:55.764293Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45890/133889 blocks (34.3%), 0 events +2026-02-04T19:07:56.005651Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45900/133889 blocks (34.3%), 0 events +2026-02-04T19:07:56.258189Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45910/133889 blocks (34.3%), 0 events +2026-02-04T19:07:56.524846Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45920/133889 blocks (34.3%), 0 events +2026-02-04T19:07:56.559816Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45930/133889 blocks (34.3%), 0 events +2026-02-04T19:07:56.797432Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45940/133889 blocks (34.3%), 0 events +2026-02-04T19:07:57.043790Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45950/133889 blocks (34.3%), 0 events +2026-02-04T19:07:57.226045Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45960/133889 blocks (34.3%), 0 events +2026-02-04T19:07:57.406917Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45970/133889 blocks (34.3%), 0 events +2026-02-04T19:07:57.579652Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45980/133889 blocks (34.3%), 0 events +2026-02-04T19:07:57.859562Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45990/133889 blocks (34.3%), 0 events +2026-02-04T19:07:58.118372Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46000/133889 blocks (34.4%), 0 events +2026-02-04T19:07:58.158934Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46010/133889 blocks (34.4%), 0 events +2026-02-04T19:07:58.384433Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46020/133889 blocks (34.4%), 0 events +2026-02-04T19:07:58.645768Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46030/133889 blocks (34.4%), 0 events +2026-02-04T19:07:58.837607Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46040/133889 blocks (34.4%), 0 events +2026-02-04T19:07:59.109986Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46050/133889 blocks (34.4%), 0 events +2026-02-04T19:07:59.243784Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46060/133889 blocks (34.4%), 0 events +2026-02-04T19:07:59.427805Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46070/133889 blocks (34.4%), 0 events +2026-02-04T19:07:59.664431Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46080/133889 blocks (34.4%), 0 events +2026-02-04T19:07:59.803546Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46090/133889 blocks (34.4%), 0 events +2026-02-04T19:08:00.001108Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46100/133889 blocks (34.4%), 0 events +2026-02-04T19:08:00.192965Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46110/133889 blocks (34.4%), 0 events +2026-02-04T19:08:00.416599Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46120/133889 blocks (34.4%), 0 events +2026-02-04T19:08:00.716822Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46130/133889 blocks (34.5%), 0 events +2026-02-04T19:08:00.782018Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46140/133889 blocks (34.5%), 0 events +2026-02-04T19:08:00.977552Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46150/133889 blocks (34.5%), 0 events +2026-02-04T19:08:01.250026Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46160/133889 blocks (34.5%), 0 events +2026-02-04T19:08:01.409778Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46170/133889 blocks (34.5%), 0 events +2026-02-04T19:08:01.602458Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46180/133889 blocks (34.5%), 0 events +2026-02-04T19:08:01.818816Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46190/133889 blocks (34.5%), 0 events +2026-02-04T19:08:02.043138Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46200/133889 blocks (34.5%), 0 events +2026-02-04T19:08:02.258552Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46210/133889 blocks (34.5%), 0 events +2026-02-04T19:08:02.407671Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46220/133889 blocks (34.5%), 0 events +2026-02-04T19:08:02.869174Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46230/133889 blocks (34.5%), 0 events +2026-02-04T19:08:02.910406Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46240/133889 blocks (34.5%), 0 events +2026-02-04T19:08:03.040475Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46250/133889 blocks (34.5%), 0 events +2026-02-04T19:08:03.305069Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46260/133889 blocks (34.6%), 0 events +2026-02-04T19:08:03.368995Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46270/133889 blocks (34.6%), 0 events +2026-02-04T19:08:03.622808Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46280/133889 blocks (34.6%), 0 events +2026-02-04T19:08:03.859525Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46290/133889 blocks (34.6%), 0 events +2026-02-04T19:08:04.029506Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46300/133889 blocks (34.6%), 0 events +2026-02-04T19:08:04.186317Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46310/133889 blocks (34.6%), 0 events +2026-02-04T19:08:04.389190Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46320/133889 blocks (34.6%), 0 events +2026-02-04T19:08:04.615108Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46330/133889 blocks (34.6%), 0 events +2026-02-04T19:08:04.772519Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46340/133889 blocks (34.6%), 0 events +2026-02-04T19:08:05.036548Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46350/133889 blocks (34.6%), 0 events +2026-02-04T19:08:05.184695Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46360/133889 blocks (34.6%), 0 events +2026-02-04T19:08:05.458281Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46370/133889 blocks (34.6%), 0 events +2026-02-04T19:08:05.589515Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46380/133889 blocks (34.6%), 0 events +2026-02-04T19:08:05.810752Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46390/133889 blocks (34.6%), 0 events +2026-02-04T19:08:05.978219Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46400/133889 blocks (34.7%), 0 events +2026-02-04T19:08:06.164759Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46410/133889 blocks (34.7%), 0 events +2026-02-04T19:08:06.486249Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46420/133889 blocks (34.7%), 0 events +2026-02-04T19:08:06.598053Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46430/133889 blocks (34.7%), 0 events +2026-02-04T19:08:06.776922Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46440/133889 blocks (34.7%), 0 events +2026-02-04T19:08:07.009846Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46450/133889 blocks (34.7%), 0 events +2026-02-04T19:08:07.262288Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46460/133889 blocks (34.7%), 0 events +2026-02-04T19:08:07.375742Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46470/133889 blocks (34.7%), 0 events +2026-02-04T19:08:07.592289Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46480/133889 blocks (34.7%), 0 events +2026-02-04T19:08:07.810134Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46490/133889 blocks (34.7%), 0 events +2026-02-04T19:08:08.062046Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46500/133889 blocks (34.7%), 0 events +2026-02-04T19:08:08.252551Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46510/133889 blocks (34.7%), 0 events +2026-02-04T19:08:08.456399Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46520/133889 blocks (34.7%), 0 events +2026-02-04T19:08:08.658175Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46530/133889 blocks (34.8%), 0 events +2026-02-04T19:08:08.796143Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46540/133889 blocks (34.8%), 0 events +2026-02-04T19:08:08.973006Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46550/133889 blocks (34.8%), 0 events +2026-02-04T19:08:09.313125Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46560/133889 blocks (34.8%), 0 events +2026-02-04T19:08:09.444996Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46570/133889 blocks (34.8%), 0 events +2026-02-04T19:08:09.630903Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46580/133889 blocks (34.8%), 0 events +2026-02-04T19:08:09.827524Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46590/133889 blocks (34.8%), 0 events +2026-02-04T19:08:09.991581Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46600/133889 blocks (34.8%), 0 events +2026-02-04T19:08:10.216332Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46610/133889 blocks (34.8%), 0 events +2026-02-04T19:08:10.458808Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46620/133889 blocks (34.8%), 0 events +2026-02-04T19:08:10.680677Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46630/133889 blocks (34.8%), 0 events +2026-02-04T19:08:10.875757Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46640/133889 blocks (34.8%), 0 events +2026-02-04T19:08:11.024702Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46650/133889 blocks (34.8%), 0 events +2026-02-04T19:08:11.210706Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46660/133889 blocks (34.8%), 0 events +2026-02-04T19:08:11.421888Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46670/133889 blocks (34.9%), 0 events +2026-02-04T19:08:11.693463Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46680/133889 blocks (34.9%), 0 events +2026-02-04T19:08:11.843620Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46690/133889 blocks (34.9%), 0 events +2026-02-04T19:08:12.026221Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46700/133889 blocks (34.9%), 0 events +2026-02-04T19:08:12.252023Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46710/133889 blocks (34.9%), 0 events +2026-02-04T19:08:12.381696Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46720/133889 blocks (34.9%), 0 events +2026-02-04T19:08:12.607835Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46730/133889 blocks (34.9%), 0 events +2026-02-04T19:08:12.834385Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46740/133889 blocks (34.9%), 0 events +2026-02-04T19:08:12.997037Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46750/133889 blocks (34.9%), 0 events +2026-02-04T19:08:13.266787Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46760/133889 blocks (34.9%), 0 events +2026-02-04T19:08:13.384397Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46770/133889 blocks (34.9%), 0 events +2026-02-04T19:08:13.610295Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46780/133889 blocks (34.9%), 0 events +2026-02-04T19:08:13.830888Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46790/133889 blocks (34.9%), 0 events +2026-02-04T19:08:13.972492Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46800/133889 blocks (35.0%), 0 events +2026-02-04T19:08:14.316299Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46810/133889 blocks (35.0%), 0 events +2026-02-04T19:08:14.513893Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46820/133889 blocks (35.0%), 0 events +2026-02-04T19:08:14.577982Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46830/133889 blocks (35.0%), 0 events +2026-02-04T19:08:14.875931Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46840/133889 blocks (35.0%), 0 events +2026-02-04T19:08:15.074452Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46850/133889 blocks (35.0%), 0 events +2026-02-04T19:08:15.266664Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46860/133889 blocks (35.0%), 0 events +2026-02-04T19:08:15.444912Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46870/133889 blocks (35.0%), 0 events +2026-02-04T19:08:15.599096Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46880/133889 blocks (35.0%), 0 events +2026-02-04T19:08:15.889324Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46890/133889 blocks (35.0%), 0 events +2026-02-04T19:08:15.971894Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46900/133889 blocks (35.0%), 0 events +2026-02-04T19:08:16.230630Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46910/133889 blocks (35.0%), 0 events +2026-02-04T19:08:16.468165Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46920/133889 blocks (35.0%), 0 events +2026-02-04T19:08:16.615018Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46930/133889 blocks (35.1%), 0 events +2026-02-04T19:08:16.838190Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46940/133889 blocks (35.1%), 0 events +2026-02-04T19:08:17.013649Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46950/133889 blocks (35.1%), 0 events +2026-02-04T19:08:17.172315Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46960/133889 blocks (35.1%), 0 events +2026-02-04T19:08:17.463005Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46970/133889 blocks (35.1%), 0 events +2026-02-04T19:08:17.653536Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46980/133889 blocks (35.1%), 0 events +2026-02-04T19:08:17.786213Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46990/133889 blocks (35.1%), 0 events +2026-02-04T19:08:18.022247Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47000/133889 blocks (35.1%), 0 events +2026-02-04T19:08:18.252747Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47010/133889 blocks (35.1%), 0 events +2026-02-04T19:08:18.363283Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47020/133889 blocks (35.1%), 0 events +2026-02-04T19:08:18.604996Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47030/133889 blocks (35.1%), 0 events +2026-02-04T19:08:18.799869Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47040/133889 blocks (35.1%), 0 events +2026-02-04T19:08:19.077967Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47050/133889 blocks (35.1%), 0 events +2026-02-04T19:08:19.193844Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47060/133889 blocks (35.1%), 0 events +2026-02-04T19:08:19.398082Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47070/133889 blocks (35.2%), 0 events +2026-02-04T19:08:19.624855Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47080/133889 blocks (35.2%), 0 events +2026-02-04T19:08:19.830266Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47090/133889 blocks (35.2%), 0 events +2026-02-04T19:08:19.992984Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47100/133889 blocks (35.2%), 0 events +2026-02-04T19:08:20.195877Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47110/133889 blocks (35.2%), 0 events +2026-02-04T19:08:20.374218Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47120/133889 blocks (35.2%), 0 events +2026-02-04T19:08:20.638042Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47130/133889 blocks (35.2%), 0 events +2026-02-04T19:08:20.792821Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47140/133889 blocks (35.2%), 0 events +2026-02-04T19:08:21.028806Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47150/133889 blocks (35.2%), 0 events +2026-02-04T19:08:21.248399Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47160/133889 blocks (35.2%), 0 events +2026-02-04T19:08:21.390230Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47170/133889 blocks (35.2%), 0 events +2026-02-04T19:08:21.698543Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47180/133889 blocks (35.2%), 0 events +2026-02-04T19:08:21.817588Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47190/133889 blocks (35.2%), 0 events +2026-02-04T19:08:21.990519Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47200/133889 blocks (35.3%), 0 events +2026-02-04T19:08:22.218462Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47210/133889 blocks (35.3%), 0 events +2026-02-04T19:08:22.444762Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47220/133889 blocks (35.3%), 0 events +2026-02-04T19:08:22.604081Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47230/133889 blocks (35.3%), 0 events +2026-02-04T19:08:22.789632Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47240/133889 blocks (35.3%), 0 events +2026-02-04T19:08:23.010782Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47250/133889 blocks (35.3%), 0 events +2026-02-04T19:08:23.260980Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47260/133889 blocks (35.3%), 0 events +2026-02-04T19:08:23.382666Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47270/133889 blocks (35.3%), 0 events +2026-02-04T19:08:23.627989Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47280/133889 blocks (35.3%), 0 events +2026-02-04T19:08:23.840357Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47290/133889 blocks (35.3%), 0 events +2026-02-04T19:08:24.019787Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47300/133889 blocks (35.3%), 0 events +2026-02-04T19:08:24.310456Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47310/133889 blocks (35.3%), 0 events +2026-02-04T19:08:24.453952Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47320/133889 blocks (35.3%), 0 events +2026-02-04T19:08:24.604967Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47330/133889 blocks (35.3%), 0 events +2026-02-04T19:08:24.836135Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47340/133889 blocks (35.4%), 0 events +2026-02-04T19:08:25.058209Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47350/133889 blocks (35.4%), 0 events +2026-02-04T19:08:25.324512Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47360/133889 blocks (35.4%), 0 events +2026-02-04T19:08:25.372480Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47370/133889 blocks (35.4%), 0 events +2026-02-04T19:08:25.597218Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47380/133889 blocks (35.4%), 0 events +2026-02-04T19:08:25.882699Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47390/133889 blocks (35.4%), 0 events +2026-02-04T19:08:25.985561Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47400/133889 blocks (35.4%), 0 events +2026-02-04T19:08:26.221810Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47410/133889 blocks (35.4%), 0 events +2026-02-04T19:08:26.417495Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47420/133889 blocks (35.4%), 0 events +2026-02-04T19:08:26.646003Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47430/133889 blocks (35.4%), 0 events +2026-02-04T19:08:26.767009Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47440/133889 blocks (35.4%), 0 events +2026-02-04T19:08:27.017018Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47450/133889 blocks (35.4%), 0 events +2026-02-04T19:08:27.228833Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47460/133889 blocks (35.4%), 0 events +2026-02-04T19:08:27.465293Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47470/133889 blocks (35.5%), 0 events +2026-02-04T19:08:27.626437Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47480/133889 blocks (35.5%), 0 events +2026-02-04T19:08:27.811090Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47490/133889 blocks (35.5%), 0 events +2026-02-04T19:08:27.981760Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47500/133889 blocks (35.5%), 0 events +2026-02-04T19:08:28.172055Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47510/133889 blocks (35.5%), 0 events +2026-02-04T19:08:28.510131Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47520/133889 blocks (35.5%), 0 events +2026-02-04T19:08:28.624772Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47530/133889 blocks (35.5%), 0 events +2026-02-04T19:08:28.805989Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47540/133889 blocks (35.5%), 0 events +2026-02-04T19:08:29.025437Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47550/133889 blocks (35.5%), 0 events +2026-02-04T19:08:29.234614Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47560/133889 blocks (35.5%), 0 events +2026-02-04T19:08:29.369709Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47570/133889 blocks (35.5%), 0 events +2026-02-04T19:08:29.649347Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47580/133889 blocks (35.5%), 0 events +2026-02-04T19:08:29.807001Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47590/133889 blocks (35.5%), 0 events +2026-02-04T19:08:30.078073Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47600/133889 blocks (35.6%), 0 events +2026-02-04T19:08:30.257424Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47610/133889 blocks (35.6%), 0 events +2026-02-04T19:08:30.433235Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47620/133889 blocks (35.6%), 0 events +2026-02-04T19:08:30.635139Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47630/133889 blocks (35.6%), 0 events +2026-02-04T19:08:30.855266Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47640/133889 blocks (35.6%), 0 events +2026-02-04T19:08:31.195032Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47650/133889 blocks (35.6%), 0 events +2026-02-04T19:08:31.234499Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47660/133889 blocks (35.6%), 0 events +2026-02-04T19:08:31.402773Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47670/133889 blocks (35.6%), 0 events +2026-02-04T19:08:31.657172Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47680/133889 blocks (35.6%), 0 events +2026-02-04T19:08:31.848236Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47690/133889 blocks (35.6%), 0 events +2026-02-04T19:08:31.977546Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47700/133889 blocks (35.6%), 0 events +2026-02-04T19:08:32.192599Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47710/133889 blocks (35.6%), 0 events +2026-02-04T19:08:32.423780Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47720/133889 blocks (35.6%), 0 events +2026-02-04T19:08:32.699088Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47730/133889 blocks (35.6%), 0 events +2026-02-04T19:08:32.776059Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47740/133889 blocks (35.7%), 0 events +2026-02-04T19:08:32.962912Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47750/133889 blocks (35.7%), 0 events +2026-02-04T19:08:33.220416Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47760/133889 blocks (35.7%), 0 events +2026-02-04T19:08:33.367459Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47770/133889 blocks (35.7%), 0 events +2026-02-04T19:08:33.714576Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47780/133889 blocks (35.7%), 0 events +2026-02-04T19:08:33.806854Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47790/133889 blocks (35.7%), 0 events +2026-02-04T19:08:34.015624Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47800/133889 blocks (35.7%), 0 events +2026-02-04T19:08:34.269951Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47810/133889 blocks (35.7%), 0 events +2026-02-04T19:08:34.391001Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47820/133889 blocks (35.7%), 0 events +2026-02-04T19:08:34.575502Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47830/133889 blocks (35.7%), 0 events +2026-02-04T19:08:34.835664Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47840/133889 blocks (35.7%), 0 events +2026-02-04T19:08:35.029286Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47850/133889 blocks (35.7%), 0 events +2026-02-04T19:08:35.338744Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47860/133889 blocks (35.7%), 0 events +2026-02-04T19:08:35.373542Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47870/133889 blocks (35.8%), 0 events +2026-02-04T19:08:35.575605Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47880/133889 blocks (35.8%), 0 events +2026-02-04T19:08:35.843003Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47890/133889 blocks (35.8%), 0 events +2026-02-04T19:08:36.022815Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47900/133889 blocks (35.8%), 0 events +2026-02-04T19:08:36.207066Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47910/133889 blocks (35.8%), 0 events +2026-02-04T19:08:36.446369Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47920/133889 blocks (35.8%), 0 events +2026-02-04T19:08:36.566769Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47930/133889 blocks (35.8%), 0 events +2026-02-04T19:08:36.860252Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47940/133889 blocks (35.8%), 0 events +2026-02-04T19:08:37.005534Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47950/133889 blocks (35.8%), 0 events +2026-02-04T19:08:37.260157Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47960/133889 blocks (35.8%), 0 events +2026-02-04T19:08:37.431314Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47970/133889 blocks (35.8%), 0 events +2026-02-04T19:08:37.621894Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47980/133889 blocks (35.8%), 0 events +2026-02-04T19:08:37.909079Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47990/133889 blocks (35.8%), 0 events +2026-02-04T19:08:37.961201Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48000/133889 blocks (35.9%), 0 events +2026-02-04T19:08:38.213565Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48010/133889 blocks (35.9%), 0 events +2026-02-04T19:08:38.470165Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48020/133889 blocks (35.9%), 0 events +2026-02-04T19:08:38.647871Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48030/133889 blocks (35.9%), 0 events +2026-02-04T19:08:38.835793Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48040/133889 blocks (35.9%), 0 events +2026-02-04T19:08:38.991697Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48050/133889 blocks (35.9%), 0 events +2026-02-04T19:08:39.188120Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48060/133889 blocks (35.9%), 0 events +2026-02-04T19:08:39.381365Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48070/133889 blocks (35.9%), 0 events +2026-02-04T19:08:39.599581Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48080/133889 blocks (35.9%), 0 events +2026-02-04T19:08:39.861460Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48090/133889 blocks (35.9%), 0 events +2026-02-04T19:08:40.046141Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48100/133889 blocks (35.9%), 0 events +2026-02-04T19:08:40.208430Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48110/133889 blocks (35.9%), 0 events +2026-02-04T19:08:40.388888Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48120/133889 blocks (35.9%), 0 events +2026-02-04T19:08:40.655823Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48130/133889 blocks (35.9%), 0 events +2026-02-04T19:08:40.780177Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48140/133889 blocks (36.0%), 0 events +2026-02-04T19:08:41.089023Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48150/133889 blocks (36.0%), 0 events +2026-02-04T19:08:41.217534Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48160/133889 blocks (36.0%), 0 events +2026-02-04T19:08:41.401744Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48170/133889 blocks (36.0%), 0 events +2026-02-04T19:08:41.617333Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48180/133889 blocks (36.0%), 0 events +2026-02-04T19:08:41.786366Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48190/133889 blocks (36.0%), 0 events +2026-02-04T19:08:41.998256Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48200/133889 blocks (36.0%), 0 events +2026-02-04T19:08:42.173887Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48210/133889 blocks (36.0%), 0 events +2026-02-04T19:08:42.434001Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48220/133889 blocks (36.0%), 0 events +2026-02-04T19:08:42.660349Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48230/133889 blocks (36.0%), 0 events +2026-02-04T19:08:42.816729Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48240/133889 blocks (36.0%), 0 events +2026-02-04T19:08:42.982219Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48250/133889 blocks (36.0%), 0 events +2026-02-04T19:08:43.185152Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48260/133889 blocks (36.0%), 0 events +2026-02-04T19:08:43.427968Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48270/133889 blocks (36.1%), 0 events +2026-02-04T19:08:43.706795Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48280/133889 blocks (36.1%), 0 events +2026-02-04T19:08:43.840888Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48290/133889 blocks (36.1%), 0 events +2026-02-04T19:08:44.020991Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48300/133889 blocks (36.1%), 0 events +2026-02-04T19:08:44.230387Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48310/133889 blocks (36.1%), 0 events +2026-02-04T19:08:44.385420Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48320/133889 blocks (36.1%), 0 events +2026-02-04T19:08:44.605092Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48330/133889 blocks (36.1%), 0 events +2026-02-04T19:08:44.785919Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48340/133889 blocks (36.1%), 0 events +2026-02-04T19:08:45.031232Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48350/133889 blocks (36.1%), 0 events +2026-02-04T19:08:45.250655Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48360/133889 blocks (36.1%), 0 events +2026-02-04T19:08:45.476625Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48370/133889 blocks (36.1%), 0 events +2026-02-04T19:08:45.593572Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48380/133889 blocks (36.1%), 0 events +2026-02-04T19:08:45.814592Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48390/133889 blocks (36.1%), 0 events +2026-02-04T19:08:46.000749Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48400/133889 blocks (36.1%), 0 events +2026-02-04T19:08:46.296653Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48410/133889 blocks (36.2%), 0 events +2026-02-04T19:08:46.359781Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48420/133889 blocks (36.2%), 0 events +2026-02-04T19:08:46.590473Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48430/133889 blocks (36.2%), 0 events +2026-02-04T19:08:46.862236Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48440/133889 blocks (36.2%), 0 events +2026-02-04T19:08:47.059841Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48450/133889 blocks (36.2%), 0 events +2026-02-04T19:08:47.213311Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48460/133889 blocks (36.2%), 0 events +2026-02-04T19:08:47.541958Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48470/133889 blocks (36.2%), 0 events +2026-02-04T19:08:47.586074Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48480/133889 blocks (36.2%), 0 events +2026-02-04T19:08:47.900612Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48490/133889 blocks (36.2%), 0 events +2026-02-04T19:08:47.960117Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48500/133889 blocks (36.2%), 0 events +2026-02-04T19:08:48.170229Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48510/133889 blocks (36.2%), 0 events +2026-02-04T19:08:48.423202Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48520/133889 blocks (36.2%), 0 events +2026-02-04T19:08:48.626019Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48530/133889 blocks (36.2%), 0 events +2026-02-04T19:08:48.816234Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48540/133889 blocks (36.3%), 0 events +2026-02-04T19:08:49.115500Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48550/133889 blocks (36.3%), 0 events +2026-02-04T19:08:49.174618Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48560/133889 blocks (36.3%), 0 events +2026-02-04T19:08:49.475074Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48570/133889 blocks (36.3%), 0 events +2026-02-04T19:08:49.670680Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48580/133889 blocks (36.3%), 0 events +2026-02-04T19:08:49.776252Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48590/133889 blocks (36.3%), 0 events +2026-02-04T19:08:50.004953Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48600/133889 blocks (36.3%), 0 events +2026-02-04T19:08:50.197303Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48610/133889 blocks (36.3%), 0 events +2026-02-04T19:08:50.391133Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48620/133889 blocks (36.3%), 0 events +2026-02-04T19:08:50.592587Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48630/133889 blocks (36.3%), 0 events +2026-02-04T19:08:50.805606Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48640/133889 blocks (36.3%), 0 events +2026-02-04T19:08:51.054589Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48650/133889 blocks (36.3%), 0 events +2026-02-04T19:08:51.419984Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48660/133889 blocks (36.3%), 0 events +2026-02-04T19:08:51.539558Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48670/133889 blocks (36.4%), 0 events +2026-02-04T19:08:51.579550Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48680/133889 blocks (36.4%), 0 events +2026-02-04T19:08:51.800085Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48690/133889 blocks (36.4%), 0 events +2026-02-04T19:08:51.972622Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48700/133889 blocks (36.4%), 0 events +2026-02-04T19:08:52.189079Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48710/133889 blocks (36.4%), 0 events +2026-02-04T19:08:52.359970Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48720/133889 blocks (36.4%), 0 events +2026-02-04T19:08:52.629710Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48730/133889 blocks (36.4%), 0 events +2026-02-04T19:08:52.806496Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48740/133889 blocks (36.4%), 0 events +2026-02-04T19:08:52.962405Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48750/133889 blocks (36.4%), 0 events +2026-02-04T19:08:53.211925Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48760/133889 blocks (36.4%), 0 events +2026-02-04T19:08:53.429444Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48770/133889 blocks (36.4%), 0 events +2026-02-04T19:08:53.670208Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48780/133889 blocks (36.4%), 0 events +2026-02-04T19:08:53.864901Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48790/133889 blocks (36.4%), 0 events +2026-02-04T19:08:54.060999Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48800/133889 blocks (36.4%), 0 events +2026-02-04T19:08:54.253485Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48810/133889 blocks (36.5%), 0 events +2026-02-04T19:08:54.391341Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48820/133889 blocks (36.5%), 0 events +2026-02-04T19:08:54.685016Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48830/133889 blocks (36.5%), 0 events +2026-02-04T19:08:54.881843Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48840/133889 blocks (36.5%), 0 events +2026-02-04T19:08:54.998717Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48850/133889 blocks (36.5%), 0 events +2026-02-04T19:08:55.251522Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48860/133889 blocks (36.5%), 0 events +2026-02-04T19:08:55.407109Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48870/133889 blocks (36.5%), 0 events +2026-02-04T19:08:55.584931Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48880/133889 blocks (36.5%), 0 events +2026-02-04T19:08:55.769471Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48890/133889 blocks (36.5%), 0 events +2026-02-04T19:08:56.015355Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48900/133889 blocks (36.5%), 0 events +2026-02-04T19:08:56.295241Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48910/133889 blocks (36.5%), 0 events +2026-02-04T19:08:56.413290Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48920/133889 blocks (36.5%), 0 events +2026-02-04T19:08:56.649281Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48930/133889 blocks (36.5%), 0 events +2026-02-04T19:08:56.813645Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48940/133889 blocks (36.6%), 0 events +2026-02-04T19:08:56.979306Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48950/133889 blocks (36.6%), 0 events +2026-02-04T19:08:57.196515Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48960/133889 blocks (36.6%), 0 events +2026-02-04T19:08:57.455850Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48970/133889 blocks (36.6%), 0 events +2026-02-04T19:08:57.612910Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48980/133889 blocks (36.6%), 0 events +2026-02-04T19:08:57.859247Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48990/133889 blocks (36.6%), 0 events +2026-02-04T19:08:58.038407Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49000/133889 blocks (36.6%), 0 events +2026-02-04T19:08:58.248349Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49010/133889 blocks (36.6%), 0 events +2026-02-04T19:08:58.390420Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49020/133889 blocks (36.6%), 0 events +2026-02-04T19:08:58.580519Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49030/133889 blocks (36.6%), 0 events +2026-02-04T19:08:58.778671Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49040/133889 blocks (36.6%), 0 events +2026-02-04T19:08:58.987449Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49050/133889 blocks (36.6%), 0 events +2026-02-04T19:08:59.209216Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49060/133889 blocks (36.6%), 0 events +2026-02-04T19:08:59.437028Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49070/133889 blocks (36.6%), 0 events +2026-02-04T19:08:59.631704Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49080/133889 blocks (36.7%), 0 events +2026-02-04T19:08:59.789508Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49090/133889 blocks (36.7%), 0 events +2026-02-04T19:09:00.037470Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49100/133889 blocks (36.7%), 0 events +2026-02-04T19:09:00.219825Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49110/133889 blocks (36.7%), 0 events +2026-02-04T19:09:00.453400Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49120/133889 blocks (36.7%), 0 events +2026-02-04T19:09:00.655534Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49130/133889 blocks (36.7%), 0 events +2026-02-04T19:09:00.759501Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49140/133889 blocks (36.7%), 0 events +2026-02-04T19:09:01.045606Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49150/133889 blocks (36.7%), 0 events +2026-02-04T19:09:01.172016Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49160/133889 blocks (36.7%), 0 events +2026-02-04T19:09:01.370796Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49170/133889 blocks (36.7%), 0 events +2026-02-04T19:09:01.619653Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49180/133889 blocks (36.7%), 0 events +2026-02-04T19:09:01.780005Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49190/133889 blocks (36.7%), 0 events +2026-02-04T19:09:02.066872Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49200/133889 blocks (36.7%), 0 events +2026-02-04T19:09:02.169757Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49210/133889 blocks (36.8%), 0 events +2026-02-04T19:09:02.424548Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49220/133889 blocks (36.8%), 0 events +2026-02-04T19:09:02.593708Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49230/133889 blocks (36.8%), 0 events +2026-02-04T19:09:02.815570Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49240/133889 blocks (36.8%), 0 events +2026-02-04T19:09:03.104733Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49250/133889 blocks (36.8%), 0 events +2026-02-04T19:09:03.251063Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49260/133889 blocks (36.8%), 0 events +2026-02-04T19:09:03.423010Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49270/133889 blocks (36.8%), 0 events +2026-02-04T19:09:03.650484Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49280/133889 blocks (36.8%), 0 events +2026-02-04T19:09:03.818066Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49290/133889 blocks (36.8%), 0 events +2026-02-04T19:09:04.120751Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49300/133889 blocks (36.8%), 0 events +2026-02-04T19:09:04.159592Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49310/133889 blocks (36.8%), 0 events +2026-02-04T19:09:04.448211Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49320/133889 blocks (36.8%), 0 events +2026-02-04T19:09:04.646211Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49330/133889 blocks (36.8%), 0 events +2026-02-04T19:09:04.783875Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49340/133889 blocks (36.9%), 0 events +2026-02-04T19:09:05.035042Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49350/133889 blocks (36.9%), 0 events +2026-02-04T19:09:05.204676Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49360/133889 blocks (36.9%), 0 events +2026-02-04T19:09:05.392694Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49370/133889 blocks (36.9%), 0 events +2026-02-04T19:09:05.726292Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49380/133889 blocks (36.9%), 0 events +2026-02-04T19:09:05.766353Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49390/133889 blocks (36.9%), 0 events +2026-02-04T19:09:06.004882Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49400/133889 blocks (36.9%), 0 events +2026-02-04T19:09:06.254105Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49410/133889 blocks (36.9%), 0 events +2026-02-04T19:09:06.444521Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49420/133889 blocks (36.9%), 0 events +2026-02-04T19:09:06.570596Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49430/133889 blocks (36.9%), 0 events +2026-02-04T19:09:06.800772Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49440/133889 blocks (36.9%), 0 events +2026-02-04T19:09:07.044982Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49450/133889 blocks (36.9%), 0 events +2026-02-04T19:09:07.267810Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49460/133889 blocks (36.9%), 0 events +2026-02-04T19:09:07.448637Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49470/133889 blocks (36.9%), 0 events +2026-02-04T19:09:07.642935Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49480/133889 blocks (37.0%), 0 events +2026-02-04T19:09:07.824458Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49490/133889 blocks (37.0%), 0 events +2026-02-04T19:09:08.040017Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49500/133889 blocks (37.0%), 0 events +2026-02-04T19:09:08.219626Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49510/133889 blocks (37.0%), 0 events +2026-02-04T19:09:08.459390Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49520/133889 blocks (37.0%), 0 events +2026-02-04T19:09:08.605338Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49530/133889 blocks (37.0%), 0 events +2026-02-04T19:09:08.841020Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49540/133889 blocks (37.0%), 0 events +2026-02-04T19:09:09.041260Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49550/133889 blocks (37.0%), 0 events +2026-02-04T19:09:09.259414Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49560/133889 blocks (37.0%), 0 events +2026-02-04T19:09:09.395313Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49570/133889 blocks (37.0%), 0 events +2026-02-04T19:09:09.641382Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49580/133889 blocks (37.0%), 0 events +2026-02-04T19:09:09.774421Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49590/133889 blocks (37.0%), 0 events +2026-02-04T19:09:10.026125Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49600/133889 blocks (37.0%), 0 events +2026-02-04T19:09:10.192137Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49610/133889 blocks (37.1%), 0 events +2026-02-04T19:09:10.450019Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49620/133889 blocks (37.1%), 0 events +2026-02-04T19:09:10.642322Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49630/133889 blocks (37.1%), 0 events +2026-02-04T19:09:10.808945Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49640/133889 blocks (37.1%), 0 events +2026-02-04T19:09:11.048819Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49650/133889 blocks (37.1%), 0 events +2026-02-04T19:09:11.246907Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49660/133889 blocks (37.1%), 0 events +2026-02-04T19:09:11.498319Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49670/133889 blocks (37.1%), 0 events +2026-02-04T19:09:11.572091Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49680/133889 blocks (37.1%), 0 events +2026-02-04T19:09:11.777356Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49690/133889 blocks (37.1%), 0 events +2026-02-04T19:09:12.019477Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49700/133889 blocks (37.1%), 0 events +2026-02-04T19:09:12.248445Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49710/133889 blocks (37.1%), 0 events +2026-02-04T19:09:12.377476Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49720/133889 blocks (37.1%), 0 events +2026-02-04T19:09:12.630250Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49730/133889 blocks (37.1%), 0 events +2026-02-04T19:09:12.810484Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49740/133889 blocks (37.1%), 0 events +2026-02-04T19:09:13.065748Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49750/133889 blocks (37.2%), 0 events +2026-02-04T19:09:13.233296Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49760/133889 blocks (37.2%), 0 events +2026-02-04T19:09:13.411243Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49770/133889 blocks (37.2%), 0 events +2026-02-04T19:09:13.611190Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49780/133889 blocks (37.2%), 0 events +2026-02-04T19:09:13.805155Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49790/133889 blocks (37.2%), 0 events +2026-02-04T19:09:14.119098Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49800/133889 blocks (37.2%), 0 events +2026-02-04T19:09:14.158384Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49810/133889 blocks (37.2%), 0 events +2026-02-04T19:09:14.371286Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49820/133889 blocks (37.2%), 0 events +2026-02-04T19:09:14.637028Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49830/133889 blocks (37.2%), 0 events +2026-02-04T19:09:14.840565Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49840/133889 blocks (37.2%), 0 events +2026-02-04T19:09:15.024014Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49850/133889 blocks (37.2%), 0 events +2026-02-04T19:09:15.225996Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49860/133889 blocks (37.2%), 0 events +2026-02-04T19:09:15.457955Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49870/133889 blocks (37.2%), 0 events +2026-02-04T19:09:15.691381Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49880/133889 blocks (37.3%), 0 events +2026-02-04T19:09:15.840918Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49890/133889 blocks (37.3%), 0 events +2026-02-04T19:09:16.055127Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49900/133889 blocks (37.3%), 0 events +2026-02-04T19:09:16.219781Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49910/133889 blocks (37.3%), 0 events +2026-02-04T19:09:16.401178Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49920/133889 blocks (37.3%), 0 events +2026-02-04T19:09:16.704118Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49930/133889 blocks (37.3%), 0 events +2026-02-04T19:09:16.816312Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49940/133889 blocks (37.3%), 0 events +2026-02-04T19:09:17.055243Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49950/133889 blocks (37.3%), 0 events +2026-02-04T19:09:17.268318Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49960/133889 blocks (37.3%), 0 events +2026-02-04T19:09:17.417379Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49970/133889 blocks (37.3%), 0 events +2026-02-04T19:09:17.750466Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49980/133889 blocks (37.3%), 0 events +2026-02-04T19:09:17.791836Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49990/133889 blocks (37.3%), 0 events +2026-02-04T19:09:18.033164Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50000/133889 blocks (37.3%), 0 events +2026-02-04T19:09:18.315158Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50010/133889 blocks (37.4%), 0 events +2026-02-04T19:09:18.441875Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50020/133889 blocks (37.4%), 0 events +2026-02-04T19:09:18.582573Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50030/133889 blocks (37.4%), 0 events +2026-02-04T19:09:18.841487Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50040/133889 blocks (37.4%), 0 events +2026-02-04T19:09:19.067627Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50050/133889 blocks (37.4%), 0 events +2026-02-04T19:09:19.198566Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50060/133889 blocks (37.4%), 0 events +2026-02-04T19:09:19.365723Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50070/133889 blocks (37.4%), 0 events +2026-02-04T19:09:19.645404Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50080/133889 blocks (37.4%), 0 events +2026-02-04T19:09:19.881451Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50090/133889 blocks (37.4%), 0 events +2026-02-04T19:09:19.975125Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50100/133889 blocks (37.4%), 0 events +2026-02-04T19:09:20.159545Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50110/133889 blocks (37.4%), 0 events +2026-02-04T19:09:20.671921Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50120/133889 blocks (37.4%), 0 events +2026-02-04T19:09:20.709046Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50130/133889 blocks (37.4%), 0 events +2026-02-04T19:09:20.926951Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50140/133889 blocks (37.4%), 0 events +2026-02-04T19:09:20.963178Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50150/133889 blocks (37.5%), 0 events +2026-02-04T19:09:21.176111Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50160/133889 blocks (37.5%), 0 events +2026-02-04T19:09:21.456427Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50170/133889 blocks (37.5%), 0 events +2026-02-04T19:09:21.661085Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50180/133889 blocks (37.5%), 0 events +2026-02-04T19:09:21.797714Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50190/133889 blocks (37.5%), 0 events +2026-02-04T19:09:22.066180Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50200/133889 blocks (37.5%), 0 events +2026-02-04T19:09:22.177226Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50210/133889 blocks (37.5%), 0 events +2026-02-04T19:09:22.503799Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50220/133889 blocks (37.5%), 0 events +2026-02-04T19:09:22.577394Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50230/133889 blocks (37.5%), 0 events +2026-02-04T19:09:22.824190Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50240/133889 blocks (37.5%), 0 events +2026-02-04T19:09:23.027252Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50250/133889 blocks (37.5%), 0 events +2026-02-04T19:09:23.179475Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50260/133889 blocks (37.5%), 0 events +2026-02-04T19:09:23.370711Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50270/133889 blocks (37.5%), 0 events +2026-02-04T19:09:23.585262Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50280/133889 blocks (37.6%), 0 events +2026-02-04T19:09:23.810910Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50290/133889 blocks (37.6%), 0 events +2026-02-04T19:09:24.078056Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50300/133889 blocks (37.6%), 0 events +2026-02-04T19:09:24.245211Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50310/133889 blocks (37.6%), 0 events +2026-02-04T19:09:24.463176Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50320/133889 blocks (37.6%), 0 events +2026-02-04T19:09:24.608461Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50330/133889 blocks (37.6%), 0 events +2026-02-04T19:09:24.779383Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50340/133889 blocks (37.6%), 0 events +2026-02-04T19:09:25.093133Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50350/133889 blocks (37.6%), 0 events +2026-02-04T19:09:25.218105Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50360/133889 blocks (37.6%), 0 events +2026-02-04T19:09:25.462516Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50370/133889 blocks (37.6%), 0 events +2026-02-04T19:09:25.653855Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50380/133889 blocks (37.6%), 0 events +2026-02-04T19:09:25.800068Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50390/133889 blocks (37.6%), 0 events +2026-02-04T19:09:26.017646Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50400/133889 blocks (37.6%), 0 events +2026-02-04T19:09:26.201069Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50410/133889 blocks (37.7%), 0 events +2026-02-04T19:09:26.387552Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50420/133889 blocks (37.7%), 0 events +2026-02-04T19:09:26.696088Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50430/133889 blocks (37.7%), 0 events +2026-02-04T19:09:26.770814Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50440/133889 blocks (37.7%), 0 events +2026-02-04T19:09:27.025907Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50450/133889 blocks (37.7%), 0 events +2026-02-04T19:09:27.223113Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50460/133889 blocks (37.7%), 0 events +2026-02-04T19:09:27.423478Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50470/133889 blocks (37.7%), 0 events +2026-02-04T19:09:27.765965Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50480/133889 blocks (37.7%), 0 events +2026-02-04T19:09:27.820839Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50490/133889 blocks (37.7%), 0 events +2026-02-04T19:09:27.965046Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50500/133889 blocks (37.7%), 0 events +2026-02-04T19:09:28.279757Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50510/133889 blocks (37.7%), 0 events +2026-02-04T19:09:28.445968Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50520/133889 blocks (37.7%), 0 events +2026-02-04T19:09:28.615758Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50530/133889 blocks (37.7%), 0 events +2026-02-04T19:09:28.813810Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50540/133889 blocks (37.7%), 0 events +2026-02-04T19:09:29.036850Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50550/133889 blocks (37.8%), 0 events +2026-02-04T19:09:29.319163Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50560/133889 blocks (37.8%), 0 events +2026-02-04T19:09:29.357293Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50570/133889 blocks (37.8%), 0 events +2026-02-04T19:09:29.587317Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50580/133889 blocks (37.8%), 0 events +2026-02-04T19:09:29.847403Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50590/133889 blocks (37.8%), 0 events +2026-02-04T19:09:30.060950Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50600/133889 blocks (37.8%), 0 events +2026-02-04T19:09:30.235544Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50610/133889 blocks (37.8%), 0 events +2026-02-04T19:09:30.458989Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50620/133889 blocks (37.8%), 0 events +2026-02-04T19:09:30.577691Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50630/133889 blocks (37.8%), 0 events +2026-02-04T19:09:30.860071Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50640/133889 blocks (37.8%), 0 events +2026-02-04T19:09:31.033437Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50650/133889 blocks (37.8%), 0 events +2026-02-04T19:09:31.264966Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50660/133889 blocks (37.8%), 0 events +2026-02-04T19:09:31.432609Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50670/133889 blocks (37.8%), 0 events +2026-02-04T19:09:31.652605Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50680/133889 blocks (37.9%), 0 events +2026-02-04T19:09:31.908001Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50690/133889 blocks (37.9%), 0 events +2026-02-04T19:09:32.032574Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50700/133889 blocks (37.9%), 0 events +2026-02-04T19:09:32.245691Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50710/133889 blocks (37.9%), 0 events +2026-02-04T19:09:32.431886Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50720/133889 blocks (37.9%), 0 events +2026-02-04T19:09:32.603135Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50730/133889 blocks (37.9%), 0 events +2026-02-04T19:09:32.846433Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50740/133889 blocks (37.9%), 0 events +2026-02-04T19:09:32.991957Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50750/133889 blocks (37.9%), 0 events +2026-02-04T19:09:33.173125Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50760/133889 blocks (37.9%), 0 events +2026-02-04T19:09:33.511786Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50770/133889 blocks (37.9%), 0 events +2026-02-04T19:09:33.653914Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50780/133889 blocks (37.9%), 0 events +2026-02-04T19:09:33.768182Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50790/133889 blocks (37.9%), 0 events +2026-02-04T19:09:34.040721Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50800/133889 blocks (37.9%), 0 events +2026-02-04T19:09:34.190929Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50810/133889 blocks (37.9%), 0 events +2026-02-04T19:09:34.427024Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50820/133889 blocks (38.0%), 0 events +2026-02-04T19:09:34.650607Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50830/133889 blocks (38.0%), 0 events +2026-02-04T19:09:34.769248Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50840/133889 blocks (38.0%), 0 events +2026-02-04T19:09:35.085850Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50850/133889 blocks (38.0%), 0 events +2026-02-04T19:09:35.188417Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50860/133889 blocks (38.0%), 0 events +2026-02-04T19:09:35.369262Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50870/133889 blocks (38.0%), 0 events +2026-02-04T19:09:35.642406Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50880/133889 blocks (38.0%), 0 events +2026-02-04T19:09:35.819346Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50890/133889 blocks (38.0%), 0 events +2026-02-04T19:09:36.143824Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50900/133889 blocks (38.0%), 0 events +2026-02-04T19:09:36.181171Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50910/133889 blocks (38.0%), 0 events +2026-02-04T19:09:36.420414Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50920/133889 blocks (38.0%), 0 events +2026-02-04T19:09:36.626176Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50930/133889 blocks (38.0%), 0 events +2026-02-04T19:09:36.849201Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50940/133889 blocks (38.0%), 0 events +2026-02-04T19:09:37.150843Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50950/133889 blocks (38.1%), 0 events +2026-02-04T19:09:37.192430Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50960/133889 blocks (38.1%), 0 events +2026-02-04T19:09:37.421735Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50970/133889 blocks (38.1%), 0 events +2026-02-04T19:09:37.579754Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50980/133889 blocks (38.1%), 0 events +2026-02-04T19:09:37.836774Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50990/133889 blocks (38.1%), 0 events +2026-02-04T19:09:37.967471Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51000/133889 blocks (38.1%), 0 events +2026-02-04T19:09:38.249423Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51010/133889 blocks (38.1%), 0 events +2026-02-04T19:09:38.429219Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51020/133889 blocks (38.1%), 0 events +2026-02-04T19:09:38.722737Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51030/133889 blocks (38.1%), 0 events +2026-02-04T19:09:38.763567Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51040/133889 blocks (38.1%), 0 events +2026-02-04T19:09:39.011643Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51050/133889 blocks (38.1%), 0 events +2026-02-04T19:09:39.284611Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51060/133889 blocks (38.1%), 0 events +2026-02-04T19:09:39.483239Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51070/133889 blocks (38.1%), 0 events +2026-02-04T19:09:39.571664Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51080/133889 blocks (38.2%), 0 events +2026-02-04T19:09:39.804578Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51090/133889 blocks (38.2%), 0 events +2026-02-04T19:09:40.062605Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51100/133889 blocks (38.2%), 0 events +2026-02-04T19:09:40.336807Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51110/133889 blocks (38.2%), 0 events +2026-02-04T19:09:40.373340Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51120/133889 blocks (38.2%), 0 events +2026-02-04T19:09:40.636457Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51130/133889 blocks (38.2%), 0 events +2026-02-04T19:09:40.852460Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51140/133889 blocks (38.2%), 0 events +2026-02-04T19:09:41.056395Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51150/133889 blocks (38.2%), 0 events +2026-02-04T19:09:41.226104Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51160/133889 blocks (38.2%), 0 events +2026-02-04T19:09:41.430712Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51170/133889 blocks (38.2%), 0 events +2026-02-04T19:09:41.599159Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51180/133889 blocks (38.2%), 0 events +2026-02-04T19:09:41.905165Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51190/133889 blocks (38.2%), 0 events +2026-02-04T19:09:41.973648Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51200/133889 blocks (38.2%), 0 events +2026-02-04T19:09:42.252731Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51210/133889 blocks (38.2%), 0 events +2026-02-04T19:09:42.423396Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51220/133889 blocks (38.3%), 0 events +2026-02-04T19:09:42.648779Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51230/133889 blocks (38.3%), 0 events +2026-02-04T19:09:42.798100Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51240/133889 blocks (38.3%), 0 events +2026-02-04T19:09:42.969147Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51250/133889 blocks (38.3%), 0 events +2026-02-04T19:09:43.189348Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51260/133889 blocks (38.3%), 0 events +2026-02-04T19:09:43.441113Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51270/133889 blocks (38.3%), 0 events +2026-02-04T19:09:43.626383Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51280/133889 blocks (38.3%), 0 events +2026-02-04T19:09:43.846823Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51290/133889 blocks (38.3%), 0 events +2026-02-04T19:09:43.997131Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51300/133889 blocks (38.3%), 0 events +2026-02-04T19:09:44.207909Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51310/133889 blocks (38.3%), 0 events +2026-02-04T19:09:44.522736Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51320/133889 blocks (38.3%), 0 events +2026-02-04T19:09:44.562797Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51330/133889 blocks (38.3%), 0 events +2026-02-04T19:09:44.829824Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51340/133889 blocks (38.3%), 0 events +2026-02-04T19:09:45.045439Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51350/133889 blocks (38.4%), 0 events +2026-02-04T19:09:45.262537Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51360/133889 blocks (38.4%), 0 events +2026-02-04T19:09:45.369437Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51370/133889 blocks (38.4%), 0 events +2026-02-04T19:09:45.626596Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51380/133889 blocks (38.4%), 0 events +2026-02-04T19:09:45.836204Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51390/133889 blocks (38.4%), 0 events +2026-02-04T19:09:46.095170Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51400/133889 blocks (38.4%), 0 events +2026-02-04T19:09:46.190035Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51410/133889 blocks (38.4%), 0 events +2026-02-04T19:09:46.400305Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51420/133889 blocks (38.4%), 0 events +2026-02-04T19:09:46.655696Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51430/133889 blocks (38.4%), 0 events +2026-02-04T19:09:46.814665Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51440/133889 blocks (38.4%), 0 events +2026-02-04T19:09:47.000505Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51450/133889 blocks (38.4%), 0 events +2026-02-04T19:09:47.340091Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51460/133889 blocks (38.4%), 0 events +2026-02-04T19:09:47.377993Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51470/133889 blocks (38.4%), 0 events +2026-02-04T19:09:47.678097Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51480/133889 blocks (38.4%), 0 events +2026-02-04T19:09:47.862249Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51490/133889 blocks (38.5%), 0 events +2026-02-04T19:09:47.973386Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51500/133889 blocks (38.5%), 0 events +2026-02-04T19:09:48.223168Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51510/133889 blocks (38.5%), 0 events +2026-02-04T19:09:48.424604Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51520/133889 blocks (38.5%), 0 events +2026-02-04T19:09:48.571701Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51530/133889 blocks (38.5%), 0 events +2026-02-04T19:09:48.879260Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51540/133889 blocks (38.5%), 0 events +2026-02-04T19:09:48.978362Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51550/133889 blocks (38.5%), 0 events +2026-02-04T19:09:49.251639Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51560/133889 blocks (38.5%), 0 events +2026-02-04T19:09:49.441055Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51570/133889 blocks (38.5%), 0 events +2026-02-04T19:09:49.732566Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51580/133889 blocks (38.5%), 0 events +2026-02-04T19:09:49.779384Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51590/133889 blocks (38.5%), 0 events +2026-02-04T19:09:50.014723Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51600/133889 blocks (38.5%), 0 events +2026-02-04T19:09:50.254831Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51610/133889 blocks (38.5%), 0 events +2026-02-04T19:09:50.485250Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51620/133889 blocks (38.6%), 0 events +2026-02-04T19:09:50.645884Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51630/133889 blocks (38.6%), 0 events +2026-02-04T19:09:50.835845Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51640/133889 blocks (38.6%), 0 events +2026-02-04T19:09:51.024100Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51650/133889 blocks (38.6%), 0 events +2026-02-04T19:09:51.165381Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51660/133889 blocks (38.6%), 0 events +2026-02-04T19:09:51.384325Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51670/133889 blocks (38.6%), 0 events +2026-02-04T19:09:51.597967Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51680/133889 blocks (38.6%), 0 events +2026-02-04T19:09:51.860491Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51690/133889 blocks (38.6%), 0 events +2026-02-04T19:09:52.064472Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51700/133889 blocks (38.6%), 0 events +2026-02-04T19:09:52.168933Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51710/133889 blocks (38.6%), 0 events +2026-02-04T19:09:52.387911Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51720/133889 blocks (38.6%), 0 events +2026-02-04T19:09:52.584972Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51730/133889 blocks (38.6%), 0 events +2026-02-04T19:09:52.909311Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51740/133889 blocks (38.6%), 0 events +2026-02-04T19:09:53.036456Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51750/133889 blocks (38.7%), 0 events +2026-02-04T19:09:53.261615Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51760/133889 blocks (38.7%), 0 events +2026-02-04T19:09:53.437278Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51770/133889 blocks (38.7%), 0 events +2026-02-04T19:09:53.606435Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51780/133889 blocks (38.7%), 0 events +2026-02-04T19:09:53.777025Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51790/133889 blocks (38.7%), 0 events +2026-02-04T19:09:54.042334Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51800/133889 blocks (38.7%), 0 events +2026-02-04T19:09:54.198027Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51810/133889 blocks (38.7%), 0 events +2026-02-04T19:09:54.451351Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51820/133889 blocks (38.7%), 0 events +2026-02-04T19:09:54.660099Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51830/133889 blocks (38.7%), 0 events +2026-02-04T19:09:54.765244Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51840/133889 blocks (38.7%), 0 events +2026-02-04T19:09:55.020513Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51850/133889 blocks (38.7%), 0 events +2026-02-04T19:09:55.259103Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51860/133889 blocks (38.7%), 0 events +2026-02-04T19:09:55.499836Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51870/133889 blocks (38.7%), 0 events +2026-02-04T19:09:55.566221Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51880/133889 blocks (38.7%), 0 events +2026-02-04T19:09:55.851083Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51890/133889 blocks (38.8%), 0 events +2026-02-04T19:09:56.057763Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51900/133889 blocks (38.8%), 0 events +2026-02-04T19:09:56.229608Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51910/133889 blocks (38.8%), 0 events +2026-02-04T19:09:56.401309Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51920/133889 blocks (38.8%), 0 events +2026-02-04T19:09:56.645138Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51930/133889 blocks (38.8%), 0 events +2026-02-04T19:09:56.851405Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51940/133889 blocks (38.8%), 0 events +2026-02-04T19:09:57.072886Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51950/133889 blocks (38.8%), 0 events +2026-02-04T19:09:57.173085Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51960/133889 blocks (38.8%), 0 events +2026-02-04T19:09:57.376175Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51970/133889 blocks (38.8%), 0 events +2026-02-04T19:09:57.627171Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51980/133889 blocks (38.8%), 0 events +2026-02-04T19:09:57.788506Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51990/133889 blocks (38.8%), 0 events +2026-02-04T19:09:57.981933Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52000/133889 blocks (38.8%), 0 events +2026-02-04T19:09:58.177524Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52010/133889 blocks (38.8%), 0 events +2026-02-04T19:09:58.385060Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52020/133889 blocks (38.9%), 0 events +2026-02-04T19:09:58.677485Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52030/133889 blocks (38.9%), 0 events +2026-02-04T19:09:58.847324Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52040/133889 blocks (38.9%), 0 events +2026-02-04T19:09:58.972344Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52050/133889 blocks (38.9%), 0 events +2026-02-04T19:09:59.199262Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52060/133889 blocks (38.9%), 0 events +2026-02-04T19:09:59.431902Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52070/133889 blocks (38.9%), 0 events +2026-02-04T19:09:59.727042Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52080/133889 blocks (38.9%), 0 events +2026-02-04T19:09:59.764091Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52090/133889 blocks (38.9%), 0 events +2026-02-04T19:10:00.017811Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52100/133889 blocks (38.9%), 0 events +2026-02-04T19:10:00.253984Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52110/133889 blocks (38.9%), 0 events +2026-02-04T19:10:00.374709Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52120/133889 blocks (38.9%), 0 events +2026-02-04T19:10:00.620984Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52130/133889 blocks (38.9%), 0 events +2026-02-04T19:10:00.792899Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52140/133889 blocks (38.9%), 0 events +2026-02-04T19:10:01.007587Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52150/133889 blocks (38.9%), 0 events +2026-02-04T19:10:01.266293Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52160/133889 blocks (39.0%), 0 events +2026-02-04T19:10:01.365683Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52170/133889 blocks (39.0%), 0 events +2026-02-04T19:10:01.630171Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52180/133889 blocks (39.0%), 0 events +2026-02-04T19:10:01.828006Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52190/133889 blocks (39.0%), 0 events +2026-02-04T19:10:02.030706Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52200/133889 blocks (39.0%), 0 events +2026-02-04T19:10:02.199740Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52210/133889 blocks (39.0%), 0 events +2026-02-04T19:10:02.417179Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52220/133889 blocks (39.0%), 0 events +2026-02-04T19:10:02.596571Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52230/133889 blocks (39.0%), 0 events +2026-02-04T19:10:02.874769Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52240/133889 blocks (39.0%), 0 events +2026-02-04T19:10:03.084692Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52250/133889 blocks (39.0%), 0 events +2026-02-04T19:10:03.238546Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52260/133889 blocks (39.0%), 0 events +2026-02-04T19:10:03.402744Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52270/133889 blocks (39.0%), 0 events +2026-02-04T19:10:03.593040Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52280/133889 blocks (39.0%), 0 events +2026-02-04T19:10:03.889265Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52290/133889 blocks (39.1%), 0 events +2026-02-04T19:10:04.084444Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52300/133889 blocks (39.1%), 0 events +2026-02-04T19:10:04.198010Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52310/133889 blocks (39.1%), 0 events +2026-02-04T19:10:04.449126Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52320/133889 blocks (39.1%), 0 events +2026-02-04T19:10:04.577337Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52330/133889 blocks (39.1%), 0 events +2026-02-04T19:10:04.845129Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52340/133889 blocks (39.1%), 0 events +2026-02-04T19:10:05.035416Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52350/133889 blocks (39.1%), 0 events +2026-02-04T19:10:05.222451Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52360/133889 blocks (39.1%), 0 events +2026-02-04T19:10:05.460996Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52370/133889 blocks (39.1%), 0 events +2026-02-04T19:10:05.621246Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52380/133889 blocks (39.1%), 0 events +2026-02-04T19:10:05.782098Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52390/133889 blocks (39.1%), 0 events +2026-02-04T19:10:06.065494Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52400/133889 blocks (39.1%), 0 events +2026-02-04T19:10:06.260209Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52410/133889 blocks (39.1%), 0 events +2026-02-04T19:10:06.508980Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52420/133889 blocks (39.2%), 0 events +2026-02-04T19:10:06.575595Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52430/133889 blocks (39.2%), 0 events +2026-02-04T19:10:06.817808Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52440/133889 blocks (39.2%), 0 events +2026-02-04T19:10:07.067901Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52450/133889 blocks (39.2%), 0 events +2026-02-04T19:10:07.165567Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52460/133889 blocks (39.2%), 0 events +2026-02-04T19:10:07.396231Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52470/133889 blocks (39.2%), 0 events +2026-02-04T19:10:07.601519Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52480/133889 blocks (39.2%), 0 events +2026-02-04T19:10:07.827579Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52490/133889 blocks (39.2%), 0 events +2026-02-04T19:10:07.978093Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52500/133889 blocks (39.2%), 0 events +2026-02-04T19:10:08.242682Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52510/133889 blocks (39.2%), 0 events +2026-02-04T19:10:08.429557Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52520/133889 blocks (39.2%), 0 events +2026-02-04T19:10:08.664878Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52530/133889 blocks (39.2%), 0 events +2026-02-04T19:10:08.780918Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52540/133889 blocks (39.2%), 0 events +2026-02-04T19:10:08.980558Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52550/133889 blocks (39.2%), 0 events +2026-02-04T19:10:09.187229Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52560/133889 blocks (39.3%), 0 events +2026-02-04T19:10:09.420749Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52570/133889 blocks (39.3%), 0 events +2026-02-04T19:10:09.691177Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52580/133889 blocks (39.3%), 0 events +2026-02-04T19:10:09.844825Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52590/133889 blocks (39.3%), 0 events +2026-02-04T19:10:10.001190Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52600/133889 blocks (39.3%), 0 events +2026-02-04T19:10:10.252987Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52610/133889 blocks (39.3%), 0 events +2026-02-04T19:10:10.377690Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52620/133889 blocks (39.3%), 0 events +2026-02-04T19:10:10.570616Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52630/133889 blocks (39.3%), 0 events +2026-02-04T19:10:10.837479Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52640/133889 blocks (39.3%), 0 events +2026-02-04T19:10:10.982897Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52650/133889 blocks (39.3%), 0 events +2026-02-04T19:10:11.227880Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52660/133889 blocks (39.3%), 0 events +2026-02-04T19:10:11.431464Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52670/133889 blocks (39.3%), 0 events +2026-02-04T19:10:11.631604Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52680/133889 blocks (39.3%), 0 events +2026-02-04T19:10:11.845993Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52690/133889 blocks (39.4%), 0 events +2026-02-04T19:10:11.989243Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52700/133889 blocks (39.4%), 0 events +2026-02-04T19:10:12.276335Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52710/133889 blocks (39.4%), 0 events +2026-02-04T19:10:12.450890Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52720/133889 blocks (39.4%), 0 events +2026-02-04T19:10:12.577863Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52730/133889 blocks (39.4%), 0 events +2026-02-04T19:10:12.833969Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52740/133889 blocks (39.4%), 0 events +2026-02-04T19:10:13.006134Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52750/133889 blocks (39.4%), 0 events +2026-02-04T19:10:13.190866Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52760/133889 blocks (39.4%), 0 events +2026-02-04T19:10:13.390884Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52770/133889 blocks (39.4%), 0 events +2026-02-04T19:10:13.588650Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52780/133889 blocks (39.4%), 0 events +2026-02-04T19:10:13.884632Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52790/133889 blocks (39.4%), 0 events +2026-02-04T19:10:13.963886Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52800/133889 blocks (39.4%), 0 events +2026-02-04T19:10:14.210594Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52810/133889 blocks (39.4%), 0 events +2026-02-04T19:10:14.413658Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52820/133889 blocks (39.5%), 0 events +2026-02-04T19:10:14.612721Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52830/133889 blocks (39.5%), 0 events +2026-02-04T19:10:14.897057Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52840/133889 blocks (39.5%), 0 events +2026-02-04T19:10:14.969636Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52850/133889 blocks (39.5%), 0 events +2026-02-04T19:10:15.240260Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52860/133889 blocks (39.5%), 0 events +2026-02-04T19:10:15.455556Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52870/133889 blocks (39.5%), 0 events +2026-02-04T19:10:15.623715Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52880/133889 blocks (39.5%), 0 events +2026-02-04T19:10:15.808322Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52890/133889 blocks (39.5%), 0 events +2026-02-04T19:10:16.014491Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52900/133889 blocks (39.5%), 0 events +2026-02-04T19:10:16.236127Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52910/133889 blocks (39.5%), 0 events +2026-02-04T19:10:16.470113Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52920/133889 blocks (39.5%), 0 events +2026-02-04T19:10:16.578574Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52930/133889 blocks (39.5%), 0 events +2026-02-04T19:10:16.787690Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52940/133889 blocks (39.5%), 0 events +2026-02-04T19:10:17.030789Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52950/133889 blocks (39.5%), 0 events +2026-02-04T19:10:17.241888Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52960/133889 blocks (39.6%), 0 events +2026-02-04T19:10:17.394181Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52970/133889 blocks (39.6%), 0 events +2026-02-04T19:10:17.589240Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52980/133889 blocks (39.6%), 0 events +2026-02-04T19:10:17.849601Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52990/133889 blocks (39.6%), 0 events +2026-02-04T19:10:18.093149Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53000/133889 blocks (39.6%), 0 events +2026-02-04T19:10:18.223071Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53010/133889 blocks (39.6%), 0 events +2026-02-04T19:10:18.411086Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53020/133889 blocks (39.6%), 0 events +2026-02-04T19:10:18.597728Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53030/133889 blocks (39.6%), 0 events +2026-02-04T19:10:18.833736Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53040/133889 blocks (39.6%), 0 events +2026-02-04T19:10:18.979375Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53050/133889 blocks (39.6%), 0 events +2026-02-04T19:10:19.168176Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53060/133889 blocks (39.6%), 0 events +2026-02-04T19:10:19.432700Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53070/133889 blocks (39.6%), 0 events +2026-02-04T19:10:19.659686Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53080/133889 blocks (39.6%), 0 events +2026-02-04T19:10:19.846857Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53090/133889 blocks (39.7%), 0 events +2026-02-04T19:10:19.983502Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53100/133889 blocks (39.7%), 0 events +2026-02-04T19:10:20.233008Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53110/133889 blocks (39.7%), 0 events +2026-02-04T19:10:20.395379Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53120/133889 blocks (39.7%), 0 events +2026-02-04T19:10:20.696792Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53130/133889 blocks (39.7%), 0 events +2026-02-04T19:10:20.893774Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53140/133889 blocks (39.7%), 0 events +2026-02-04T19:10:20.968352Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53150/133889 blocks (39.7%), 0 events +2026-02-04T19:10:21.219840Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53160/133889 blocks (39.7%), 0 events +2026-02-04T19:10:21.443440Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53170/133889 blocks (39.7%), 0 events +2026-02-04T19:10:21.751418Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53180/133889 blocks (39.7%), 0 events +2026-02-04T19:10:21.796384Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53190/133889 blocks (39.7%), 0 events +2026-02-04T19:10:22.035570Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53200/133889 blocks (39.7%), 0 events +2026-02-04T19:10:22.290961Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53210/133889 blocks (39.7%), 0 events +2026-02-04T19:10:22.466017Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53220/133889 blocks (39.7%), 0 events +2026-02-04T19:10:22.577744Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53230/133889 blocks (39.8%), 0 events +2026-02-04T19:10:22.856649Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53240/133889 blocks (39.8%), 0 events +2026-02-04T19:10:22.988714Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53250/133889 blocks (39.8%), 0 events +2026-02-04T19:10:23.285295Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53260/133889 blocks (39.8%), 0 events +2026-02-04T19:10:23.426248Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53270/133889 blocks (39.8%), 0 events +2026-02-04T19:10:23.644013Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53280/133889 blocks (39.8%), 0 events +2026-02-04T19:10:23.849846Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53290/133889 blocks (39.8%), 0 events +2026-02-04T19:10:24.014945Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53300/133889 blocks (39.8%), 0 events +2026-02-04T19:10:24.206618Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53310/133889 blocks (39.8%), 0 events +2026-02-04T19:10:24.372622Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53320/133889 blocks (39.8%), 0 events +2026-02-04T19:10:24.576870Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53330/133889 blocks (39.8%), 0 events +2026-02-04T19:10:24.897839Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53340/133889 blocks (39.8%), 0 events +2026-02-04T19:10:25.018933Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53350/133889 blocks (39.8%), 0 events +2026-02-04T19:10:25.184933Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53360/133889 blocks (39.9%), 0 events +2026-02-04T19:10:25.441089Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53370/133889 blocks (39.9%), 0 events +2026-02-04T19:10:25.620418Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53380/133889 blocks (39.9%), 0 events +2026-02-04T19:10:25.808876Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53390/133889 blocks (39.9%), 0 events +2026-02-04T19:10:26.070712Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53400/133889 blocks (39.9%), 0 events +2026-02-04T19:10:26.216398Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53410/133889 blocks (39.9%), 0 events +2026-02-04T19:10:26.464269Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53420/133889 blocks (39.9%), 0 events +2026-02-04T19:10:26.622349Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53430/133889 blocks (39.9%), 0 events +2026-02-04T19:10:26.800201Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53440/133889 blocks (39.9%), 0 events +2026-02-04T19:10:27.042447Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53450/133889 blocks (39.9%), 0 events +2026-02-04T19:10:27.195224Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53460/133889 blocks (39.9%), 0 events +2026-02-04T19:10:27.517634Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53470/133889 blocks (39.9%), 0 events +2026-02-04T19:10:27.555623Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53480/133889 blocks (39.9%), 0 events +2026-02-04T19:10:27.862260Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53490/133889 blocks (40.0%), 0 events +2026-02-04T19:10:28.044251Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53500/133889 blocks (40.0%), 0 events +2026-02-04T19:10:28.168474Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53510/133889 blocks (40.0%), 0 events +2026-02-04T19:10:28.387640Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53520/133889 blocks (40.0%), 0 events +2026-02-04T19:10:28.616287Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53530/133889 blocks (40.0%), 0 events +2026-02-04T19:10:28.851451Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53540/133889 blocks (40.0%), 0 events +2026-02-04T19:10:29.082416Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53550/133889 blocks (40.0%), 0 events +2026-02-04T19:10:29.226521Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53560/133889 blocks (40.0%), 0 events +2026-02-04T19:10:29.426801Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53570/133889 blocks (40.0%), 0 events +2026-02-04T19:10:29.619564Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53580/133889 blocks (40.0%), 0 events +2026-02-04T19:10:29.826197Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53590/133889 blocks (40.0%), 0 events +2026-02-04T19:10:29.967860Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53600/133889 blocks (40.0%), 0 events +2026-02-04T19:10:30.226777Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53610/133889 blocks (40.0%), 0 events +2026-02-04T19:10:30.436965Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53620/133889 blocks (40.0%), 0 events +2026-02-04T19:10:30.661844Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53630/133889 blocks (40.1%), 0 events +2026-02-04T19:10:30.809705Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53640/133889 blocks (40.1%), 0 events +2026-02-04T19:10:31.149935Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53650/133889 blocks (40.1%), 0 events +2026-02-04T19:10:31.192736Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53660/133889 blocks (40.1%), 0 events +2026-02-04T19:10:31.413297Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53670/133889 blocks (40.1%), 0 events +2026-02-04T19:10:31.673891Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53680/133889 blocks (40.1%), 0 events +2026-02-04T19:10:31.787282Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53690/133889 blocks (40.1%), 0 events +2026-02-04T19:10:32.010574Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53700/133889 blocks (40.1%), 0 events +2026-02-04T19:10:32.236115Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53710/133889 blocks (40.1%), 0 events +2026-02-04T19:10:32.455164Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53720/133889 blocks (40.1%), 0 events +2026-02-04T19:10:32.628519Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53730/133889 blocks (40.1%), 0 events +2026-02-04T19:10:32.848129Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53740/133889 blocks (40.1%), 0 events +2026-02-04T19:10:33.004165Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53750/133889 blocks (40.1%), 0 events +2026-02-04T19:10:33.285029Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53760/133889 blocks (40.2%), 0 events +2026-02-04T19:10:33.375739Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53770/133889 blocks (40.2%), 0 events +2026-02-04T19:10:33.584344Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53780/133889 blocks (40.2%), 0 events +2026-02-04T19:10:33.839165Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53790/133889 blocks (40.2%), 0 events +2026-02-04T19:10:34.011700Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53800/133889 blocks (40.2%), 0 events +2026-02-04T19:10:34.186167Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53810/133889 blocks (40.2%), 0 events +2026-02-04T19:10:34.470631Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53820/133889 blocks (40.2%), 0 events +2026-02-04T19:10:34.566479Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53830/133889 blocks (40.2%), 0 events +2026-02-04T19:10:34.860841Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53840/133889 blocks (40.2%), 0 events +2026-02-04T19:10:35.035326Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53850/133889 blocks (40.2%), 0 events +2026-02-04T19:10:35.212673Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53860/133889 blocks (40.2%), 0 events +2026-02-04T19:10:35.401749Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53870/133889 blocks (40.2%), 0 events +2026-02-04T19:10:35.580127Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53880/133889 blocks (40.2%), 0 events +2026-02-04T19:10:35.900544Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53890/133889 blocks (40.2%), 0 events +2026-02-04T19:10:36.047502Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53900/133889 blocks (40.3%), 0 events +2026-02-04T19:10:36.200548Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53910/133889 blocks (40.3%), 0 events +2026-02-04T19:10:36.449612Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53920/133889 blocks (40.3%), 0 events +2026-02-04T19:10:36.586754Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53930/133889 blocks (40.3%), 0 events +2026-02-04T19:10:36.916526Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53940/133889 blocks (40.3%), 0 events +2026-02-04T19:10:36.958531Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53950/133889 blocks (40.3%), 0 events +2026-02-04T19:10:37.259000Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53960/133889 blocks (40.3%), 0 events +2026-02-04T19:10:37.477004Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53970/133889 blocks (40.3%), 0 events +2026-02-04T19:10:37.632166Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53980/133889 blocks (40.3%), 0 events +2026-02-04T19:10:37.798525Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53990/133889 blocks (40.3%), 0 events +2026-02-04T19:10:37.996353Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54000/133889 blocks (40.3%), 0 events +2026-02-04T19:10:38.240761Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54010/133889 blocks (40.3%), 0 events +2026-02-04T19:10:38.530700Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54020/133889 blocks (40.3%), 0 events +2026-02-04T19:10:38.569810Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54030/133889 blocks (40.4%), 0 events +2026-02-04T19:10:38.855687Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54040/133889 blocks (40.4%), 0 events +2026-02-04T19:10:39.048474Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54050/133889 blocks (40.4%), 0 events +2026-02-04T19:10:39.238577Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54060/133889 blocks (40.4%), 0 events +2026-02-04T19:10:39.388641Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54070/133889 blocks (40.4%), 0 events +2026-02-04T19:10:39.580761Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54080/133889 blocks (40.4%), 0 events +2026-02-04T19:10:39.828365Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54090/133889 blocks (40.4%), 0 events +2026-02-04T19:10:40.066382Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54100/133889 blocks (40.4%), 0 events +2026-02-04T19:10:40.256222Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54110/133889 blocks (40.4%), 0 events +2026-02-04T19:10:40.445542Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54120/133889 blocks (40.4%), 0 events +2026-02-04T19:10:40.660000Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54130/133889 blocks (40.4%), 0 events +2026-02-04T19:10:40.837338Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54140/133889 blocks (40.4%), 0 events +2026-02-04T19:10:40.966730Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54150/133889 blocks (40.4%), 0 events +2026-02-04T19:10:41.213829Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54160/133889 blocks (40.5%), 0 events +2026-02-04T19:10:41.368689Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54170/133889 blocks (40.5%), 0 events +2026-02-04T19:10:41.673879Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54180/133889 blocks (40.5%), 0 events +2026-02-04T19:10:41.785021Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54190/133889 blocks (40.5%), 0 events +2026-02-04T19:10:42.067062Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54200/133889 blocks (40.5%), 0 events +2026-02-04T19:10:42.209830Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54210/133889 blocks (40.5%), 0 events +2026-02-04T19:10:42.458544Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54220/133889 blocks (40.5%), 0 events +2026-02-04T19:10:42.718888Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54230/133889 blocks (40.5%), 0 events +2026-02-04T19:10:42.757577Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54240/133889 blocks (40.5%), 0 events +2026-02-04T19:10:43.049702Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54250/133889 blocks (40.5%), 0 events +2026-02-04T19:10:43.247112Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54260/133889 blocks (40.5%), 0 events +2026-02-04T19:10:43.400228Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54270/133889 blocks (40.5%), 0 events +2026-02-04T19:10:43.586607Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54280/133889 blocks (40.5%), 0 events +2026-02-04T19:10:43.787812Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54290/133889 blocks (40.5%), 0 events +2026-02-04T19:10:43.986403Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54300/133889 blocks (40.6%), 0 events +2026-02-04T19:10:44.299793Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54310/133889 blocks (40.6%), 0 events +2026-02-04T19:10:44.366855Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54320/133889 blocks (40.6%), 0 events +2026-02-04T19:10:44.663433Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54330/133889 blocks (40.6%), 0 events +2026-02-04T19:10:44.814799Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54340/133889 blocks (40.6%), 0 events +2026-02-04T19:10:45.003622Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54350/133889 blocks (40.6%), 0 events +2026-02-04T19:10:45.185639Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54360/133889 blocks (40.6%), 0 events +2026-02-04T19:10:45.402401Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54370/133889 blocks (40.6%), 0 events +2026-02-04T19:10:45.642843Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54380/133889 blocks (40.6%), 0 events +2026-02-04T19:10:45.863059Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54390/133889 blocks (40.6%), 0 events +2026-02-04T19:10:45.991769Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54400/133889 blocks (40.6%), 0 events +2026-02-04T19:10:46.249887Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54410/133889 blocks (40.6%), 0 events +2026-02-04T19:10:46.413238Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54420/133889 blocks (40.6%), 0 events +2026-02-04T19:10:46.910052Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54430/133889 blocks (40.7%), 0 events +2026-02-04T19:10:46.951811Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54440/133889 blocks (40.7%), 0 events +2026-02-04T19:10:46.985827Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54450/133889 blocks (40.7%), 0 events +2026-02-04T19:10:47.245245Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54460/133889 blocks (40.7%), 0 events +2026-02-04T19:10:47.439990Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54470/133889 blocks (40.7%), 0 events +2026-02-04T19:10:47.598234Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54480/133889 blocks (40.7%), 0 events +2026-02-04T19:10:47.923313Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54490/133889 blocks (40.7%), 0 events +2026-02-04T19:10:47.972755Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54500/133889 blocks (40.7%), 0 events +2026-02-04T19:10:48.192020Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54510/133889 blocks (40.7%), 0 events +2026-02-04T19:10:48.450862Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54520/133889 blocks (40.7%), 0 events +2026-02-04T19:10:48.646706Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54530/133889 blocks (40.7%), 0 events +2026-02-04T19:10:48.849604Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54540/133889 blocks (40.7%), 0 events +2026-02-04T19:10:49.007626Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54550/133889 blocks (40.7%), 0 events +2026-02-04T19:10:49.230149Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54560/133889 blocks (40.7%), 0 events +2026-02-04T19:10:49.496162Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54570/133889 blocks (40.8%), 0 events +2026-02-04T19:10:49.893371Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54580/133889 blocks (40.8%), 0 events +2026-02-04T19:10:49.926096Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54590/133889 blocks (40.8%), 0 events +2026-02-04T19:10:50.020239Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54600/133889 blocks (40.8%), 0 events +2026-02-04T19:10:50.163996Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54610/133889 blocks (40.8%), 0 events +2026-02-04T19:10:50.742052Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54620/133889 blocks (40.8%), 0 events +2026-02-04T19:10:50.782852Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54630/133889 blocks (40.8%), 0 events +2026-02-04T19:10:50.820382Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54640/133889 blocks (40.8%), 0 events +2026-02-04T19:10:51.106208Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54650/133889 blocks (40.8%), 0 events +2026-02-04T19:10:51.163124Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54660/133889 blocks (40.8%), 0 events +2026-02-04T19:10:51.421455Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54670/133889 blocks (40.8%), 0 events +2026-02-04T19:10:51.656868Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54680/133889 blocks (40.8%), 0 events +2026-02-04T19:10:51.830440Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54690/133889 blocks (40.8%), 0 events +2026-02-04T19:10:52.120319Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54700/133889 blocks (40.9%), 0 events +2026-02-04T19:10:52.158118Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54710/133889 blocks (40.9%), 0 events +2026-02-04T19:10:52.383713Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54720/133889 blocks (40.9%), 0 events +2026-02-04T19:10:52.644608Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54730/133889 blocks (40.9%), 0 events +2026-02-04T19:10:52.802388Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54740/133889 blocks (40.9%), 0 events +2026-02-04T19:10:52.992525Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54750/133889 blocks (40.9%), 0 events +2026-02-04T19:10:53.200906Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54760/133889 blocks (40.9%), 0 events +2026-02-04T19:10:53.470327Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54770/133889 blocks (40.9%), 0 events +2026-02-04T19:10:53.579414Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54780/133889 blocks (40.9%), 0 events +2026-02-04T19:10:53.830175Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54790/133889 blocks (40.9%), 0 events +2026-02-04T19:10:54.062706Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54800/133889 blocks (40.9%), 0 events +2026-02-04T19:10:54.249517Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54810/133889 blocks (40.9%), 0 events +2026-02-04T19:10:54.408316Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54820/133889 blocks (40.9%), 0 events +2026-02-04T19:10:54.739167Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54830/133889 blocks (41.0%), 0 events +2026-02-04T19:10:54.774559Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54840/133889 blocks (41.0%), 0 events +2026-02-04T19:10:55.038136Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54850/133889 blocks (41.0%), 0 events +2026-02-04T19:10:55.298146Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54860/133889 blocks (41.0%), 0 events +2026-02-04T19:10:55.461910Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54870/133889 blocks (41.0%), 0 events +2026-02-04T19:10:55.603848Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54880/133889 blocks (41.0%), 0 events +2026-02-04T19:10:55.820844Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54890/133889 blocks (41.0%), 0 events +2026-02-04T19:10:56.020881Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54900/133889 blocks (41.0%), 0 events +2026-02-04T19:10:56.178189Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54910/133889 blocks (41.0%), 0 events +2026-02-04T19:10:56.377279Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54920/133889 blocks (41.0%), 0 events +2026-02-04T19:10:56.660056Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54930/133889 blocks (41.0%), 0 events +2026-02-04T19:10:56.869266Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54940/133889 blocks (41.0%), 0 events +2026-02-04T19:10:57.055939Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54950/133889 blocks (41.0%), 0 events +2026-02-04T19:10:57.224318Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54960/133889 blocks (41.0%), 0 events +2026-02-04T19:10:57.396881Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54970/133889 blocks (41.1%), 0 events +2026-02-04T19:10:57.595615Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54980/133889 blocks (41.1%), 0 events +2026-02-04T19:10:57.883739Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54990/133889 blocks (41.1%), 0 events +2026-02-04T19:10:58.052062Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55000/133889 blocks (41.1%), 0 events +2026-02-04T19:10:58.243954Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55010/133889 blocks (41.1%), 0 events +2026-02-04T19:10:58.448248Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55020/133889 blocks (41.1%), 0 events +2026-02-04T19:10:58.625998Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55030/133889 blocks (41.1%), 0 events +2026-02-04T19:10:58.765588Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55040/133889 blocks (41.1%), 0 events +2026-02-04T19:10:59.008694Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55050/133889 blocks (41.1%), 0 events +2026-02-04T19:10:59.218790Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55060/133889 blocks (41.1%), 0 events +2026-02-04T19:10:59.497325Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55070/133889 blocks (41.1%), 0 events +2026-02-04T19:10:59.629589Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55080/133889 blocks (41.1%), 0 events +2026-02-04T19:10:59.846925Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55090/133889 blocks (41.1%), 0 events +2026-02-04T19:11:00.056512Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55100/133889 blocks (41.2%), 0 events +2026-02-04T19:11:00.196096Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55110/133889 blocks (41.2%), 0 events +2026-02-04T19:11:00.540954Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55120/133889 blocks (41.2%), 0 events +2026-02-04T19:11:00.583619Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55130/133889 blocks (41.2%), 0 events +2026-02-04T19:11:00.861525Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55140/133889 blocks (41.2%), 0 events +2026-02-04T19:11:01.062918Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55150/133889 blocks (41.2%), 0 events +2026-02-04T19:11:01.243819Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55160/133889 blocks (41.2%), 0 events +2026-02-04T19:11:01.442710Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55170/133889 blocks (41.2%), 0 events +2026-02-04T19:11:01.617899Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55180/133889 blocks (41.2%), 0 events +2026-02-04T19:11:01.838426Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55190/133889 blocks (41.2%), 0 events +2026-02-04T19:11:02.080841Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55200/133889 blocks (41.2%), 0 events +2026-02-04T19:11:02.215763Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55210/133889 blocks (41.2%), 0 events +2026-02-04T19:11:02.399273Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55220/133889 blocks (41.2%), 0 events +2026-02-04T19:11:02.643182Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55230/133889 blocks (41.3%), 0 events +2026-02-04T19:11:02.815308Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55240/133889 blocks (41.3%), 0 events +2026-02-04T19:11:03.129626Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55250/133889 blocks (41.3%), 0 events +2026-02-04T19:11:03.168276Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55260/133889 blocks (41.3%), 0 events +2026-02-04T19:11:03.448665Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55270/133889 blocks (41.3%), 0 events +2026-02-04T19:11:03.653260Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55280/133889 blocks (41.3%), 0 events +2026-02-04T19:11:03.855289Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55290/133889 blocks (41.3%), 0 events +2026-02-04T19:11:03.969576Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55300/133889 blocks (41.3%), 0 events +2026-02-04T19:11:04.223353Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55310/133889 blocks (41.3%), 0 events +2026-02-04T19:11:04.453580Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55320/133889 blocks (41.3%), 0 events +2026-02-04T19:11:04.735734Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55330/133889 blocks (41.3%), 0 events +2026-02-04T19:11:04.799111Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55340/133889 blocks (41.3%), 0 events +2026-02-04T19:11:05.054639Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55350/133889 blocks (41.3%), 0 events +2026-02-04T19:11:05.267763Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55360/133889 blocks (41.3%), 0 events +2026-02-04T19:11:05.376694Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55370/133889 blocks (41.4%), 0 events +2026-02-04T19:11:05.619686Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55380/133889 blocks (41.4%), 0 events +2026-02-04T19:11:05.795464Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55390/133889 blocks (41.4%), 0 events +2026-02-04T19:11:06.029678Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55400/133889 blocks (41.4%), 0 events +2026-02-04T19:11:06.275484Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55410/133889 blocks (41.4%), 0 events +2026-02-04T19:11:06.360442Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55420/133889 blocks (41.4%), 0 events +2026-02-04T19:11:06.636236Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55430/133889 blocks (41.4%), 0 events +2026-02-04T19:11:06.833680Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55440/133889 blocks (41.4%), 0 events +2026-02-04T19:11:07.014062Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55450/133889 blocks (41.4%), 0 events +2026-02-04T19:11:07.216429Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55460/133889 blocks (41.4%), 0 events +2026-02-04T19:11:07.464149Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55470/133889 blocks (41.4%), 0 events +2026-02-04T19:11:07.586875Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55480/133889 blocks (41.4%), 0 events +2026-02-04T19:11:07.846975Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55490/133889 blocks (41.4%), 0 events +2026-02-04T19:11:08.038193Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55500/133889 blocks (41.5%), 0 events +2026-02-04T19:11:08.220304Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55510/133889 blocks (41.5%), 0 events +2026-02-04T19:11:08.411196Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55520/133889 blocks (41.5%), 0 events +2026-02-04T19:11:08.573598Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55530/133889 blocks (41.5%), 0 events +2026-02-04T19:11:08.777647Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55540/133889 blocks (41.5%), 0 events +2026-02-04T19:11:09.025210Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55550/133889 blocks (41.5%), 0 events +2026-02-04T19:11:09.197383Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55560/133889 blocks (41.5%), 0 events +2026-02-04T19:11:09.454662Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55570/133889 blocks (41.5%), 0 events +2026-02-04T19:11:09.630325Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55580/133889 blocks (41.5%), 0 events +2026-02-04T19:11:09.839330Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55590/133889 blocks (41.5%), 0 events +2026-02-04T19:11:09.983549Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55600/133889 blocks (41.5%), 0 events +2026-02-04T19:11:10.194233Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55610/133889 blocks (41.5%), 0 events +2026-02-04T19:11:10.502772Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55620/133889 blocks (41.5%), 0 events +2026-02-04T19:11:10.644062Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55630/133889 blocks (41.5%), 0 events +2026-02-04T19:11:10.832652Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55640/133889 blocks (41.6%), 0 events +2026-02-04T19:11:11.034638Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55650/133889 blocks (41.6%), 0 events +2026-02-04T19:11:11.229386Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55660/133889 blocks (41.6%), 0 events +2026-02-04T19:11:11.376784Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55670/133889 blocks (41.6%), 0 events +2026-02-04T19:11:11.569370Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55680/133889 blocks (41.6%), 0 events +2026-02-04T19:11:11.836666Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55690/133889 blocks (41.6%), 0 events +2026-02-04T19:11:12.076242Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55700/133889 blocks (41.6%), 0 events +2026-02-04T19:11:12.250809Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55710/133889 blocks (41.6%), 0 events +2026-02-04T19:11:12.377793Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55720/133889 blocks (41.6%), 0 events +2026-02-04T19:11:12.665746Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55730/133889 blocks (41.6%), 0 events +2026-02-04T19:11:12.860440Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55740/133889 blocks (41.6%), 0 events +2026-02-04T19:11:13.089941Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55750/133889 blocks (41.6%), 0 events +2026-02-04T19:11:13.209096Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55760/133889 blocks (41.6%), 0 events +2026-02-04T19:11:13.398541Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55770/133889 blocks (41.7%), 0 events +2026-02-04T19:11:13.647523Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55780/133889 blocks (41.7%), 0 events +2026-02-04T19:11:13.834892Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55790/133889 blocks (41.7%), 0 events +2026-02-04T19:11:14.139656Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55800/133889 blocks (41.7%), 0 events +2026-02-04T19:11:14.181802Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55810/133889 blocks (41.7%), 0 events +2026-02-04T19:11:14.393863Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55820/133889 blocks (41.7%), 0 events +2026-02-04T19:11:14.663635Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55830/133889 blocks (41.7%), 0 events +2026-02-04T19:11:14.806567Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55840/133889 blocks (41.7%), 0 events +2026-02-04T19:11:14.977808Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55850/133889 blocks (41.7%), 0 events +2026-02-04T19:11:15.221306Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55860/133889 blocks (41.7%), 0 events +2026-02-04T19:11:15.427627Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55870/133889 blocks (41.7%), 0 events +2026-02-04T19:11:15.712283Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55880/133889 blocks (41.7%), 0 events +2026-02-04T19:11:15.820976Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55890/133889 blocks (41.7%), 0 events +2026-02-04T19:11:15.971539Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55900/133889 blocks (41.8%), 0 events +2026-02-04T19:11:16.265947Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55910/133889 blocks (41.8%), 0 events +2026-02-04T19:11:16.409387Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55920/133889 blocks (41.8%), 0 events +2026-02-04T19:11:16.643838Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55930/133889 blocks (41.8%), 0 events +2026-02-04T19:11:16.823725Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55940/133889 blocks (41.8%), 0 events +2026-02-04T19:11:16.968839Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55950/133889 blocks (41.8%), 0 events +2026-02-04T19:11:17.285192Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55960/133889 blocks (41.8%), 0 events +2026-02-04T19:11:17.416405Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55970/133889 blocks (41.8%), 0 events +2026-02-04T19:11:17.571219Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55980/133889 blocks (41.8%), 0 events +2026-02-04T19:11:17.859796Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55990/133889 blocks (41.8%), 0 events +2026-02-04T19:11:17.993803Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56000/133889 blocks (41.8%), 0 events +2026-02-04T19:11:18.173498Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56010/133889 blocks (41.8%), 0 events +2026-02-04T19:11:18.529269Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56020/133889 blocks (41.8%), 0 events +2026-02-04T19:11:18.568363Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56030/133889 blocks (41.8%), 0 events +2026-02-04T19:11:18.896500Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56040/133889 blocks (41.9%), 0 events +2026-02-04T19:11:19.087299Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56050/133889 blocks (41.9%), 0 events +2026-02-04T19:11:19.196563Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56060/133889 blocks (41.9%), 0 events +2026-02-04T19:11:19.412332Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56070/133889 blocks (41.9%), 0 events +2026-02-04T19:11:19.615000Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56080/133889 blocks (41.9%), 0 events +2026-02-04T19:11:19.782189Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56090/133889 blocks (41.9%), 0 events +2026-02-04T19:11:20.102317Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56100/133889 blocks (41.9%), 0 events +2026-02-04T19:11:20.187653Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56110/133889 blocks (41.9%), 0 events +2026-02-04T19:11:20.470110Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56120/133889 blocks (41.9%), 0 events +2026-02-04T19:11:20.626058Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56130/133889 blocks (41.9%), 0 events +2026-02-04T19:11:20.827946Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56140/133889 blocks (41.9%), 0 events +2026-02-04T19:11:21.017148Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56150/133889 blocks (41.9%), 0 events +2026-02-04T19:11:21.184174Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56160/133889 blocks (41.9%), 0 events +2026-02-04T19:11:21.523246Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56170/133889 blocks (42.0%), 0 events +2026-02-04T19:11:21.563121Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56180/133889 blocks (42.0%), 0 events +2026-02-04T19:11:21.804448Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56190/133889 blocks (42.0%), 0 events +2026-02-04T19:11:22.041980Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56200/133889 blocks (42.0%), 0 events +2026-02-04T19:11:22.237428Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56210/133889 blocks (42.0%), 0 events +2026-02-04T19:11:22.526851Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56220/133889 blocks (42.0%), 0 events +2026-02-04T19:11:22.569025Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56230/133889 blocks (42.0%), 0 events +2026-02-04T19:11:22.778578Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56240/133889 blocks (42.0%), 0 events +2026-02-04T19:11:23.084854Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56250/133889 blocks (42.0%), 0 events +2026-02-04T19:11:23.280885Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56260/133889 blocks (42.0%), 0 events +2026-02-04T19:11:23.418435Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56270/133889 blocks (42.0%), 0 events +2026-02-04T19:11:23.608439Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56280/133889 blocks (42.0%), 0 events +2026-02-04T19:11:23.864585Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56290/133889 blocks (42.0%), 0 events +2026-02-04T19:11:23.979638Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56300/133889 blocks (42.0%), 0 events +2026-02-04T19:11:24.198306Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56310/133889 blocks (42.1%), 0 events +2026-02-04T19:11:24.453443Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56320/133889 blocks (42.1%), 0 events +2026-02-04T19:11:24.653052Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56330/133889 blocks (42.1%), 0 events +2026-02-04T19:11:24.782796Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56340/133889 blocks (42.1%), 0 events +2026-02-04T19:11:24.969025Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56350/133889 blocks (42.1%), 0 events +2026-02-04T19:11:25.256907Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56360/133889 blocks (42.1%), 0 events +2026-02-04T19:11:25.368215Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56370/133889 blocks (42.1%), 0 events +2026-02-04T19:11:25.707802Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56380/133889 blocks (42.1%), 0 events +2026-02-04T19:11:25.797628Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56390/133889 blocks (42.1%), 0 events +2026-02-04T19:11:25.988108Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56400/133889 blocks (42.1%), 0 events +2026-02-04T19:11:26.230680Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56410/133889 blocks (42.1%), 0 events +2026-02-04T19:11:26.396432Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56420/133889 blocks (42.1%), 0 events +2026-02-04T19:11:26.601491Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56430/133889 blocks (42.1%), 0 events +2026-02-04T19:11:26.787607Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56440/133889 blocks (42.2%), 0 events +2026-02-04T19:11:27.040969Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56450/133889 blocks (42.2%), 0 events +2026-02-04T19:11:27.281862Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56460/133889 blocks (42.2%), 0 events +2026-02-04T19:11:27.385340Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56470/133889 blocks (42.2%), 0 events +2026-02-04T19:11:27.646019Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56480/133889 blocks (42.2%), 0 events +2026-02-04T19:11:27.804275Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56490/133889 blocks (42.2%), 0 events +2026-02-04T19:11:28.055350Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56500/133889 blocks (42.2%), 0 events +2026-02-04T19:11:28.187096Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56510/133889 blocks (42.2%), 0 events +2026-02-04T19:11:28.399956Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56520/133889 blocks (42.2%), 0 events +2026-02-04T19:11:28.620624Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56530/133889 blocks (42.2%), 0 events +2026-02-04T19:11:28.851462Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56540/133889 blocks (42.2%), 0 events +2026-02-04T19:11:28.988883Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56550/133889 blocks (42.2%), 0 events +2026-02-04T19:11:29.226381Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56560/133889 blocks (42.2%), 0 events +2026-02-04T19:11:29.431505Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56570/133889 blocks (42.3%), 0 events +2026-02-04T19:11:29.629692Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56580/133889 blocks (42.3%), 0 events +2026-02-04T19:11:29.908236Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56590/133889 blocks (42.3%), 0 events +2026-02-04T19:11:29.982441Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56600/133889 blocks (42.3%), 0 events +2026-02-04T19:11:30.175232Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56610/133889 blocks (42.3%), 0 events +2026-02-04T19:11:30.424652Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56620/133889 blocks (42.3%), 0 events +2026-02-04T19:11:30.619657Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56630/133889 blocks (42.3%), 0 events +2026-02-04T19:11:30.808038Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56640/133889 blocks (42.3%), 0 events +2026-02-04T19:11:31.016639Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56650/133889 blocks (42.3%), 0 events +2026-02-04T19:11:31.232556Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56660/133889 blocks (42.3%), 0 events +2026-02-04T19:11:31.472063Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56670/133889 blocks (42.3%), 0 events +2026-02-04T19:11:31.581295Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56680/133889 blocks (42.3%), 0 events +2026-02-04T19:11:31.776618Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56690/133889 blocks (42.3%), 0 events +2026-02-04T19:11:32.029371Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56700/133889 blocks (42.3%), 0 events +2026-02-04T19:11:32.185510Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56710/133889 blocks (42.4%), 0 events +2026-02-04T19:11:32.518238Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56720/133889 blocks (42.4%), 0 events +2026-02-04T19:11:32.553500Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56730/133889 blocks (42.4%), 0 events +2026-02-04T19:11:32.802823Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56740/133889 blocks (42.4%), 0 events +2026-02-04T19:11:33.045581Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56750/133889 blocks (42.4%), 0 events +2026-02-04T19:11:33.206129Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56760/133889 blocks (42.4%), 0 events +2026-02-04T19:11:33.536888Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56770/133889 blocks (42.4%), 0 events +2026-02-04T19:11:33.576933Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56780/133889 blocks (42.4%), 0 events +2026-02-04T19:11:33.801758Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56790/133889 blocks (42.4%), 0 events +2026-02-04T19:11:34.095979Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56800/133889 blocks (42.4%), 0 events +2026-02-04T19:11:34.203253Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56810/133889 blocks (42.4%), 0 events +2026-02-04T19:11:34.458421Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56820/133889 blocks (42.4%), 0 events +2026-02-04T19:11:34.618915Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56830/133889 blocks (42.4%), 0 events +2026-02-04T19:11:34.781284Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56840/133889 blocks (42.5%), 0 events +2026-02-04T19:11:35.144825Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56850/133889 blocks (42.5%), 0 events +2026-02-04T19:11:35.181616Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56860/133889 blocks (42.5%), 0 events +2026-02-04T19:11:35.373184Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56870/133889 blocks (42.5%), 0 events +2026-02-04T19:11:35.665698Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56880/133889 blocks (42.5%), 0 events +2026-02-04T19:11:35.835203Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56890/133889 blocks (42.5%), 0 events +2026-02-04T19:11:35.964994Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56900/133889 blocks (42.5%), 0 events +2026-02-04T19:11:36.219089Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56910/133889 blocks (42.5%), 0 events +2026-02-04T19:11:36.424904Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56920/133889 blocks (42.5%), 0 events +2026-02-04T19:11:36.714293Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56930/133889 blocks (42.5%), 0 events +2026-02-04T19:11:36.799273Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56940/133889 blocks (42.5%), 0 events +2026-02-04T19:11:36.988236Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56950/133889 blocks (42.5%), 0 events +2026-02-04T19:11:37.240213Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56960/133889 blocks (42.5%), 0 events +2026-02-04T19:11:37.389587Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56970/133889 blocks (42.5%), 0 events +2026-02-04T19:11:37.581374Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56980/133889 blocks (42.6%), 0 events +2026-02-04T19:11:37.839604Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56990/133889 blocks (42.6%), 0 events +2026-02-04T19:11:38.029115Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57000/133889 blocks (42.6%), 0 events +2026-02-04T19:11:38.286755Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57010/133889 blocks (42.6%), 0 events +2026-02-04T19:11:38.368158Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57020/133889 blocks (42.6%), 0 events +2026-02-04T19:11:38.622678Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57030/133889 blocks (42.6%), 0 events +2026-02-04T19:11:38.807113Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57040/133889 blocks (42.6%), 0 events +2026-02-04T19:11:38.991837Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57050/133889 blocks (42.6%), 0 events +2026-02-04T19:11:39.185324Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57060/133889 blocks (42.6%), 0 events +2026-02-04T19:11:39.473200Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57070/133889 blocks (42.6%), 0 events +2026-02-04T19:11:39.649673Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57080/133889 blocks (42.6%), 0 events +2026-02-04T19:11:39.861225Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57090/133889 blocks (42.6%), 0 events +2026-02-04T19:11:40.058176Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57100/133889 blocks (42.6%), 0 events +2026-02-04T19:11:40.226658Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57110/133889 blocks (42.7%), 0 events +2026-02-04T19:11:40.388164Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57120/133889 blocks (42.7%), 0 events +2026-02-04T19:11:40.588039Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57130/133889 blocks (42.7%), 0 events +2026-02-04T19:11:40.919323Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57140/133889 blocks (42.7%), 0 events +2026-02-04T19:11:40.956991Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57150/133889 blocks (42.7%), 0 events +2026-02-04T19:11:41.168907Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57160/133889 blocks (42.7%), 0 events +2026-02-04T19:11:41.433099Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57170/133889 blocks (42.7%), 0 events +2026-02-04T19:11:41.651027Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57180/133889 blocks (42.7%), 0 events +2026-02-04T19:11:41.765724Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57190/133889 blocks (42.7%), 0 events +2026-02-04T19:11:41.995216Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57200/133889 blocks (42.7%), 0 events +2026-02-04T19:11:42.205610Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57210/133889 blocks (42.7%), 0 events +2026-02-04T19:11:42.449355Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57220/133889 blocks (42.7%), 0 events +2026-02-04T19:11:42.619218Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57230/133889 blocks (42.7%), 0 events +2026-02-04T19:11:42.857675Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57240/133889 blocks (42.8%), 0 events +2026-02-04T19:11:43.000935Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57250/133889 blocks (42.8%), 0 events +2026-02-04T19:11:43.215273Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57260/133889 blocks (42.8%), 0 events +2026-02-04T19:11:43.381456Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57270/133889 blocks (42.8%), 0 events +2026-02-04T19:11:43.605156Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57280/133889 blocks (42.8%), 0 events +2026-02-04T19:11:43.774406Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57290/133889 blocks (42.8%), 0 events +2026-02-04T19:11:44.055871Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57300/133889 blocks (42.8%), 0 events +2026-02-04T19:11:44.182911Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57310/133889 blocks (42.8%), 0 events +2026-02-04T19:11:44.546560Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57320/133889 blocks (42.8%), 0 events +2026-02-04T19:11:44.589183Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57330/133889 blocks (42.8%), 0 events +2026-02-04T19:11:44.818424Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57340/133889 blocks (42.8%), 0 events +2026-02-04T19:11:45.216575Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57350/133889 blocks (42.8%), 0 events +2026-02-04T19:11:45.261448Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57360/133889 blocks (42.8%), 0 events +2026-02-04T19:11:45.378037Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57370/133889 blocks (42.8%), 0 events +2026-02-04T19:11:45.651674Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57380/133889 blocks (42.9%), 0 events +2026-02-04T19:11:45.772281Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57390/133889 blocks (42.9%), 0 events +2026-02-04T19:11:45.979687Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57400/133889 blocks (42.9%), 0 events +2026-02-04T19:11:46.175606Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57410/133889 blocks (42.9%), 0 events +2026-02-04T19:11:46.396157Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57420/133889 blocks (42.9%), 0 events +2026-02-04T19:11:46.678742Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57430/133889 blocks (42.9%), 0 events +2026-02-04T19:11:46.810493Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57440/133889 blocks (42.9%), 0 events +2026-02-04T19:11:47.020867Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57450/133889 blocks (42.9%), 0 events +2026-02-04T19:11:47.210656Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57460/133889 blocks (42.9%), 0 events +2026-02-04T19:11:47.463710Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57470/133889 blocks (42.9%), 0 events +2026-02-04T19:11:47.724192Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57480/133889 blocks (42.9%), 0 events +2026-02-04T19:11:47.761137Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57490/133889 blocks (42.9%), 0 events +2026-02-04T19:11:47.977611Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57500/133889 blocks (42.9%), 0 events +2026-02-04T19:11:48.251096Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57510/133889 blocks (43.0%), 0 events +2026-02-04T19:11:48.410202Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57520/133889 blocks (43.0%), 0 events +2026-02-04T19:11:48.581993Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57530/133889 blocks (43.0%), 0 events +2026-02-04T19:11:48.861321Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57540/133889 blocks (43.0%), 0 events +2026-02-04T19:11:49.007902Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57550/133889 blocks (43.0%), 0 events +2026-02-04T19:11:49.266436Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57560/133889 blocks (43.0%), 0 events +2026-02-04T19:11:49.446879Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57570/133889 blocks (43.0%), 0 events +2026-02-04T19:11:49.584359Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57580/133889 blocks (43.0%), 0 events +2026-02-04T19:11:49.828166Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57590/133889 blocks (43.0%), 0 events +2026-02-04T19:11:50.022711Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57600/133889 blocks (43.0%), 0 events +2026-02-04T19:11:50.311338Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57610/133889 blocks (43.0%), 0 events +2026-02-04T19:11:50.442281Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57620/133889 blocks (43.0%), 0 events +2026-02-04T19:11:50.623545Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57630/133889 blocks (43.0%), 0 events +2026-02-04T19:11:50.870482Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57640/133889 blocks (43.1%), 0 events +2026-02-04T19:11:51.058374Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57650/133889 blocks (43.1%), 0 events +2026-02-04T19:11:51.163483Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57660/133889 blocks (43.1%), 0 events +2026-02-04T19:11:51.429554Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57670/133889 blocks (43.1%), 0 events +2026-02-04T19:11:51.618569Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57680/133889 blocks (43.1%), 0 events +2026-02-04T19:11:51.772774Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57690/133889 blocks (43.1%), 0 events +2026-02-04T19:11:51.976020Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57700/133889 blocks (43.1%), 0 events +2026-02-04T19:11:52.182935Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57710/133889 blocks (43.1%), 0 events +2026-02-04T19:11:52.446999Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57720/133889 blocks (43.1%), 0 events +2026-02-04T19:11:52.650780Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57730/133889 blocks (43.1%), 0 events +2026-02-04T19:11:52.823836Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57740/133889 blocks (43.1%), 0 events +2026-02-04T19:11:53.036868Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57750/133889 blocks (43.1%), 0 events +2026-02-04T19:11:53.271278Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57760/133889 blocks (43.1%), 0 events +2026-02-04T19:11:53.458762Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57770/133889 blocks (43.1%), 0 events +2026-02-04T19:11:53.600156Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57780/133889 blocks (43.2%), 0 events +2026-02-04T19:11:53.854108Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57790/133889 blocks (43.2%), 0 events +2026-02-04T19:11:54.071621Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57800/133889 blocks (43.2%), 0 events +2026-02-04T19:11:54.292294Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57810/133889 blocks (43.2%), 0 events +2026-02-04T19:11:54.403024Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57820/133889 blocks (43.2%), 0 events +2026-02-04T19:11:54.627381Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57830/133889 blocks (43.2%), 0 events +2026-02-04T19:11:54.845642Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57840/133889 blocks (43.2%), 0 events +2026-02-04T19:11:55.063049Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57850/133889 blocks (43.2%), 0 events +2026-02-04T19:11:55.227649Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57860/133889 blocks (43.2%), 0 events +2026-02-04T19:11:55.395532Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57870/133889 blocks (43.2%), 0 events +2026-02-04T19:11:55.629013Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57880/133889 blocks (43.2%), 0 events +2026-02-04T19:11:55.832799Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57890/133889 blocks (43.2%), 0 events +2026-02-04T19:11:56.079395Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57900/133889 blocks (43.2%), 0 events +2026-02-04T19:11:56.229913Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57910/133889 blocks (43.3%), 0 events +2026-02-04T19:11:56.391798Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57920/133889 blocks (43.3%), 0 events +2026-02-04T19:11:56.650014Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57930/133889 blocks (43.3%), 0 events +2026-02-04T19:11:56.846444Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57940/133889 blocks (43.3%), 0 events +2026-02-04T19:11:57.129645Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57950/133889 blocks (43.3%), 0 events +2026-02-04T19:11:57.173039Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57960/133889 blocks (43.3%), 0 events +2026-02-04T19:11:57.386191Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57970/133889 blocks (43.3%), 0 events +2026-02-04T19:11:57.686250Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57980/133889 blocks (43.3%), 0 events +2026-02-04T19:11:57.814629Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57990/133889 blocks (43.3%), 0 events +2026-02-04T19:11:57.973440Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58000/133889 blocks (43.3%), 0 events +2026-02-04T19:11:58.236668Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58010/133889 blocks (43.3%), 0 events +2026-02-04T19:11:58.463427Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58020/133889 blocks (43.3%), 0 events +2026-02-04T19:11:58.699495Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58030/133889 blocks (43.3%), 0 events +2026-02-04T19:11:58.846187Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58040/133889 blocks (43.3%), 0 events +2026-02-04T19:11:59.018391Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58050/133889 blocks (43.4%), 0 events +2026-02-04T19:11:59.260256Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58060/133889 blocks (43.4%), 0 events +2026-02-04T19:11:59.437593Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58070/133889 blocks (43.4%), 0 events +2026-02-04T19:11:59.578255Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58080/133889 blocks (43.4%), 0 events +2026-02-04T19:11:59.805987Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58090/133889 blocks (43.4%), 0 events +2026-02-04T19:12:00.054838Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58100/133889 blocks (43.4%), 0 events +2026-02-04T19:12:00.183282Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58110/133889 blocks (43.4%), 0 events +2026-02-04T19:12:00.390715Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58120/133889 blocks (43.4%), 0 events +2026-02-04T19:12:00.651469Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58130/133889 blocks (43.4%), 0 events +2026-02-04T19:12:00.829003Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58140/133889 blocks (43.4%), 0 events +2026-02-04T19:12:00.999476Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58150/133889 blocks (43.4%), 0 events +2026-02-04T19:12:01.183755Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58160/133889 blocks (43.4%), 0 events +2026-02-04T19:12:01.439456Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58170/133889 blocks (43.4%), 0 events +2026-02-04T19:12:01.608592Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58180/133889 blocks (43.5%), 0 events +2026-02-04T19:12:01.880591Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58190/133889 blocks (43.5%), 0 events +2026-02-04T19:12:02.000809Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58200/133889 blocks (43.5%), 0 events +2026-02-04T19:12:02.226940Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58210/133889 blocks (43.5%), 0 events +2026-02-04T19:12:02.434071Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58220/133889 blocks (43.5%), 0 events +2026-02-04T19:12:02.641288Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58230/133889 blocks (43.5%), 0 events +2026-02-04T19:12:02.893455Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58240/133889 blocks (43.5%), 0 events +2026-02-04T19:12:03.000761Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58250/133889 blocks (43.5%), 0 events +2026-02-04T19:12:03.217657Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58260/133889 blocks (43.5%), 0 events +2026-02-04T19:12:03.459533Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58270/133889 blocks (43.5%), 0 events +2026-02-04T19:12:03.607073Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58280/133889 blocks (43.5%), 0 events +2026-02-04T19:12:03.797440Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58290/133889 blocks (43.5%), 0 events +2026-02-04T19:12:04.064560Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58300/133889 blocks (43.5%), 0 events +2026-02-04T19:12:04.260103Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58310/133889 blocks (43.6%), 0 events +2026-02-04T19:12:04.468452Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58320/133889 blocks (43.6%), 0 events +2026-02-04T19:12:04.637567Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58330/133889 blocks (43.6%), 0 events +2026-02-04T19:12:04.850541Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58340/133889 blocks (43.6%), 0 events +2026-02-04T19:12:05.036877Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58350/133889 blocks (43.6%), 0 events +2026-02-04T19:12:05.209170Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58360/133889 blocks (43.6%), 0 events +2026-02-04T19:12:05.383216Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58370/133889 blocks (43.6%), 0 events +2026-02-04T19:12:05.660410Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58380/133889 blocks (43.6%), 0 events +2026-02-04T19:12:05.828035Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58390/133889 blocks (43.6%), 0 events +2026-02-04T19:12:06.072435Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58400/133889 blocks (43.6%), 0 events +2026-02-04T19:12:06.167229Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58410/133889 blocks (43.6%), 0 events +2026-02-04T19:12:06.425642Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58420/133889 blocks (43.6%), 0 events +2026-02-04T19:12:06.600745Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58430/133889 blocks (43.6%), 0 events +2026-02-04T19:12:06.827506Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58440/133889 blocks (43.6%), 0 events +2026-02-04T19:12:07.090125Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58450/133889 blocks (43.7%), 0 events +2026-02-04T19:12:07.208577Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58460/133889 blocks (43.7%), 0 events +2026-02-04T19:12:07.376677Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58470/133889 blocks (43.7%), 0 events +2026-02-04T19:12:07.649903Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58480/133889 blocks (43.7%), 0 events +2026-02-04T19:12:07.775057Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58490/133889 blocks (43.7%), 0 events +2026-02-04T19:12:08.139256Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58500/133889 blocks (43.7%), 0 events +2026-02-04T19:12:08.180570Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58510/133889 blocks (43.7%), 0 events +2026-02-04T19:12:08.398088Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58520/133889 blocks (43.7%), 0 events +2026-02-04T19:12:08.693416Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58530/133889 blocks (43.7%), 0 events +2026-02-04T19:12:08.825147Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58540/133889 blocks (43.7%), 0 events +2026-02-04T19:12:09.024776Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58550/133889 blocks (43.7%), 0 events +2026-02-04T19:12:09.284747Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58560/133889 blocks (43.7%), 0 events +2026-02-04T19:12:09.409201Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58570/133889 blocks (43.7%), 0 events +2026-02-04T19:12:09.711649Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58580/133889 blocks (43.8%), 0 events +2026-02-04T19:12:09.791260Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58590/133889 blocks (43.8%), 0 events +2026-02-04T19:12:09.963245Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58600/133889 blocks (43.8%), 0 events +2026-02-04T19:12:10.268010Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58610/133889 blocks (43.8%), 0 events +2026-02-04T19:12:10.400627Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58620/133889 blocks (43.8%), 0 events +2026-02-04T19:12:10.602764Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58630/133889 blocks (43.8%), 0 events +2026-02-04T19:12:10.839302Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58640/133889 blocks (43.8%), 0 events +2026-02-04T19:12:11.049635Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58650/133889 blocks (43.8%), 0 events +2026-02-04T19:12:11.284507Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58660/133889 blocks (43.8%), 0 events +2026-02-04T19:12:11.445493Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58670/133889 blocks (43.8%), 0 events +2026-02-04T19:12:11.571993Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58680/133889 blocks (43.8%), 0 events +2026-02-04T19:12:11.851506Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58690/133889 blocks (43.8%), 0 events +2026-02-04T19:12:12.052405Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58700/133889 blocks (43.8%), 0 events +2026-02-04T19:12:12.199430Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58710/133889 blocks (43.8%), 0 events +2026-02-04T19:12:12.425516Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58720/133889 blocks (43.9%), 0 events +2026-02-04T19:12:12.572464Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58730/133889 blocks (43.9%), 0 events +2026-02-04T19:12:12.892387Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58740/133889 blocks (43.9%), 0 events +2026-02-04T19:12:12.972531Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58750/133889 blocks (43.9%), 0 events +2026-02-04T19:12:13.196338Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58760/133889 blocks (43.9%), 0 events +2026-02-04T19:12:13.418833Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58770/133889 blocks (43.9%), 0 events +2026-02-04T19:12:13.587103Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58780/133889 blocks (43.9%), 0 events +2026-02-04T19:12:13.775375Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58790/133889 blocks (43.9%), 0 events +2026-02-04T19:12:14.003707Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58800/133889 blocks (43.9%), 0 events +2026-02-04T19:12:14.192543Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58810/133889 blocks (43.9%), 0 events +2026-02-04T19:12:14.460841Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58820/133889 blocks (43.9%), 0 events +2026-02-04T19:12:14.599700Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58830/133889 blocks (43.9%), 0 events +2026-02-04T19:12:14.850009Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58840/133889 blocks (43.9%), 0 events +2026-02-04T19:12:14.988011Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58850/133889 blocks (44.0%), 0 events +2026-02-04T19:12:15.218712Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58860/133889 blocks (44.0%), 0 events +2026-02-04T19:12:15.514682Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58870/133889 blocks (44.0%), 0 events +2026-02-04T19:12:15.676438Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58880/133889 blocks (44.0%), 0 events +2026-02-04T19:12:15.824576Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58890/133889 blocks (44.0%), 0 events +2026-02-04T19:12:16.036816Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58900/133889 blocks (44.0%), 0 events +2026-02-04T19:12:16.230777Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58910/133889 blocks (44.0%), 0 events +2026-02-04T19:12:16.402413Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58920/133889 blocks (44.0%), 0 events +2026-02-04T19:12:16.590399Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58930/133889 blocks (44.0%), 0 events +2026-02-04T19:12:16.825352Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58940/133889 blocks (44.0%), 0 events +2026-02-04T19:12:17.085581Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58950/133889 blocks (44.0%), 0 events +2026-02-04T19:12:17.259316Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58960/133889 blocks (44.0%), 0 events +2026-02-04T19:12:17.384211Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58970/133889 blocks (44.0%), 0 events +2026-02-04T19:12:17.648917Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58980/133889 blocks (44.1%), 0 events +2026-02-04T19:12:17.845369Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58990/133889 blocks (44.1%), 0 events +2026-02-04T19:12:18.099185Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59000/133889 blocks (44.1%), 0 events +2026-02-04T19:12:18.236774Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59010/133889 blocks (44.1%), 0 events +2026-02-04T19:12:18.426017Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59020/133889 blocks (44.1%), 0 events +2026-02-04T19:12:18.653819Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59030/133889 blocks (44.1%), 0 events +2026-02-04T19:12:18.860809Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59040/133889 blocks (44.1%), 0 events +2026-02-04T19:12:19.148152Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59050/133889 blocks (44.1%), 0 events +2026-02-04T19:12:19.184549Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59060/133889 blocks (44.1%), 0 events +2026-02-04T19:12:19.459339Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59070/133889 blocks (44.1%), 0 events +2026-02-04T19:12:19.672122Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59080/133889 blocks (44.1%), 0 events +2026-02-04T19:12:19.868252Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59090/133889 blocks (44.1%), 0 events +2026-02-04T19:12:20.043369Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59100/133889 blocks (44.1%), 0 events +2026-02-04T19:12:20.229039Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59110/133889 blocks (44.1%), 0 events +2026-02-04T19:12:20.432710Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59120/133889 blocks (44.2%), 0 events +2026-02-04T19:12:20.618473Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59130/133889 blocks (44.2%), 0 events +2026-02-04T19:12:20.768634Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59140/133889 blocks (44.2%), 0 events +2026-02-04T19:12:20.993915Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59150/133889 blocks (44.2%), 0 events +2026-02-04T19:12:21.244770Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59160/133889 blocks (44.2%), 0 events +2026-02-04T19:12:21.482580Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59170/133889 blocks (44.2%), 0 events +2026-02-04T19:12:21.637244Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59180/133889 blocks (44.2%), 0 events +2026-02-04T19:12:21.820357Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59190/133889 blocks (44.2%), 0 events +2026-02-04T19:12:22.015054Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59200/133889 blocks (44.2%), 0 events +2026-02-04T19:12:22.196363Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59210/133889 blocks (44.2%), 0 events +2026-02-04T19:12:22.392823Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59220/133889 blocks (44.2%), 0 events +2026-02-04T19:12:22.661132Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59230/133889 blocks (44.2%), 0 events +2026-02-04T19:12:22.853648Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59240/133889 blocks (44.2%), 0 events +2026-02-04T19:12:22.976262Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59250/133889 blocks (44.3%), 0 events +2026-02-04T19:12:23.341635Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59260/133889 blocks (44.3%), 0 events +2026-02-04T19:12:23.379123Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59270/133889 blocks (44.3%), 0 events +2026-02-04T19:12:23.640664Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59280/133889 blocks (44.3%), 0 events +2026-02-04T19:12:23.866011Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59290/133889 blocks (44.3%), 0 events +2026-02-04T19:12:23.997686Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59300/133889 blocks (44.3%), 0 events +2026-02-04T19:12:24.209875Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59310/133889 blocks (44.3%), 0 events +2026-02-04T19:12:24.442666Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59320/133889 blocks (44.3%), 0 events +2026-02-04T19:12:24.592970Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59330/133889 blocks (44.3%), 0 events +2026-02-04T19:12:24.815348Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59340/133889 blocks (44.3%), 0 events +2026-02-04T19:12:24.974428Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59350/133889 blocks (44.3%), 0 events +2026-02-04T19:12:25.223433Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59360/133889 blocks (44.3%), 0 events +2026-02-04T19:12:25.485460Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59370/133889 blocks (44.3%), 0 events +2026-02-04T19:12:25.644385Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59380/133889 blocks (44.3%), 0 events +2026-02-04T19:12:25.850326Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59390/133889 blocks (44.4%), 0 events +2026-02-04T19:12:26.016750Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59400/133889 blocks (44.4%), 0 events +2026-02-04T19:12:26.235626Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59410/133889 blocks (44.4%), 0 events +2026-02-04T19:12:26.487000Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59420/133889 blocks (44.4%), 0 events +2026-02-04T19:12:26.620031Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59430/133889 blocks (44.4%), 0 events +2026-02-04T19:12:26.855666Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59440/133889 blocks (44.4%), 0 events +2026-02-04T19:12:27.056271Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59450/133889 blocks (44.4%), 0 events +2026-02-04T19:12:27.255080Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59460/133889 blocks (44.4%), 0 events +2026-02-04T19:12:27.436271Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59470/133889 blocks (44.4%), 0 events +2026-02-04T19:12:27.653481Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59480/133889 blocks (44.4%), 0 events +2026-02-04T19:12:27.812096Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59490/133889 blocks (44.4%), 0 events +2026-02-04T19:12:27.962767Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59500/133889 blocks (44.4%), 0 events +2026-02-04T19:12:28.227796Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59510/133889 blocks (44.4%), 0 events +2026-02-04T19:12:28.432450Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59520/133889 blocks (44.5%), 0 events +2026-02-04T19:12:28.634309Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59530/133889 blocks (44.5%), 0 events +2026-02-04T19:12:28.833062Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59540/133889 blocks (44.5%), 0 events +2026-02-04T19:12:28.995375Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59550/133889 blocks (44.5%), 0 events +2026-02-04T19:12:29.205279Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59560/133889 blocks (44.5%), 0 events +2026-02-04T19:12:29.379753Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59570/133889 blocks (44.5%), 0 events +2026-02-04T19:12:29.669231Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59580/133889 blocks (44.5%), 0 events +2026-02-04T19:12:29.774604Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59590/133889 blocks (44.5%), 0 events +2026-02-04T19:12:29.969749Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59600/133889 blocks (44.5%), 0 events +2026-02-04T19:12:30.199724Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59610/133889 blocks (44.5%), 0 events +2026-02-04T19:12:30.440214Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59620/133889 blocks (44.5%), 0 events +2026-02-04T19:12:30.713005Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59630/133889 blocks (44.5%), 0 events +2026-02-04T19:12:30.824033Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59640/133889 blocks (44.5%), 0 events +2026-02-04T19:12:31.036686Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59650/133889 blocks (44.6%), 0 events +2026-02-04T19:12:31.237900Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59660/133889 blocks (44.6%), 0 events +2026-02-04T19:12:31.437043Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59670/133889 blocks (44.6%), 0 events +2026-02-04T19:12:31.569518Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59680/133889 blocks (44.6%), 0 events +2026-02-04T19:12:31.759553Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59690/133889 blocks (44.6%), 0 events +2026-02-04T19:12:32.055759Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59700/133889 blocks (44.6%), 0 events +2026-02-04T19:12:32.288284Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59710/133889 blocks (44.6%), 0 events +2026-02-04T19:12:32.357935Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59720/133889 blocks (44.6%), 0 events +2026-02-04T19:12:32.661434Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59730/133889 blocks (44.6%), 0 events +2026-02-04T19:12:32.807800Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59740/133889 blocks (44.6%), 0 events +2026-02-04T19:12:33.027301Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59750/133889 blocks (44.6%), 0 events +2026-02-04T19:12:33.302687Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59760/133889 blocks (44.6%), 0 events +2026-02-04T19:12:33.415326Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59770/133889 blocks (44.6%), 0 events +2026-02-04T19:12:33.679906Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59780/133889 blocks (44.6%), 0 events +2026-02-04T19:12:33.860056Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59790/133889 blocks (44.7%), 0 events +2026-02-04T19:12:34.054087Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59800/133889 blocks (44.7%), 0 events +2026-02-04T19:12:34.247221Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59810/133889 blocks (44.7%), 0 events +2026-02-04T19:12:34.466295Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59820/133889 blocks (44.7%), 0 events +2026-02-04T19:12:34.566972Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59830/133889 blocks (44.7%), 0 events +2026-02-04T19:12:34.875811Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59840/133889 blocks (44.7%), 0 events +2026-02-04T19:12:34.990416Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59850/133889 blocks (44.7%), 0 events +2026-02-04T19:12:35.224228Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59860/133889 blocks (44.7%), 0 events +2026-02-04T19:12:35.431715Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59870/133889 blocks (44.7%), 0 events +2026-02-04T19:12:35.613705Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59880/133889 blocks (44.7%), 0 events +2026-02-04T19:12:35.924689Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59890/133889 blocks (44.7%), 0 events +2026-02-04T19:12:35.967537Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59900/133889 blocks (44.7%), 0 events +2026-02-04T19:12:36.263112Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59910/133889 blocks (44.7%), 0 events +2026-02-04T19:12:36.482753Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59920/133889 blocks (44.8%), 0 events +2026-02-04T19:12:36.588472Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59930/133889 blocks (44.8%), 0 events +2026-02-04T19:12:36.850572Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59940/133889 blocks (44.8%), 0 events +2026-02-04T19:12:37.051420Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59950/133889 blocks (44.8%), 0 events +2026-02-04T19:12:37.265341Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59960/133889 blocks (44.8%), 0 events +2026-02-04T19:12:37.497185Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59970/133889 blocks (44.8%), 0 events +2026-02-04T19:12:37.660275Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59980/133889 blocks (44.8%), 0 events +2026-02-04T19:12:37.796310Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59990/133889 blocks (44.8%), 0 events +2026-02-04T19:12:38.055697Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60000/133889 blocks (44.8%), 0 events +2026-02-04T19:12:38.211374Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60010/133889 blocks (44.8%), 0 events +2026-02-04T19:12:38.454530Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60020/133889 blocks (44.8%), 0 events +2026-02-04T19:12:38.658209Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60030/133889 blocks (44.8%), 0 events +2026-02-04T19:12:38.775843Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60040/133889 blocks (44.8%), 0 events +2026-02-04T19:12:39.109445Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60050/133889 blocks (44.9%), 0 events +2026-02-04T19:12:39.178754Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60060/133889 blocks (44.9%), 0 events +2026-02-04T19:12:39.420544Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60070/133889 blocks (44.9%), 0 events +2026-02-04T19:12:39.630332Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60080/133889 blocks (44.9%), 0 events +2026-02-04T19:12:39.855813Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60090/133889 blocks (44.9%), 0 events +2026-02-04T19:12:40.006464Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60100/133889 blocks (44.9%), 0 events +2026-02-04T19:12:40.257345Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60110/133889 blocks (44.9%), 0 events +2026-02-04T19:12:40.360688Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60120/133889 blocks (44.9%), 0 events +2026-02-04T19:12:40.689406Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60130/133889 blocks (44.9%), 0 events +2026-02-04T19:12:40.848511Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60140/133889 blocks (44.9%), 0 events +2026-02-04T19:12:40.989686Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60150/133889 blocks (44.9%), 0 events +2026-02-04T19:12:41.253464Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60160/133889 blocks (44.9%), 0 events +2026-02-04T19:12:41.363830Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60170/133889 blocks (44.9%), 0 events +2026-02-04T19:12:41.726140Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60180/133889 blocks (44.9%), 0 events +2026-02-04T19:12:41.774694Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60190/133889 blocks (45.0%), 0 events +2026-02-04T19:12:42.022846Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60200/133889 blocks (45.0%), 0 events +2026-02-04T19:12:42.269061Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60210/133889 blocks (45.0%), 0 events +2026-02-04T19:12:42.449096Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60220/133889 blocks (45.0%), 0 events +2026-02-04T19:12:42.584306Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60230/133889 blocks (45.0%), 0 events +2026-02-04T19:12:42.771792Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60240/133889 blocks (45.0%), 0 events +2026-02-04T19:12:43.040397Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60250/133889 blocks (45.0%), 0 events +2026-02-04T19:12:43.264178Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60260/133889 blocks (45.0%), 0 events +2026-02-04T19:12:43.357929Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60270/133889 blocks (45.0%), 0 events +2026-02-04T19:12:43.597113Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60280/133889 blocks (45.0%), 0 events +2026-02-04T19:12:43.825931Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60290/133889 blocks (45.0%), 0 events +2026-02-04T19:12:43.963327Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60300/133889 blocks (45.0%), 0 events +2026-02-04T19:12:44.312870Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60310/133889 blocks (45.0%), 0 events +2026-02-04T19:12:44.359067Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60320/133889 blocks (45.1%), 0 events +2026-02-04T19:12:44.609273Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60330/133889 blocks (45.1%), 0 events +2026-02-04T19:12:44.867165Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60340/133889 blocks (45.1%), 0 events +2026-02-04T19:12:45.026249Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60350/133889 blocks (45.1%), 0 events +2026-02-04T19:12:45.196836Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60360/133889 blocks (45.1%), 0 events +2026-02-04T19:12:45.418493Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60370/133889 blocks (45.1%), 0 events +2026-02-04T19:12:45.655479Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60380/133889 blocks (45.1%), 0 events +2026-02-04T19:12:45.783326Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60390/133889 blocks (45.1%), 0 events +2026-02-04T19:12:46.052089Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60400/133889 blocks (45.1%), 0 events +2026-02-04T19:12:46.206035Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60410/133889 blocks (45.1%), 0 events +2026-02-04T19:12:46.444756Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60420/133889 blocks (45.1%), 0 events +2026-02-04T19:12:46.577583Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60430/133889 blocks (45.1%), 0 events +2026-02-04T19:12:46.817133Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60440/133889 blocks (45.1%), 0 events +2026-02-04T19:12:46.980696Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60450/133889 blocks (45.1%), 0 events +2026-02-04T19:12:47.225193Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60460/133889 blocks (45.2%), 0 events +2026-02-04T19:12:47.495321Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60470/133889 blocks (45.2%), 0 events +2026-02-04T19:12:47.658596Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60480/133889 blocks (45.2%), 0 events +2026-02-04T19:12:47.814794Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60490/133889 blocks (45.2%), 0 events +2026-02-04T19:12:48.016543Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60500/133889 blocks (45.2%), 0 events +2026-02-04T19:12:48.216801Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60510/133889 blocks (45.2%), 0 events +2026-02-04T19:12:48.506122Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60520/133889 blocks (45.2%), 0 events +2026-02-04T19:12:48.568629Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60530/133889 blocks (45.2%), 0 events +2026-02-04T19:12:48.864693Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60540/133889 blocks (45.2%), 0 events +2026-02-04T19:12:49.028631Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60550/133889 blocks (45.2%), 0 events +2026-02-04T19:12:49.222033Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60560/133889 blocks (45.2%), 0 events +2026-02-04T19:12:49.398526Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60570/133889 blocks (45.2%), 0 events +2026-02-04T19:12:49.597757Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60580/133889 blocks (45.2%), 0 events +2026-02-04T19:12:49.846908Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60590/133889 blocks (45.3%), 0 events +2026-02-04T19:12:50.077245Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60600/133889 blocks (45.3%), 0 events +2026-02-04T19:12:50.195434Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60610/133889 blocks (45.3%), 0 events +2026-02-04T19:12:50.441165Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60620/133889 blocks (45.3%), 0 events +2026-02-04T19:12:50.637016Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60630/133889 blocks (45.3%), 0 events +2026-02-04T19:12:50.836718Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60640/133889 blocks (45.3%), 0 events +2026-02-04T19:12:51.026431Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60650/133889 blocks (45.3%), 0 events +2026-02-04T19:12:51.239787Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60660/133889 blocks (45.3%), 0 events +2026-02-04T19:12:51.377369Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60670/133889 blocks (45.3%), 0 events +2026-02-04T19:12:51.688205Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60680/133889 blocks (45.3%), 0 events +2026-02-04T19:12:51.863040Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60690/133889 blocks (45.3%), 0 events +2026-02-04T19:12:52.054475Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60700/133889 blocks (45.3%), 0 events +2026-02-04T19:12:52.230143Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60710/133889 blocks (45.3%), 0 events +2026-02-04T19:12:52.413089Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60720/133889 blocks (45.4%), 0 events +2026-02-04T19:12:52.598726Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60730/133889 blocks (45.4%), 0 events +2026-02-04T19:12:52.815745Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60740/133889 blocks (45.4%), 0 events +2026-02-04T19:12:52.981554Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60750/133889 blocks (45.4%), 0 events +2026-02-04T19:12:53.261997Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60760/133889 blocks (45.4%), 0 events +2026-02-04T19:12:53.385640Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60770/133889 blocks (45.4%), 0 events +2026-02-04T19:12:53.632289Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60780/133889 blocks (45.4%), 0 events +2026-02-04T19:12:53.816744Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60790/133889 blocks (45.4%), 0 events +2026-02-04T19:12:54.022403Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60800/133889 blocks (45.4%), 0 events +2026-02-04T19:12:54.305964Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60810/133889 blocks (45.4%), 0 events +2026-02-04T19:12:54.461557Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60820/133889 blocks (45.4%), 0 events +2026-02-04T19:12:54.627927Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60830/133889 blocks (45.4%), 0 events +2026-02-04T19:12:54.832766Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60840/133889 blocks (45.4%), 0 events +2026-02-04T19:12:55.014511Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60850/133889 blocks (45.4%), 0 events +2026-02-04T19:12:55.196495Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60860/133889 blocks (45.5%), 0 events +2026-02-04T19:12:55.372981Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60870/133889 blocks (45.5%), 0 events +2026-02-04T19:12:55.664660Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60880/133889 blocks (45.5%), 0 events +2026-02-04T19:12:55.845717Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60890/133889 blocks (45.5%), 0 events +2026-02-04T19:12:56.061313Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60900/133889 blocks (45.5%), 0 events +2026-02-04T19:12:56.239615Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60910/133889 blocks (45.5%), 0 events +2026-02-04T19:12:56.404396Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60920/133889 blocks (45.5%), 0 events +2026-02-04T19:12:56.597759Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60930/133889 blocks (45.5%), 0 events +2026-02-04T19:12:56.895137Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60940/133889 blocks (45.5%), 0 events +2026-02-04T19:12:57.011165Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60950/133889 blocks (45.5%), 0 events +2026-02-04T19:12:57.195636Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60960/133889 blocks (45.5%), 0 events +2026-02-04T19:12:57.451847Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60970/133889 blocks (45.5%), 0 events +2026-02-04T19:12:57.651088Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60980/133889 blocks (45.5%), 0 events +2026-02-04T19:12:57.940352Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60990/133889 blocks (45.6%), 0 events +2026-02-04T19:12:57.983426Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61000/133889 blocks (45.6%), 0 events +2026-02-04T19:12:58.200403Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61010/133889 blocks (45.6%), 0 events +2026-02-04T19:12:58.467327Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61020/133889 blocks (45.6%), 0 events +2026-02-04T19:12:58.630078Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61030/133889 blocks (45.6%), 0 events +2026-02-04T19:12:58.858740Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61040/133889 blocks (45.6%), 0 events +2026-02-04T19:12:59.026328Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61050/133889 blocks (45.6%), 0 events +2026-02-04T19:12:59.199342Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61060/133889 blocks (45.6%), 0 events +2026-02-04T19:12:59.421903Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61070/133889 blocks (45.6%), 0 events +2026-02-04T19:12:59.644410Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61080/133889 blocks (45.6%), 0 events +2026-02-04T19:12:59.846198Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61090/133889 blocks (45.6%), 0 events +2026-02-04T19:13:00.081351Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61100/133889 blocks (45.6%), 0 events +2026-02-04T19:13:00.231281Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61110/133889 blocks (45.6%), 0 events +2026-02-04T19:13:00.442778Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61120/133889 blocks (45.6%), 0 events +2026-02-04T19:13:00.642292Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61130/133889 blocks (45.7%), 0 events +2026-02-04T19:13:00.788871Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61140/133889 blocks (45.7%), 0 events +2026-02-04T19:13:01.089385Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61150/133889 blocks (45.7%), 0 events +2026-02-04T19:13:01.234562Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61160/133889 blocks (45.7%), 0 events +2026-02-04T19:13:01.417140Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61170/133889 blocks (45.7%), 0 events +2026-02-04T19:13:01.658784Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61180/133889 blocks (45.7%), 0 events +2026-02-04T19:13:01.828386Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61190/133889 blocks (45.7%), 0 events +2026-02-04T19:13:02.036611Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61200/133889 blocks (45.7%), 0 events +2026-02-04T19:13:02.173832Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61210/133889 blocks (45.7%), 0 events +2026-02-04T19:13:02.459421Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61220/133889 blocks (45.7%), 0 events +2026-02-04T19:13:02.697947Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61230/133889 blocks (45.7%), 0 events +2026-02-04T19:13:02.796143Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61240/133889 blocks (45.7%), 0 events +2026-02-04T19:13:03.028455Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61250/133889 blocks (45.7%), 0 events +2026-02-04T19:13:03.221001Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61260/133889 blocks (45.8%), 0 events +2026-02-04T19:13:03.399811Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61270/133889 blocks (45.8%), 0 events +2026-02-04T19:13:03.739730Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61280/133889 blocks (45.8%), 0 events +2026-02-04T19:13:03.782824Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61290/133889 blocks (45.8%), 0 events +2026-02-04T19:13:04.031043Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61300/133889 blocks (45.8%), 0 events +2026-02-04T19:13:04.265620Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61310/133889 blocks (45.8%), 0 events +2026-02-04T19:13:04.375789Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61320/133889 blocks (45.8%), 0 events +2026-02-04T19:13:04.643239Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61330/133889 blocks (45.8%), 0 events +2026-02-04T19:13:04.837822Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61340/133889 blocks (45.8%), 0 events +2026-02-04T19:13:05.047702Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61350/133889 blocks (45.8%), 0 events +2026-02-04T19:13:05.175033Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61360/133889 blocks (45.8%), 0 events +2026-02-04T19:13:05.451195Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61370/133889 blocks (45.8%), 0 events +2026-02-04T19:13:05.591004Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61380/133889 blocks (45.8%), 0 events +2026-02-04T19:13:05.871162Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61390/133889 blocks (45.9%), 0 events +2026-02-04T19:13:06.040486Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61400/133889 blocks (45.9%), 0 events +2026-02-04T19:13:06.197263Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61410/133889 blocks (45.9%), 0 events +2026-02-04T19:13:06.415201Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61420/133889 blocks (45.9%), 0 events +2026-02-04T19:13:06.628001Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61430/133889 blocks (45.9%), 0 events +2026-02-04T19:13:06.855895Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61440/133889 blocks (45.9%), 0 events +2026-02-04T19:13:06.989760Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61450/133889 blocks (45.9%), 0 events +2026-02-04T19:13:07.255661Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61460/133889 blocks (45.9%), 0 events +2026-02-04T19:13:07.416623Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61470/133889 blocks (45.9%), 0 events +2026-02-04T19:13:07.564855Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61480/133889 blocks (45.9%), 0 events +2026-02-04T19:13:07.903751Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61490/133889 blocks (45.9%), 0 events +2026-02-04T19:13:08.029142Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61500/133889 blocks (45.9%), 0 events +2026-02-04T19:13:08.187085Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61510/133889 blocks (45.9%), 0 events +2026-02-04T19:13:08.459261Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61520/133889 blocks (45.9%), 0 events +2026-02-04T19:13:08.656920Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61530/133889 blocks (46.0%), 0 events +2026-02-04T19:13:08.770205Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61540/133889 blocks (46.0%), 0 events +2026-02-04T19:13:09.023046Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61550/133889 blocks (46.0%), 0 events +2026-02-04T19:13:09.185866Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61560/133889 blocks (46.0%), 0 events +2026-02-04T19:13:09.508977Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61570/133889 blocks (46.0%), 0 events +2026-02-04T19:13:09.608092Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61580/133889 blocks (46.0%), 0 events +2026-02-04T19:13:09.848941Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61590/133889 blocks (46.0%), 0 events +2026-02-04T19:13:10.035731Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61600/133889 blocks (46.0%), 0 events +2026-02-04T19:13:10.179858Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61610/133889 blocks (46.0%), 0 events +2026-02-04T19:13:10.525243Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61620/133889 blocks (46.0%), 0 events +2026-02-04T19:13:10.560549Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61630/133889 blocks (46.0%), 0 events +2026-02-04T19:13:10.827502Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61640/133889 blocks (46.0%), 0 events +2026-02-04T19:13:11.084298Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61650/133889 blocks (46.0%), 0 events +2026-02-04T19:13:11.179697Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61660/133889 blocks (46.1%), 0 events +2026-02-04T19:13:11.409861Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61670/133889 blocks (46.1%), 0 events +2026-02-04T19:13:11.628124Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61680/133889 blocks (46.1%), 0 events +2026-02-04T19:13:11.804444Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61690/133889 blocks (46.1%), 0 events +2026-02-04T19:13:11.957377Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61700/133889 blocks (46.1%), 0 events +2026-02-04T19:13:12.230316Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61710/133889 blocks (46.1%), 0 events +2026-02-04T19:13:12.378567Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61720/133889 blocks (46.1%), 0 events +2026-02-04T19:13:12.751666Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61730/133889 blocks (46.1%), 0 events +2026-02-04T19:13:12.787692Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61740/133889 blocks (46.1%), 0 events +2026-02-04T19:13:12.949663Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61750/133889 blocks (46.1%), 0 events +2026-02-04T19:13:13.231129Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61760/133889 blocks (46.1%), 0 events +2026-02-04T19:13:13.443704Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61770/133889 blocks (46.1%), 0 events +2026-02-04T19:13:13.671646Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61780/133889 blocks (46.1%), 0 events +2026-02-04T19:13:13.812310Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61790/133889 blocks (46.1%), 0 events +2026-02-04T19:13:14.055252Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61800/133889 blocks (46.2%), 0 events +2026-02-04T19:13:14.232193Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61810/133889 blocks (46.2%), 0 events +2026-02-04T19:13:14.409014Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61820/133889 blocks (46.2%), 0 events +2026-02-04T19:13:14.592048Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61830/133889 blocks (46.2%), 0 events +2026-02-04T19:13:14.766114Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61840/133889 blocks (46.2%), 0 events +2026-02-04T19:13:15.030235Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61850/133889 blocks (46.2%), 0 events +2026-02-04T19:13:15.296345Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61860/133889 blocks (46.2%), 0 events +2026-02-04T19:13:15.365065Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61870/133889 blocks (46.2%), 0 events +2026-02-04T19:13:15.638299Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61880/133889 blocks (46.2%), 0 events +2026-02-04T19:13:15.800214Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61890/133889 blocks (46.2%), 0 events +2026-02-04T19:13:16.031804Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61900/133889 blocks (46.2%), 0 events +2026-02-04T19:13:16.291822Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61910/133889 blocks (46.2%), 0 events +2026-02-04T19:13:16.449631Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61920/133889 blocks (46.2%), 0 events +2026-02-04T19:13:16.602853Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61930/133889 blocks (46.3%), 0 events +2026-02-04T19:13:16.846033Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61940/133889 blocks (46.3%), 0 events +2026-02-04T19:13:17.049824Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61950/133889 blocks (46.3%), 0 events +2026-02-04T19:13:17.220185Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61960/133889 blocks (46.3%), 0 events +2026-02-04T19:13:17.417056Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61970/133889 blocks (46.3%), 0 events +2026-02-04T19:13:17.590528Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61980/133889 blocks (46.3%), 0 events +2026-02-04T19:13:17.864770Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61990/133889 blocks (46.3%), 0 events +2026-02-04T19:13:18.011614Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62000/133889 blocks (46.3%), 0 events +2026-02-04T19:13:18.274165Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62010/133889 blocks (46.3%), 0 events +2026-02-04T19:13:18.425159Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62020/133889 blocks (46.3%), 0 events +2026-02-04T19:13:18.576715Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62030/133889 blocks (46.3%), 0 events +2026-02-04T19:13:18.914154Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62040/133889 blocks (46.3%), 0 events +2026-02-04T19:13:18.991710Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62050/133889 blocks (46.3%), 0 events +2026-02-04T19:13:19.214144Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62060/133889 blocks (46.4%), 0 events +2026-02-04T19:13:19.470410Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62070/133889 blocks (46.4%), 0 events +2026-02-04T19:13:19.614680Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62080/133889 blocks (46.4%), 0 events +2026-02-04T19:13:19.793974Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62090/133889 blocks (46.4%), 0 events +2026-02-04T19:13:20.046268Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62100/133889 blocks (46.4%), 0 events +2026-02-04T19:13:20.266687Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62110/133889 blocks (46.4%), 0 events +2026-02-04T19:13:20.521946Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62120/133889 blocks (46.4%), 0 events +2026-02-04T19:13:20.560139Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62130/133889 blocks (46.4%), 0 events +2026-02-04T19:13:20.803320Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62140/133889 blocks (46.4%), 0 events +2026-02-04T19:13:21.043800Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62150/133889 blocks (46.4%), 0 events +2026-02-04T19:13:21.253511Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62160/133889 blocks (46.4%), 0 events +2026-02-04T19:13:21.532598Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62170/133889 blocks (46.4%), 0 events +2026-02-04T19:13:21.568003Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62180/133889 blocks (46.4%), 0 events +2026-02-04T19:13:21.825596Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62190/133889 blocks (46.4%), 0 events +2026-02-04T19:13:22.089763Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62200/133889 blocks (46.5%), 0 events +2026-02-04T19:13:22.166356Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62210/133889 blocks (46.5%), 0 events +2026-02-04T19:13:22.455861Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62220/133889 blocks (46.5%), 0 events +2026-02-04T19:13:22.620407Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62230/133889 blocks (46.5%), 0 events +2026-02-04T19:13:22.775431Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62240/133889 blocks (46.5%), 0 events +2026-02-04T19:13:22.979914Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62250/133889 blocks (46.5%), 0 events +2026-02-04T19:13:23.244733Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62260/133889 blocks (46.5%), 0 events +2026-02-04T19:13:23.376739Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62270/133889 blocks (46.5%), 0 events +2026-02-04T19:13:23.666487Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62280/133889 blocks (46.5%), 0 events +2026-02-04T19:13:23.844215Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62290/133889 blocks (46.5%), 0 events +2026-02-04T19:13:24.044554Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62300/133889 blocks (46.5%), 0 events +2026-02-04T19:13:24.207058Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62310/133889 blocks (46.5%), 0 events +2026-02-04T19:13:24.424517Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62320/133889 blocks (46.5%), 0 events +2026-02-04T19:13:24.680486Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62330/133889 blocks (46.6%), 0 events +2026-02-04T19:13:24.833132Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62340/133889 blocks (46.6%), 0 events +2026-02-04T19:13:25.024688Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62350/133889 blocks (46.6%), 0 events +2026-02-04T19:13:25.239662Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62360/133889 blocks (46.6%), 0 events +2026-02-04T19:13:25.427943Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62370/133889 blocks (46.6%), 0 events +2026-02-04T19:13:25.608342Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62380/133889 blocks (46.6%), 0 events +2026-02-04T19:13:25.793771Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62390/133889 blocks (46.6%), 0 events +2026-02-04T19:13:26.002379Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62400/133889 blocks (46.6%), 0 events +2026-02-04T19:13:26.251418Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62410/133889 blocks (46.6%), 0 events +2026-02-04T19:13:26.401140Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62420/133889 blocks (46.6%), 0 events +2026-02-04T19:13:26.585030Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62430/133889 blocks (46.6%), 0 events +2026-02-04T19:13:26.839225Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62440/133889 blocks (46.6%), 0 events +2026-02-04T19:13:27.016888Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62450/133889 blocks (46.6%), 0 events +2026-02-04T19:13:27.185074Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62460/133889 blocks (46.7%), 0 events +2026-02-04T19:13:27.442338Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62470/133889 blocks (46.7%), 0 events +2026-02-04T19:13:27.605833Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62480/133889 blocks (46.7%), 0 events +2026-02-04T19:13:27.856356Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62490/133889 blocks (46.7%), 0 events +2026-02-04T19:13:27.971384Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62500/133889 blocks (46.7%), 0 events +2026-02-04T19:13:28.200765Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62510/133889 blocks (46.7%), 0 events +2026-02-04T19:13:28.444977Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62520/133889 blocks (46.7%), 0 events +2026-02-04T19:13:28.658972Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62530/133889 blocks (46.7%), 0 events +2026-02-04T19:13:28.908291Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62540/133889 blocks (46.7%), 0 events +2026-02-04T19:13:28.979303Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62550/133889 blocks (46.7%), 0 events +2026-02-04T19:13:29.237079Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62560/133889 blocks (46.7%), 0 events +2026-02-04T19:13:29.430949Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62570/133889 blocks (46.7%), 0 events +2026-02-04T19:13:29.800263Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62580/133889 blocks (46.7%), 0 events +2026-02-04T19:13:29.921984Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62590/133889 blocks (46.7%), 0 events +2026-02-04T19:13:29.965873Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62600/133889 blocks (46.8%), 0 events +2026-02-04T19:13:30.227103Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62610/133889 blocks (46.8%), 0 events +2026-02-04T19:13:30.481641Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62620/133889 blocks (46.8%), 0 events +2026-02-04T19:13:30.648607Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62630/133889 blocks (46.8%), 0 events +2026-02-04T19:13:30.777777Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62640/133889 blocks (46.8%), 0 events +2026-02-04T19:13:31.007862Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62650/133889 blocks (46.8%), 0 events +2026-02-04T19:13:31.246257Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62660/133889 blocks (46.8%), 0 events +2026-02-04T19:13:31.537248Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62670/133889 blocks (46.8%), 0 events +2026-02-04T19:13:31.582538Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62680/133889 blocks (46.8%), 0 events +2026-02-04T19:13:31.771018Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62690/133889 blocks (46.8%), 0 events +2026-02-04T19:13:32.056092Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62700/133889 blocks (46.8%), 0 events +2026-02-04T19:13:32.201948Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62710/133889 blocks (46.8%), 0 events +2026-02-04T19:13:32.542648Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62720/133889 blocks (46.8%), 0 events +2026-02-04T19:13:32.578767Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62730/133889 blocks (46.9%), 0 events +2026-02-04T19:13:32.777355Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62740/133889 blocks (46.9%), 0 events +2026-02-04T19:13:33.102851Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62750/133889 blocks (46.9%), 0 events +2026-02-04T19:13:33.219629Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62760/133889 blocks (46.9%), 0 events +2026-02-04T19:13:33.398477Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62770/133889 blocks (46.9%), 0 events +2026-02-04T19:13:33.624521Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62780/133889 blocks (46.9%), 0 events +2026-02-04T19:13:33.762127Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62790/133889 blocks (46.9%), 0 events +2026-02-04T19:13:34.000217Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62800/133889 blocks (46.9%), 0 events +2026-02-04T19:13:34.229841Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62810/133889 blocks (46.9%), 0 events +2026-02-04T19:13:34.451525Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62820/133889 blocks (46.9%), 0 events +2026-02-04T19:13:34.671753Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62830/133889 blocks (46.9%), 0 events +2026-02-04T19:13:34.832783Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62840/133889 blocks (46.9%), 0 events +2026-02-04T19:13:35.001572Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62850/133889 blocks (46.9%), 0 events +2026-02-04T19:13:35.232824Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62860/133889 blocks (46.9%), 0 events +2026-02-04T19:13:35.449892Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62870/133889 blocks (47.0%), 0 events +2026-02-04T19:13:35.584659Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62880/133889 blocks (47.0%), 0 events +2026-02-04T19:13:35.843320Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62890/133889 blocks (47.0%), 0 events +2026-02-04T19:13:36.056713Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62900/133889 blocks (47.0%), 0 events +2026-02-04T19:13:36.246189Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62910/133889 blocks (47.0%), 0 events +2026-02-04T19:13:36.387933Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62920/133889 blocks (47.0%), 0 events +2026-02-04T19:13:36.584554Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62930/133889 blocks (47.0%), 0 events +2026-02-04T19:13:36.780059Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62940/133889 blocks (47.0%), 0 events +2026-02-04T19:13:36.993020Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62950/133889 blocks (47.0%), 0 events +2026-02-04T19:13:37.296951Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62960/133889 blocks (47.0%), 0 events +2026-02-04T19:13:37.453533Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62970/133889 blocks (47.0%), 0 events +2026-02-04T19:13:37.617683Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62980/133889 blocks (47.0%), 0 events +2026-02-04T19:13:37.822124Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62990/133889 blocks (47.0%), 0 events +2026-02-04T19:13:37.970653Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63000/133889 blocks (47.1%), 0 events +2026-02-04T19:13:38.190873Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63010/133889 blocks (47.1%), 0 events +2026-02-04T19:13:38.432131Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63020/133889 blocks (47.1%), 0 events +2026-02-04T19:13:38.642757Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63030/133889 blocks (47.1%), 0 events +2026-02-04T19:13:38.870615Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63040/133889 blocks (47.1%), 0 events +2026-02-04T19:13:39.000866Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63050/133889 blocks (47.1%), 0 events +2026-02-04T19:13:39.360551Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63060/133889 blocks (47.1%), 0 events +2026-02-04T19:13:39.401440Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63070/133889 blocks (47.1%), 0 events +2026-02-04T19:13:39.617893Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63080/133889 blocks (47.1%), 0 events +2026-02-04T19:13:39.780293Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63090/133889 blocks (47.1%), 0 events +2026-02-04T19:13:39.994918Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63100/133889 blocks (47.1%), 0 events +2026-02-04T19:13:40.226779Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63110/133889 blocks (47.1%), 0 events +2026-02-04T19:13:40.441305Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63120/133889 blocks (47.1%), 0 events +2026-02-04T19:13:40.640233Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63130/133889 blocks (47.2%), 0 events +2026-02-04T19:13:41.125062Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63140/133889 blocks (47.2%), 0 events +2026-02-04T19:13:41.164239Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63150/133889 blocks (47.2%), 0 events +2026-02-04T19:13:41.206644Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63160/133889 blocks (47.2%), 0 events +2026-02-04T19:13:41.492319Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63170/133889 blocks (47.2%), 0 events +2026-02-04T19:13:41.637241Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63180/133889 blocks (47.2%), 0 events +2026-02-04T19:13:41.781514Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63190/133889 blocks (47.2%), 0 events +2026-02-04T19:13:42.062298Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63200/133889 blocks (47.2%), 0 events +2026-02-04T19:13:42.174927Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63210/133889 blocks (47.2%), 0 events +2026-02-04T19:13:42.504456Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63220/133889 blocks (47.2%), 0 events +2026-02-04T19:13:42.567466Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63230/133889 blocks (47.2%), 0 events +2026-02-04T19:13:42.842113Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63240/133889 blocks (47.2%), 0 events +2026-02-04T19:13:43.026933Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63250/133889 blocks (47.2%), 0 events +2026-02-04T19:13:43.216455Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63260/133889 blocks (47.2%), 0 events +2026-02-04T19:13:43.440305Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63270/133889 blocks (47.3%), 0 events +2026-02-04T19:13:43.619145Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63280/133889 blocks (47.3%), 0 events +2026-02-04T19:13:43.820305Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63290/133889 blocks (47.3%), 0 events +2026-02-04T19:13:44.076387Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63300/133889 blocks (47.3%), 0 events +2026-02-04T19:13:44.223967Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63310/133889 blocks (47.3%), 0 events +2026-02-04T19:13:44.424417Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63320/133889 blocks (47.3%), 0 events +2026-02-04T19:13:44.634283Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63330/133889 blocks (47.3%), 0 events +2026-02-04T19:13:44.839330Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63340/133889 blocks (47.3%), 0 events +2026-02-04T19:13:45.025525Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63350/133889 blocks (47.3%), 0 events +2026-02-04T19:13:45.245819Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63360/133889 blocks (47.3%), 0 events +2026-02-04T19:13:45.454502Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63370/133889 blocks (47.3%), 0 events +2026-02-04T19:13:45.685815Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63380/133889 blocks (47.3%), 0 events +2026-02-04T19:13:45.797311Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63390/133889 blocks (47.3%), 0 events +2026-02-04T19:13:45.989137Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63400/133889 blocks (47.4%), 0 events +2026-02-04T19:13:46.240814Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63410/133889 blocks (47.4%), 0 events +2026-02-04T19:13:46.457225Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63420/133889 blocks (47.4%), 0 events +2026-02-04T19:13:46.580751Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63430/133889 blocks (47.4%), 0 events +2026-02-04T19:13:46.795595Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63440/133889 blocks (47.4%), 0 events +2026-02-04T19:13:47.010433Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63450/133889 blocks (47.4%), 0 events +2026-02-04T19:13:47.260263Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63460/133889 blocks (47.4%), 0 events +2026-02-04T19:13:47.452593Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63470/133889 blocks (47.4%), 0 events +2026-02-04T19:13:47.652417Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63480/133889 blocks (47.4%), 0 events +2026-02-04T19:13:47.836465Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63490/133889 blocks (47.4%), 0 events +2026-02-04T19:13:48.042341Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63500/133889 blocks (47.4%), 0 events +2026-02-04T19:13:48.270119Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63510/133889 blocks (47.4%), 0 events +2026-02-04T19:13:48.434033Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63520/133889 blocks (47.4%), 0 events +2026-02-04T19:13:48.579425Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63530/133889 blocks (47.4%), 0 events +2026-02-04T19:13:48.826592Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63540/133889 blocks (47.5%), 0 events +2026-02-04T19:13:48.984395Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63550/133889 blocks (47.5%), 0 events +2026-02-04T19:13:49.179270Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63560/133889 blocks (47.5%), 0 events +2026-02-04T19:13:49.442507Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63570/133889 blocks (47.5%), 0 events +2026-02-04T19:13:49.623335Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63580/133889 blocks (47.5%), 0 events +2026-02-04T19:13:49.872951Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63590/133889 blocks (47.5%), 0 events +2026-02-04T19:13:50.008925Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63600/133889 blocks (47.5%), 0 events +2026-02-04T19:13:50.216104Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63610/133889 blocks (47.5%), 0 events +2026-02-04T19:13:50.404571Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63620/133889 blocks (47.5%), 0 events +2026-02-04T19:13:50.577064Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63630/133889 blocks (47.5%), 0 events +2026-02-04T19:13:50.893685Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63640/133889 blocks (47.5%), 0 events +2026-02-04T19:13:50.963502Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63650/133889 blocks (47.5%), 0 events +2026-02-04T19:13:51.203612Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63660/133889 blocks (47.5%), 0 events +2026-02-04T19:13:51.450335Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63670/133889 blocks (47.6%), 0 events +2026-02-04T19:13:51.646506Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63680/133889 blocks (47.6%), 0 events +2026-02-04T19:13:51.941583Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63690/133889 blocks (47.6%), 0 events +2026-02-04T19:13:51.979935Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63700/133889 blocks (47.6%), 0 events +2026-02-04T19:13:52.176369Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63710/133889 blocks (47.6%), 0 events +2026-02-04T19:13:52.496318Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63720/133889 blocks (47.6%), 0 events +2026-02-04T19:13:52.692582Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63730/133889 blocks (47.6%), 0 events +2026-02-04T19:13:52.818603Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63740/133889 blocks (47.6%), 0 events +2026-02-04T19:13:53.022008Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63750/133889 blocks (47.6%), 0 events +2026-02-04T19:13:53.249138Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63760/133889 blocks (47.6%), 0 events +2026-02-04T19:13:53.544954Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63770/133889 blocks (47.6%), 0 events +2026-02-04T19:13:53.582955Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63780/133889 blocks (47.6%), 0 events +2026-02-04T19:13:53.811434Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63790/133889 blocks (47.6%), 0 events +2026-02-04T19:13:54.078070Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63800/133889 blocks (47.7%), 0 events +2026-02-04T19:13:54.269689Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63810/133889 blocks (47.7%), 0 events +2026-02-04T19:13:54.384652Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63820/133889 blocks (47.7%), 0 events +2026-02-04T19:13:54.592191Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63830/133889 blocks (47.7%), 0 events +2026-02-04T19:13:54.820199Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63840/133889 blocks (47.7%), 0 events +2026-02-04T19:13:54.975216Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63850/133889 blocks (47.7%), 0 events +2026-02-04T19:13:55.285016Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63860/133889 blocks (47.7%), 0 events +2026-02-04T19:13:55.396911Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63870/133889 blocks (47.7%), 0 events +2026-02-04T19:13:55.643395Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63880/133889 blocks (47.7%), 0 events +2026-02-04T19:13:55.842601Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63890/133889 blocks (47.7%), 0 events +2026-02-04T19:13:56.134746Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63900/133889 blocks (47.7%), 0 events +2026-02-04T19:13:56.175718Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63910/133889 blocks (47.7%), 0 events +2026-02-04T19:13:56.456221Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63920/133889 blocks (47.7%), 0 events +2026-02-04T19:13:56.572260Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63930/133889 blocks (47.7%), 0 events +2026-02-04T19:13:56.887371Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63940/133889 blocks (47.8%), 0 events +2026-02-04T19:13:57.181894Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63950/133889 blocks (47.8%), 0 events +2026-02-04T19:13:57.224295Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63960/133889 blocks (47.8%), 0 events +2026-02-04T19:13:57.416518Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63970/133889 blocks (47.8%), 0 events +2026-02-04T19:13:57.620503Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63980/133889 blocks (47.8%), 0 events +2026-02-04T19:13:57.790098Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63990/133889 blocks (47.8%), 0 events +2026-02-04T19:13:58.011957Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64000/133889 blocks (47.8%), 0 events +2026-02-04T19:13:58.265401Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64010/133889 blocks (47.8%), 0 events +2026-02-04T19:13:58.430023Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64020/133889 blocks (47.8%), 0 events +2026-02-04T19:13:58.757014Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64030/133889 blocks (47.8%), 0 events +2026-02-04T19:13:58.800964Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64040/133889 blocks (47.8%), 0 events +2026-02-04T19:13:58.986812Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64050/133889 blocks (47.8%), 0 events +2026-02-04T19:13:59.180628Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64060/133889 blocks (47.8%), 0 events +2026-02-04T19:13:59.478637Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64070/133889 blocks (47.9%), 0 events +2026-02-04T19:13:59.579918Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64080/133889 blocks (47.9%), 0 events +2026-02-04T19:13:59.842223Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64090/133889 blocks (47.9%), 0 events +2026-02-04T19:14:00.058933Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64100/133889 blocks (47.9%), 0 events +2026-02-04T19:14:00.187663Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64110/133889 blocks (47.9%), 0 events +2026-02-04T19:14:00.391528Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64120/133889 blocks (47.9%), 0 events +2026-02-04T19:14:00.666123Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64130/133889 blocks (47.9%), 0 events +2026-02-04T19:14:00.887686Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64140/133889 blocks (47.9%), 0 events +2026-02-04T19:14:01.019030Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64150/133889 blocks (47.9%), 0 events +2026-02-04T19:14:01.218976Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64160/133889 blocks (47.9%), 0 events +2026-02-04T19:14:01.444601Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64170/133889 blocks (47.9%), 0 events +2026-02-04T19:14:01.575135Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64180/133889 blocks (47.9%), 0 events +2026-02-04T19:14:01.903814Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64190/133889 blocks (47.9%), 0 events +2026-02-04T19:14:02.060400Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64200/133889 blocks (47.9%), 0 events +2026-02-04T19:14:02.219357Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64210/133889 blocks (48.0%), 0 events +2026-02-04T19:14:02.459303Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64220/133889 blocks (48.0%), 0 events +2026-02-04T19:14:02.636293Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64230/133889 blocks (48.0%), 0 events +2026-02-04T19:14:02.778818Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64240/133889 blocks (48.0%), 0 events +2026-02-04T19:14:02.985475Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64250/133889 blocks (48.0%), 0 events +2026-02-04T19:14:03.260858Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64260/133889 blocks (48.0%), 0 events +2026-02-04T19:14:03.475362Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64270/133889 blocks (48.0%), 0 events +2026-02-04T19:14:03.673312Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64280/133889 blocks (48.0%), 0 events +2026-02-04T19:14:03.776192Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64290/133889 blocks (48.0%), 0 events +2026-02-04T19:14:04.031466Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64300/133889 blocks (48.0%), 0 events +2026-02-04T19:14:04.173519Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64310/133889 blocks (48.0%), 0 events +2026-02-04T19:14:04.397732Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64320/133889 blocks (48.0%), 0 events +2026-02-04T19:14:04.624337Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64330/133889 blocks (48.0%), 0 events +2026-02-04T19:14:04.841707Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64340/133889 blocks (48.1%), 0 events +2026-02-04T19:14:05.084338Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64350/133889 blocks (48.1%), 0 events +2026-02-04T19:14:05.184276Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64360/133889 blocks (48.1%), 0 events +2026-02-04T19:14:05.431382Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64370/133889 blocks (48.1%), 0 events +2026-02-04T19:14:05.613388Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64380/133889 blocks (48.1%), 0 events +2026-02-04T19:14:05.809134Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64390/133889 blocks (48.1%), 0 events +2026-02-04T19:14:05.965987Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64400/133889 blocks (48.1%), 0 events +2026-02-04T19:14:06.197803Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64410/133889 blocks (48.1%), 0 events +2026-02-04T19:14:06.458480Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64420/133889 blocks (48.1%), 0 events +2026-02-04T19:14:06.650461Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64430/133889 blocks (48.1%), 0 events +2026-02-04T19:14:06.859817Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64440/133889 blocks (48.1%), 0 events +2026-02-04T19:14:07.146317Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64450/133889 blocks (48.1%), 0 events +2026-02-04T19:14:07.185741Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64460/133889 blocks (48.1%), 0 events +2026-02-04T19:14:07.423816Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64470/133889 blocks (48.2%), 0 events +2026-02-04T19:14:07.668985Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64480/133889 blocks (48.2%), 0 events +2026-02-04T19:14:07.877524Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64490/133889 blocks (48.2%), 0 events +2026-02-04T19:14:08.047382Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64500/133889 blocks (48.2%), 0 events +2026-02-04T19:14:08.224126Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64510/133889 blocks (48.2%), 0 events +2026-02-04T19:14:08.394480Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64520/133889 blocks (48.2%), 0 events +2026-02-04T19:14:08.718335Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64530/133889 blocks (48.2%), 0 events +2026-02-04T19:14:08.755216Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64540/133889 blocks (48.2%), 0 events +2026-02-04T19:14:09.061842Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64550/133889 blocks (48.2%), 0 events +2026-02-04T19:14:09.242876Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64560/133889 blocks (48.2%), 0 events +2026-02-04T19:14:09.395067Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64570/133889 blocks (48.2%), 0 events +2026-02-04T19:14:09.608697Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64580/133889 blocks (48.2%), 0 events +2026-02-04T19:14:09.836265Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64590/133889 blocks (48.2%), 0 events +2026-02-04T19:14:10.043822Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64600/133889 blocks (48.2%), 0 events +2026-02-04T19:14:10.328592Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64610/133889 blocks (48.3%), 0 events +2026-02-04T19:14:10.365623Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64620/133889 blocks (48.3%), 0 events +2026-02-04T19:14:10.587156Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64630/133889 blocks (48.3%), 0 events +2026-02-04T19:14:10.862533Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64640/133889 blocks (48.3%), 0 events +2026-02-04T19:14:11.028178Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64650/133889 blocks (48.3%), 0 events +2026-02-04T19:14:11.339129Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64660/133889 blocks (48.3%), 0 events +2026-02-04T19:14:11.402759Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64670/133889 blocks (48.3%), 0 events +2026-02-04T19:14:11.627840Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64680/133889 blocks (48.3%), 0 events +2026-02-04T19:14:11.895971Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64690/133889 blocks (48.3%), 0 events +2026-02-04T19:14:12.037807Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64700/133889 blocks (48.3%), 0 events +2026-02-04T19:14:12.207216Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64710/133889 blocks (48.3%), 0 events +2026-02-04T19:14:12.423204Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64720/133889 blocks (48.3%), 0 events +2026-02-04T19:14:12.564976Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64730/133889 blocks (48.3%), 0 events +2026-02-04T19:14:12.791296Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64740/133889 blocks (48.4%), 0 events +2026-02-04T19:14:12.976828Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64750/133889 blocks (48.4%), 0 events +2026-02-04T19:14:13.198365Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64760/133889 blocks (48.4%), 0 events +2026-02-04T19:14:13.470284Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64770/133889 blocks (48.4%), 0 events +2026-02-04T19:14:13.634896Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64780/133889 blocks (48.4%), 0 events +2026-02-04T19:14:13.791022Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64790/133889 blocks (48.4%), 0 events +2026-02-04T19:14:13.995781Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64800/133889 blocks (48.4%), 0 events +2026-02-04T19:14:14.248621Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64810/133889 blocks (48.4%), 0 events +2026-02-04T19:14:14.763549Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64820/133889 blocks (48.4%), 0 events +2026-02-04T19:14:14.806235Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64830/133889 blocks (48.4%), 0 events +2026-02-04T19:14:14.846299Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64840/133889 blocks (48.4%), 0 events +2026-02-04T19:14:15.040251Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64850/133889 blocks (48.4%), 0 events +2026-02-04T19:14:15.166840Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64860/133889 blocks (48.4%), 0 events +2026-02-04T19:14:15.532094Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64870/133889 blocks (48.5%), 0 events +2026-02-04T19:14:15.569929Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64880/133889 blocks (48.5%), 0 events +2026-02-04T19:14:15.811779Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64890/133889 blocks (48.5%), 0 events +2026-02-04T19:14:16.058124Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64900/133889 blocks (48.5%), 0 events +2026-02-04T19:14:16.225729Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64910/133889 blocks (48.5%), 0 events +2026-02-04T19:14:16.421966Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64920/133889 blocks (48.5%), 0 events +2026-02-04T19:14:16.652746Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64930/133889 blocks (48.5%), 0 events +2026-02-04T19:14:16.835863Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64940/133889 blocks (48.5%), 0 events +2026-02-04T19:14:17.107462Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64950/133889 blocks (48.5%), 0 events +2026-02-04T19:14:17.231398Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64960/133889 blocks (48.5%), 0 events +2026-02-04T19:14:17.450431Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64970/133889 blocks (48.5%), 0 events +2026-02-04T19:14:17.676421Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64980/133889 blocks (48.5%), 0 events +2026-02-04T19:14:17.882406Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64990/133889 blocks (48.5%), 0 events +2026-02-04T19:14:17.986202Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65000/133889 blocks (48.5%), 0 events +2026-02-04T19:14:18.205305Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65010/133889 blocks (48.6%), 0 events +2026-02-04T19:14:18.426890Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65020/133889 blocks (48.6%), 0 events +2026-02-04T19:14:18.583341Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65030/133889 blocks (48.6%), 0 events +2026-02-04T19:14:18.847698Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65040/133889 blocks (48.6%), 0 events +2026-02-04T19:14:19.009631Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65050/133889 blocks (48.6%), 0 events +2026-02-04T19:14:19.245785Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65060/133889 blocks (48.6%), 0 events +2026-02-04T19:14:19.418675Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65070/133889 blocks (48.6%), 0 events +2026-02-04T19:14:19.595089Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65080/133889 blocks (48.6%), 0 events +2026-02-04T19:14:19.846143Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65090/133889 blocks (48.6%), 0 events +2026-02-04T19:14:20.055995Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65100/133889 blocks (48.6%), 0 events +2026-02-04T19:14:20.253888Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65110/133889 blocks (48.6%), 0 events +2026-02-04T19:14:20.442177Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65120/133889 blocks (48.6%), 0 events +2026-02-04T19:14:20.652792Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65130/133889 blocks (48.6%), 0 events +2026-02-04T19:14:20.854754Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65140/133889 blocks (48.7%), 0 events +2026-02-04T19:14:21.003900Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65150/133889 blocks (48.7%), 0 events +2026-02-04T19:14:21.330626Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65160/133889 blocks (48.7%), 0 events +2026-02-04T19:14:21.373599Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65170/133889 blocks (48.7%), 0 events +2026-02-04T19:14:21.635226Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65180/133889 blocks (48.7%), 0 events +2026-02-04T19:14:21.863016Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65190/133889 blocks (48.7%), 0 events +2026-02-04T19:14:22.061259Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65200/133889 blocks (48.7%), 0 events +2026-02-04T19:14:22.255489Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65210/133889 blocks (48.7%), 0 events +2026-02-04T19:14:22.422786Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65220/133889 blocks (48.7%), 0 events +2026-02-04T19:14:22.645344Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65230/133889 blocks (48.7%), 0 events +2026-02-04T19:14:22.909192Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65240/133889 blocks (48.7%), 0 events +2026-02-04T19:14:22.961869Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65250/133889 blocks (48.7%), 0 events +2026-02-04T19:14:23.173138Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65260/133889 blocks (48.7%), 0 events +2026-02-04T19:14:23.448431Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65270/133889 blocks (48.7%), 0 events +2026-02-04T19:14:23.602426Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65280/133889 blocks (48.8%), 0 events +2026-02-04T19:14:23.765606Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65290/133889 blocks (48.8%), 0 events +2026-02-04T19:14:24.024408Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65300/133889 blocks (48.8%), 0 events +2026-02-04T19:14:24.245863Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65310/133889 blocks (48.8%), 0 events +2026-02-04T19:14:24.445855Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65320/133889 blocks (48.8%), 0 events +2026-02-04T19:14:24.591733Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65330/133889 blocks (48.8%), 0 events +2026-02-04T19:14:24.856078Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65340/133889 blocks (48.8%), 0 events +2026-02-04T19:14:25.040339Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65350/133889 blocks (48.8%), 0 events +2026-02-04T19:14:25.169134Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65360/133889 blocks (48.8%), 0 events +2026-02-04T19:14:25.535120Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65370/133889 blocks (48.8%), 0 events +2026-02-04T19:14:25.581403Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65380/133889 blocks (48.8%), 0 events +2026-02-04T19:14:25.798519Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65390/133889 blocks (48.8%), 0 events +2026-02-04T19:14:26.283819Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65400/133889 blocks (48.8%), 0 events +2026-02-04T19:14:26.324524Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65410/133889 blocks (48.9%), 0 events +2026-02-04T19:14:26.364761Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65420/133889 blocks (48.9%), 0 events +2026-02-04T19:14:26.648562Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65430/133889 blocks (48.9%), 0 events +2026-02-04T19:14:26.844475Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65440/133889 blocks (48.9%), 0 events +2026-02-04T19:14:27.067612Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65450/133889 blocks (48.9%), 0 events +2026-02-04T19:14:27.246693Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65460/133889 blocks (48.9%), 0 events +2026-02-04T19:14:27.384516Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65470/133889 blocks (48.9%), 0 events +2026-02-04T19:14:27.641955Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65480/133889 blocks (48.9%), 0 events +2026-02-04T19:14:27.839175Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65490/133889 blocks (48.9%), 0 events +2026-02-04T19:14:28.004915Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65500/133889 blocks (48.9%), 0 events +2026-02-04T19:14:28.245787Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65510/133889 blocks (48.9%), 0 events +2026-02-04T19:14:28.385936Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65520/133889 blocks (48.9%), 0 events +2026-02-04T19:14:28.640699Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65530/133889 blocks (48.9%), 0 events +2026-02-04T19:14:28.857058Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65540/133889 blocks (49.0%), 0 events +2026-02-04T19:14:29.039394Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65550/133889 blocks (49.0%), 0 events +2026-02-04T19:14:29.195327Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65560/133889 blocks (49.0%), 0 events +2026-02-04T19:14:29.416411Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65570/133889 blocks (49.0%), 0 events +2026-02-04T19:14:29.586956Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65580/133889 blocks (49.0%), 0 events +2026-02-04T19:14:29.805354Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65590/133889 blocks (49.0%), 0 events +2026-02-04T19:14:30.010618Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65600/133889 blocks (49.0%), 0 events +2026-02-04T19:14:30.244925Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65610/133889 blocks (49.0%), 0 events +2026-02-04T19:14:30.443138Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65620/133889 blocks (49.0%), 0 events +2026-02-04T19:14:30.634166Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65630/133889 blocks (49.0%), 0 events +2026-02-04T19:14:30.772573Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65640/133889 blocks (49.0%), 0 events +2026-02-04T19:14:31.012079Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65650/133889 blocks (49.0%), 0 events +2026-02-04T19:14:31.297054Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65660/133889 blocks (49.0%), 0 events +2026-02-04T19:14:31.381237Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65670/133889 blocks (49.0%), 0 events +2026-02-04T19:14:31.677399Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65680/133889 blocks (49.1%), 0 events +2026-02-04T19:14:31.825029Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65690/133889 blocks (49.1%), 0 events +2026-02-04T19:14:31.977791Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65700/133889 blocks (49.1%), 0 events +2026-02-04T19:14:32.198477Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65710/133889 blocks (49.1%), 0 events +2026-02-04T19:14:32.376960Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65720/133889 blocks (49.1%), 0 events +2026-02-04T19:14:32.649817Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65730/133889 blocks (49.1%), 0 events +2026-02-04T19:14:32.867373Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65740/133889 blocks (49.1%), 0 events +2026-02-04T19:14:33.058471Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65750/133889 blocks (49.1%), 0 events +2026-02-04T19:14:33.242141Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65760/133889 blocks (49.1%), 0 events +2026-02-04T19:14:33.405148Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65770/133889 blocks (49.1%), 0 events +2026-02-04T19:14:33.651186Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65780/133889 blocks (49.1%), 0 events +2026-02-04T19:14:33.921370Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65790/133889 blocks (49.1%), 0 events +2026-02-04T19:14:33.985272Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65800/133889 blocks (49.1%), 0 events +2026-02-04T19:14:34.200302Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65810/133889 blocks (49.2%), 0 events +2026-02-04T19:14:34.461714Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65820/133889 blocks (49.2%), 0 events +2026-02-04T19:14:34.594020Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65830/133889 blocks (49.2%), 0 events +2026-02-04T19:14:34.777962Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65840/133889 blocks (49.2%), 0 events +2026-02-04T19:14:35.036756Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65850/133889 blocks (49.2%), 0 events +2026-02-04T19:14:35.182515Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65860/133889 blocks (49.2%), 0 events +2026-02-04T19:14:35.456217Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65870/133889 blocks (49.2%), 0 events +2026-02-04T19:14:35.565773Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65880/133889 blocks (49.2%), 0 events +2026-02-04T19:14:35.782829Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65890/133889 blocks (49.2%), 0 events +2026-02-04T19:14:36.047832Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65900/133889 blocks (49.2%), 0 events +2026-02-04T19:14:36.208121Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65910/133889 blocks (49.2%), 0 events +2026-02-04T19:14:36.539789Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65920/133889 blocks (49.2%), 0 events +2026-02-04T19:14:36.580793Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65930/133889 blocks (49.2%), 0 events +2026-02-04T19:14:36.853314Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65940/133889 blocks (49.2%), 0 events +2026-02-04T19:14:37.060440Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65950/133889 blocks (49.3%), 0 events +2026-02-04T19:14:37.205544Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65960/133889 blocks (49.3%), 0 events +2026-02-04T19:14:37.408555Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65970/133889 blocks (49.3%), 0 events +2026-02-04T19:14:37.594981Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65980/133889 blocks (49.3%), 0 events +2026-02-04T19:14:37.846171Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65990/133889 blocks (49.3%), 0 events +2026-02-04T19:14:38.074879Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66000/133889 blocks (49.3%), 0 events +2026-02-04T19:14:38.165554Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66010/133889 blocks (49.3%), 0 events +2026-02-04T19:14:38.382551Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66020/133889 blocks (49.3%), 0 events +2026-02-04T19:14:38.637212Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66030/133889 blocks (49.3%), 0 events +2026-02-04T19:14:38.768709Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66040/133889 blocks (49.3%), 0 events +2026-02-04T19:14:39.002128Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66050/133889 blocks (49.3%), 0 events +2026-02-04T19:14:39.194016Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66060/133889 blocks (49.3%), 0 events +2026-02-04T19:14:39.490246Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66070/133889 blocks (49.3%), 0 events +2026-02-04T19:14:39.687426Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66080/133889 blocks (49.4%), 0 events +2026-02-04T19:14:39.825827Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66090/133889 blocks (49.4%), 0 events +2026-02-04T19:14:40.002155Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66100/133889 blocks (49.4%), 0 events +2026-02-04T19:14:40.276796Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66110/133889 blocks (49.4%), 0 events +2026-02-04T19:14:40.396839Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66120/133889 blocks (49.4%), 0 events +2026-02-04T19:14:40.584209Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66130/133889 blocks (49.4%), 0 events +2026-02-04T19:14:40.773631Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66140/133889 blocks (49.4%), 0 events +2026-02-04T19:14:41.030359Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66150/133889 blocks (49.4%), 0 events +2026-02-04T19:14:41.307769Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66160/133889 blocks (49.4%), 0 events +2026-02-04T19:14:41.378024Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66170/133889 blocks (49.4%), 0 events +2026-02-04T19:14:41.623263Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66180/133889 blocks (49.4%), 0 events +2026-02-04T19:14:41.802696Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66190/133889 blocks (49.4%), 0 events +2026-02-04T19:14:42.033431Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66200/133889 blocks (49.4%), 0 events +2026-02-04T19:14:42.302948Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66210/133889 blocks (49.5%), 0 events +2026-02-04T19:14:42.412396Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66220/133889 blocks (49.5%), 0 events +2026-02-04T19:14:42.614811Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66230/133889 blocks (49.5%), 0 events +2026-02-04T19:14:42.831295Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66240/133889 blocks (49.5%), 0 events +2026-02-04T19:14:43.052617Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66250/133889 blocks (49.5%), 0 events +2026-02-04T19:14:43.320831Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66260/133889 blocks (49.5%), 0 events +2026-02-04T19:14:43.363021Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66270/133889 blocks (49.5%), 0 events +2026-02-04T19:14:43.639066Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66280/133889 blocks (49.5%), 0 events +2026-02-04T19:14:43.887941Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66290/133889 blocks (49.5%), 0 events +2026-02-04T19:14:44.040102Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66300/133889 blocks (49.5%), 0 events +2026-02-04T19:14:44.254047Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66310/133889 blocks (49.5%), 0 events +2026-02-04T19:14:44.416806Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66320/133889 blocks (49.5%), 0 events +2026-02-04T19:14:44.593649Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66330/133889 blocks (49.5%), 0 events +2026-02-04T19:14:44.895222Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66340/133889 blocks (49.5%), 0 events +2026-02-04T19:14:44.984326Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66350/133889 blocks (49.6%), 0 events +2026-02-04T19:14:45.205799Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66360/133889 blocks (49.6%), 0 events +2026-02-04T19:14:45.447551Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66370/133889 blocks (49.6%), 0 events +2026-02-04T19:14:45.649877Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66380/133889 blocks (49.6%), 0 events +2026-02-04T19:14:45.851092Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66390/133889 blocks (49.6%), 0 events +2026-02-04T19:14:45.981955Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66400/133889 blocks (49.6%), 0 events +2026-02-04T19:14:46.207492Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66410/133889 blocks (49.6%), 0 events +2026-02-04T19:14:46.467704Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66420/133889 blocks (49.6%), 0 events +2026-02-04T19:14:46.662417Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66430/133889 blocks (49.6%), 0 events +2026-02-04T19:14:46.848813Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66440/133889 blocks (49.6%), 0 events +2026-02-04T19:14:47.018271Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66450/133889 blocks (49.6%), 0 events +2026-02-04T19:14:47.237615Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66460/133889 blocks (49.6%), 0 events +2026-02-04T19:14:47.397418Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66470/133889 blocks (49.6%), 0 events +2026-02-04T19:14:47.708800Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66480/133889 blocks (49.7%), 0 events +2026-02-04T19:14:47.817092Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66490/133889 blocks (49.7%), 0 events +2026-02-04T19:14:48.069893Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66500/133889 blocks (49.7%), 0 events +2026-02-04T19:14:48.233232Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66510/133889 blocks (49.7%), 0 events +2026-02-04T19:14:48.410860Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66520/133889 blocks (49.7%), 0 events +2026-02-04T19:14:48.645879Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66530/133889 blocks (49.7%), 0 events +2026-02-04T19:14:48.851686Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66540/133889 blocks (49.7%), 0 events +2026-02-04T19:14:49.087170Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66550/133889 blocks (49.7%), 0 events +2026-02-04T19:14:49.200737Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66560/133889 blocks (49.7%), 0 events +2026-02-04T19:14:49.435274Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66570/133889 blocks (49.7%), 0 events +2026-02-04T19:14:49.643845Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66580/133889 blocks (49.7%), 0 events +2026-02-04T19:14:49.837556Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66590/133889 blocks (49.7%), 0 events +2026-02-04T19:14:50.030346Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66600/133889 blocks (49.7%), 0 events +2026-02-04T19:14:50.329847Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66610/133889 blocks (49.7%), 0 events +2026-02-04T19:14:50.367081Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66620/133889 blocks (49.8%), 0 events +2026-02-04T19:14:50.658330Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66630/133889 blocks (49.8%), 0 events +2026-02-04T19:14:50.887456Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66640/133889 blocks (49.8%), 0 events +2026-02-04T19:14:51.002934Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66650/133889 blocks (49.8%), 0 events +2026-02-04T19:14:51.214196Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66660/133889 blocks (49.8%), 0 events +2026-02-04T19:14:51.415842Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66670/133889 blocks (49.8%), 0 events +2026-02-04T19:14:51.593731Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66680/133889 blocks (49.8%), 0 events +2026-02-04T19:14:51.827525Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66690/133889 blocks (49.8%), 0 events +2026-02-04T19:14:51.969875Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66700/133889 blocks (49.8%), 0 events +2026-02-04T19:14:52.263106Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66710/133889 blocks (49.8%), 0 events +2026-02-04T19:14:52.426536Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66720/133889 blocks (49.8%), 0 events +2026-02-04T19:14:52.627761Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66730/133889 blocks (49.8%), 0 events +2026-02-04T19:14:52.839513Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66740/133889 blocks (49.8%), 0 events +2026-02-04T19:14:53.281805Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66750/133889 blocks (49.9%), 0 events +2026-02-04T19:14:53.320256Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66760/133889 blocks (49.9%), 0 events +2026-02-04T19:14:53.360451Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66770/133889 blocks (49.9%), 0 events +2026-02-04T19:14:53.657475Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66780/133889 blocks (49.9%), 0 events +2026-02-04T19:14:53.839616Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66790/133889 blocks (49.9%), 0 events +2026-02-04T19:14:54.037319Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66800/133889 blocks (49.9%), 0 events +2026-02-04T19:14:54.217761Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66810/133889 blocks (49.9%), 0 events +2026-02-04T19:14:54.420140Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66820/133889 blocks (49.9%), 0 events +2026-02-04T19:14:54.581253Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66830/133889 blocks (49.9%), 0 events +2026-02-04T19:14:54.854130Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66840/133889 blocks (49.9%), 0 events +2026-02-04T19:14:55.049671Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66850/133889 blocks (49.9%), 0 events +2026-02-04T19:14:55.227020Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66860/133889 blocks (49.9%), 0 events +2026-02-04T19:14:55.443186Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66870/133889 blocks (49.9%), 0 events +2026-02-04T19:14:55.632225Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66880/133889 blocks (50.0%), 0 events +2026-02-04T19:14:55.931832Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66890/133889 blocks (50.0%), 0 events +2026-02-04T19:14:55.970183Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66900/133889 blocks (50.0%), 0 events +2026-02-04T19:14:56.190345Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66910/133889 blocks (50.0%), 0 events +2026-02-04T19:14:56.456380Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66920/133889 blocks (50.0%), 0 events +2026-02-04T19:14:56.653895Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66930/133889 blocks (50.0%), 0 events +2026-02-04T19:14:56.788783Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66940/133889 blocks (50.0%), 0 events +2026-02-04T19:14:57.042803Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66950/133889 blocks (50.0%), 0 events +2026-02-04T19:14:57.243669Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66960/133889 blocks (50.0%), 0 events +2026-02-04T19:14:57.506730Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66970/133889 blocks (50.0%), 0 events +2026-02-04T19:14:57.623442Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66980/133889 blocks (50.0%), 0 events +2026-02-04T19:14:57.857364Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66990/133889 blocks (50.0%), 0 events +2026-02-04T19:14:58.031833Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67000/133889 blocks (50.0%), 0 events +2026-02-04T19:14:58.192554Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67010/133889 blocks (50.0%), 0 events +2026-02-04T19:14:58.383470Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67020/133889 blocks (50.1%), 0 events +2026-02-04T19:14:58.638149Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67030/133889 blocks (50.1%), 0 events +2026-02-04T19:14:58.786159Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67040/133889 blocks (50.1%), 0 events +2026-02-04T19:14:59.081392Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67050/133889 blocks (50.1%), 0 events +2026-02-04T19:14:59.198438Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67060/133889 blocks (50.1%), 0 events +2026-02-04T19:14:59.453147Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67070/133889 blocks (50.1%), 0 events +2026-02-04T19:14:59.611519Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67080/133889 blocks (50.1%), 0 events +2026-02-04T19:14:59.825210Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67090/133889 blocks (50.1%), 0 events +2026-02-04T19:15:00.095242Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67100/133889 blocks (50.1%), 0 events +2026-02-04T19:15:00.217517Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67110/133889 blocks (50.1%), 0 events +2026-02-04T19:15:00.400750Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67120/133889 blocks (50.1%), 0 events +2026-02-04T19:15:00.662880Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67130/133889 blocks (50.1%), 0 events +2026-02-04T19:15:00.848398Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67140/133889 blocks (50.1%), 0 events +2026-02-04T19:15:01.144304Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67150/133889 blocks (50.2%), 0 events +2026-02-04T19:15:01.193595Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67160/133889 blocks (50.2%), 0 events +2026-02-04T19:15:01.454774Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67170/133889 blocks (50.2%), 0 events +2026-02-04T19:15:01.574560Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67180/133889 blocks (50.2%), 0 events +2026-02-04T19:15:01.822438Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67190/133889 blocks (50.2%), 0 events +2026-02-04T19:15:02.030363Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67200/133889 blocks (50.2%), 0 events +2026-02-04T19:15:02.262565Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67210/133889 blocks (50.2%), 0 events +2026-02-04T19:15:02.422294Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67220/133889 blocks (50.2%), 0 events +2026-02-04T19:15:02.565920Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67230/133889 blocks (50.2%), 0 events +2026-02-04T19:15:02.912516Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67240/133889 blocks (50.2%), 0 events +2026-02-04T19:15:02.995158Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67250/133889 blocks (50.2%), 0 events +2026-02-04T19:15:03.239415Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67260/133889 blocks (50.2%), 0 events +2026-02-04T19:15:03.481965Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67270/133889 blocks (50.2%), 0 events +2026-02-04T19:15:03.628701Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67280/133889 blocks (50.3%), 0 events +2026-02-04T19:15:03.799088Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67290/133889 blocks (50.3%), 0 events +2026-02-04T19:15:04.044996Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67300/133889 blocks (50.3%), 0 events +2026-02-04T19:15:04.172756Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67310/133889 blocks (50.3%), 0 events +2026-02-04T19:15:04.376520Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67320/133889 blocks (50.3%), 0 events +2026-02-04T19:15:04.603374Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67330/133889 blocks (50.3%), 0 events +2026-02-04T19:15:04.846923Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67340/133889 blocks (50.3%), 0 events +2026-02-04T19:15:04.989136Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67350/133889 blocks (50.3%), 0 events +2026-02-04T19:15:05.224684Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67360/133889 blocks (50.3%), 0 events +2026-02-04T19:15:05.430104Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67370/133889 blocks (50.3%), 0 events +2026-02-04T19:15:05.615021Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67380/133889 blocks (50.3%), 0 events +2026-02-04T19:15:05.897395Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67390/133889 blocks (50.3%), 0 events +2026-02-04T19:15:06.018362Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67400/133889 blocks (50.3%), 0 events +2026-02-04T19:15:06.254240Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67410/133889 blocks (50.3%), 0 events +2026-02-04T19:15:06.423657Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67420/133889 blocks (50.4%), 0 events +2026-02-04T19:15:06.636426Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67430/133889 blocks (50.4%), 0 events +2026-02-04T19:15:06.945581Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67440/133889 blocks (50.4%), 0 events +2026-02-04T19:15:06.984915Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67450/133889 blocks (50.4%), 0 events +2026-02-04T19:15:07.258306Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67460/133889 blocks (50.4%), 0 events +2026-02-04T19:15:07.465694Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67470/133889 blocks (50.4%), 0 events +2026-02-04T19:15:07.667714Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67480/133889 blocks (50.4%), 0 events +2026-02-04T19:15:07.822550Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67490/133889 blocks (50.4%), 0 events +2026-02-04T19:15:07.996833Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67500/133889 blocks (50.4%), 0 events +2026-02-04T19:15:08.244188Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67510/133889 blocks (50.4%), 0 events +2026-02-04T19:15:08.516811Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67520/133889 blocks (50.4%), 0 events +2026-02-04T19:15:08.558107Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67530/133889 blocks (50.4%), 0 events +2026-02-04T19:15:08.858642Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67540/133889 blocks (50.4%), 0 events +2026-02-04T19:15:09.063665Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67550/133889 blocks (50.5%), 0 events +2026-02-04T19:15:09.235038Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67560/133889 blocks (50.5%), 0 events +2026-02-04T19:15:09.417798Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67570/133889 blocks (50.5%), 0 events +2026-02-04T19:15:09.649029Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67580/133889 blocks (50.5%), 0 events +2026-02-04T19:15:09.765426Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67590/133889 blocks (50.5%), 0 events +2026-02-04T19:15:10.094001Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67600/133889 blocks (50.5%), 0 events +2026-02-04T19:15:10.216282Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67610/133889 blocks (50.5%), 0 events +2026-02-04T19:15:10.437903Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67620/133889 blocks (50.5%), 0 events +2026-02-04T19:15:10.614255Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67630/133889 blocks (50.5%), 0 events +2026-02-04T19:15:10.826991Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67640/133889 blocks (50.5%), 0 events +2026-02-04T19:15:10.981234Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67650/133889 blocks (50.5%), 0 events +2026-02-04T19:15:11.212047Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67660/133889 blocks (50.5%), 0 events +2026-02-04T19:15:11.381963Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67670/133889 blocks (50.5%), 0 events +2026-02-04T19:15:11.672614Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67680/133889 blocks (50.5%), 0 events +2026-02-04T19:15:11.842961Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67690/133889 blocks (50.6%), 0 events +2026-02-04T19:15:11.983439Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67700/133889 blocks (50.6%), 0 events +2026-02-04T19:15:12.241285Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67710/133889 blocks (50.6%), 0 events +2026-02-04T19:15:12.440786Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67720/133889 blocks (50.6%), 0 events +2026-02-04T19:15:12.677865Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67730/133889 blocks (50.6%), 0 events +2026-02-04T19:15:12.799873Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67740/133889 blocks (50.6%), 0 events +2026-02-04T19:15:12.994497Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67750/133889 blocks (50.6%), 0 events +2026-02-04T19:15:13.237163Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67760/133889 blocks (50.6%), 0 events +2026-02-04T19:15:13.380864Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67770/133889 blocks (50.6%), 0 events +2026-02-04T19:15:13.727230Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67780/133889 blocks (50.6%), 0 events +2026-02-04T19:15:13.770267Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67790/133889 blocks (50.6%), 0 events +2026-02-04T19:15:13.968111Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67800/133889 blocks (50.6%), 0 events +2026-02-04T19:15:14.284053Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67810/133889 blocks (50.6%), 0 events +2026-02-04T19:15:14.415012Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67820/133889 blocks (50.7%), 0 events +2026-02-04T19:15:14.629816Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67830/133889 blocks (50.7%), 0 events +2026-02-04T19:15:14.842336Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67840/133889 blocks (50.7%), 0 events +2026-02-04T19:15:14.986010Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67850/133889 blocks (50.7%), 0 events +2026-02-04T19:15:15.300544Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67860/133889 blocks (50.7%), 0 events +2026-02-04T19:15:15.433566Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67870/133889 blocks (50.7%), 0 events +2026-02-04T19:15:15.635854Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67880/133889 blocks (50.7%), 0 events +2026-02-04T19:15:15.859131Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67890/133889 blocks (50.7%), 0 events +2026-02-04T19:15:15.979922Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67900/133889 blocks (50.7%), 0 events +2026-02-04T19:15:16.215422Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67910/133889 blocks (50.7%), 0 events +2026-02-04T19:15:16.384197Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67920/133889 blocks (50.7%), 0 events +2026-02-04T19:15:16.582145Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67930/133889 blocks (50.7%), 0 events +2026-02-04T19:15:16.904544Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67940/133889 blocks (50.7%), 0 events +2026-02-04T19:15:16.971033Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67950/133889 blocks (50.8%), 0 events +2026-02-04T19:15:17.263469Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67960/133889 blocks (50.8%), 0 events +2026-02-04T19:15:17.465542Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67970/133889 blocks (50.8%), 0 events +2026-02-04T19:15:17.655331Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67980/133889 blocks (50.8%), 0 events +2026-02-04T19:15:17.820963Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67990/133889 blocks (50.8%), 0 events +2026-02-04T19:15:18.067311Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68000/133889 blocks (50.8%), 0 events +2026-02-04T19:15:18.279393Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68010/133889 blocks (50.8%), 0 events +2026-02-04T19:15:18.473253Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68020/133889 blocks (50.8%), 0 events +2026-02-04T19:15:18.656774Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68030/133889 blocks (50.8%), 0 events +2026-02-04T19:15:18.809108Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68040/133889 blocks (50.8%), 0 events +2026-02-04T19:15:19.018879Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68050/133889 blocks (50.8%), 0 events +2026-02-04T19:15:19.225996Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68060/133889 blocks (50.8%), 0 events +2026-02-04T19:15:19.530660Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68070/133889 blocks (50.8%), 0 events +2026-02-04T19:15:19.565690Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68080/133889 blocks (50.8%), 0 events +2026-02-04T19:15:19.848067Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68090/133889 blocks (50.9%), 0 events +2026-02-04T19:15:20.050328Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68100/133889 blocks (50.9%), 0 events +2026-02-04T19:15:20.226089Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68110/133889 blocks (50.9%), 0 events +2026-02-04T19:15:20.391945Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68120/133889 blocks (50.9%), 0 events +2026-02-04T19:15:20.613439Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68130/133889 blocks (50.9%), 0 events +2026-02-04T19:15:20.769055Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68140/133889 blocks (50.9%), 0 events +2026-02-04T19:15:21.064822Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68150/133889 blocks (50.9%), 0 events +2026-02-04T19:15:21.228041Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68160/133889 blocks (50.9%), 0 events +2026-02-04T19:15:21.401683Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68170/133889 blocks (50.9%), 0 events +2026-02-04T19:15:21.626167Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68180/133889 blocks (50.9%), 0 events +2026-02-04T19:15:21.835608Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68190/133889 blocks (50.9%), 0 events +2026-02-04T19:15:22.112827Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68200/133889 blocks (50.9%), 0 events +2026-02-04T19:15:22.192860Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68210/133889 blocks (50.9%), 0 events +2026-02-04T19:15:22.433331Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68220/133889 blocks (51.0%), 0 events +2026-02-04T19:15:22.674827Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68230/133889 blocks (51.0%), 0 events +2026-02-04T19:15:22.770399Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68240/133889 blocks (51.0%), 0 events +2026-02-04T19:15:23.054608Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68250/133889 blocks (51.0%), 0 events +2026-02-04T19:15:23.196974Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68260/133889 blocks (51.0%), 0 events +2026-02-04T19:15:23.432749Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68270/133889 blocks (51.0%), 0 events +2026-02-04T19:15:23.574768Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68280/133889 blocks (51.0%), 0 events +2026-02-04T19:15:23.806743Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68290/133889 blocks (51.0%), 0 events +2026-02-04T19:15:24.003244Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68300/133889 blocks (51.0%), 0 events +2026-02-04T19:15:24.260643Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68310/133889 blocks (51.0%), 0 events +2026-02-04T19:15:24.452031Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68320/133889 blocks (51.0%), 0 events +2026-02-04T19:15:24.558485Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68330/133889 blocks (51.0%), 0 events +2026-02-04T19:15:24.778676Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68340/133889 blocks (51.0%), 0 events +2026-02-04T19:15:24.997481Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68350/133889 blocks (51.0%), 0 events +2026-02-04T19:15:25.295606Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68360/133889 blocks (51.1%), 0 events +2026-02-04T19:15:25.500521Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68370/133889 blocks (51.1%), 0 events +2026-02-04T19:15:25.644698Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68380/133889 blocks (51.1%), 0 events +2026-02-04T19:15:25.820910Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68390/133889 blocks (51.1%), 0 events +2026-02-04T19:15:26.021164Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68400/133889 blocks (51.1%), 0 events +2026-02-04T19:15:26.208770Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68410/133889 blocks (51.1%), 0 events +2026-02-04T19:15:26.504037Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68420/133889 blocks (51.1%), 0 events +2026-02-04T19:15:26.653793Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68430/133889 blocks (51.1%), 0 events +2026-02-04T19:15:26.869403Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68440/133889 blocks (51.1%), 0 events +2026-02-04T19:15:27.075861Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68450/133889 blocks (51.1%), 0 events +2026-02-04T19:15:27.224813Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68460/133889 blocks (51.1%), 0 events +2026-02-04T19:15:27.409431Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68470/133889 blocks (51.1%), 0 events +2026-02-04T19:15:27.652286Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68480/133889 blocks (51.1%), 0 events +2026-02-04T19:15:27.918093Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68490/133889 blocks (51.2%), 0 events +2026-02-04T19:15:27.960192Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68500/133889 blocks (51.2%), 0 events +2026-02-04T19:15:28.170469Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68510/133889 blocks (51.2%), 0 events +2026-02-04T19:15:28.443252Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68520/133889 blocks (51.2%), 0 events +2026-02-04T19:15:28.662807Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68530/133889 blocks (51.2%), 0 events +2026-02-04T19:15:28.770170Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68540/133889 blocks (51.2%), 0 events +2026-02-04T19:15:29.038881Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68550/133889 blocks (51.2%), 0 events +2026-02-04T19:15:29.162681Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68560/133889 blocks (51.2%), 0 events +2026-02-04T19:15:29.494253Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68570/133889 blocks (51.2%), 0 events +2026-02-04T19:15:29.601210Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68580/133889 blocks (51.2%), 0 events +2026-02-04T19:15:29.811660Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68590/133889 blocks (51.2%), 0 events +2026-02-04T19:15:30.036406Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68600/133889 blocks (51.2%), 0 events +2026-02-04T19:15:30.248965Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68610/133889 blocks (51.2%), 0 events +2026-02-04T19:15:30.537824Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68620/133889 blocks (51.3%), 0 events +2026-02-04T19:15:30.581786Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68630/133889 blocks (51.3%), 0 events +2026-02-04T19:15:30.870225Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68640/133889 blocks (51.3%), 0 events +2026-02-04T19:15:31.065637Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68650/133889 blocks (51.3%), 0 events +2026-02-04T19:15:31.232844Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68660/133889 blocks (51.3%), 0 events +2026-02-04T19:15:31.425406Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68670/133889 blocks (51.3%), 0 events +2026-02-04T19:15:31.588814Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68680/133889 blocks (51.3%), 0 events +2026-02-04T19:15:31.845212Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68690/133889 blocks (51.3%), 0 events +2026-02-04T19:15:32.122177Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68700/133889 blocks (51.3%), 0 events +2026-02-04T19:15:32.164807Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68710/133889 blocks (51.3%), 0 events +2026-02-04T19:15:32.393920Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68720/133889 blocks (51.3%), 0 events +2026-02-04T19:15:32.634539Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68730/133889 blocks (51.3%), 0 events +2026-02-04T19:15:32.767060Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68740/133889 blocks (51.3%), 0 events +2026-02-04T19:15:33.010086Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68750/133889 blocks (51.3%), 0 events +2026-02-04T19:15:33.215382Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68760/133889 blocks (51.4%), 0 events +2026-02-04T19:15:33.683467Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68770/133889 blocks (51.4%), 0 events +2026-02-04T19:15:33.728074Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68780/133889 blocks (51.4%), 0 events +2026-02-04T19:15:33.774225Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68790/133889 blocks (51.4%), 0 events +2026-02-04T19:15:33.975453Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68800/133889 blocks (51.4%), 0 events +2026-02-04T19:15:34.211191Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68810/133889 blocks (51.4%), 0 events +2026-02-04T19:15:34.432539Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68820/133889 blocks (51.4%), 0 events +2026-02-04T19:15:34.588339Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68830/133889 blocks (51.4%), 0 events +2026-02-04T19:15:34.795212Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68840/133889 blocks (51.4%), 0 events +2026-02-04T19:15:35.037768Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68850/133889 blocks (51.4%), 0 events +2026-02-04T19:15:35.264300Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68860/133889 blocks (51.4%), 0 events +2026-02-04T19:15:35.458598Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68870/133889 blocks (51.4%), 0 events +2026-02-04T19:15:35.599685Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68880/133889 blocks (51.4%), 0 events +2026-02-04T19:15:35.798911Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68890/133889 blocks (51.5%), 0 events +2026-02-04T19:15:36.052557Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68900/133889 blocks (51.5%), 0 events +2026-02-04T19:15:36.302103Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68910/133889 blocks (51.5%), 0 events +2026-02-04T19:15:36.422067Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68920/133889 blocks (51.5%), 0 events +2026-02-04T19:15:36.613960Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68930/133889 blocks (51.5%), 0 events +2026-02-04T19:15:36.849438Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68940/133889 blocks (51.5%), 0 events +2026-02-04T19:15:37.009388Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68950/133889 blocks (51.5%), 0 events +2026-02-04T19:15:37.318914Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68960/133889 blocks (51.5%), 0 events +2026-02-04T19:15:37.362424Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68970/133889 blocks (51.5%), 0 events +2026-02-04T19:15:37.593709Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68980/133889 blocks (51.5%), 0 events +2026-02-04T19:15:37.881105Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68990/133889 blocks (51.5%), 0 events +2026-02-04T19:15:38.041265Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69000/133889 blocks (51.5%), 0 events +2026-02-04T19:15:38.185562Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69010/133889 blocks (51.5%), 0 events +2026-02-04T19:15:38.398089Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69020/133889 blocks (51.5%), 0 events +2026-02-04T19:15:38.644466Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69030/133889 blocks (51.6%), 0 events +2026-02-04T19:15:38.925038Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69040/133889 blocks (51.6%), 0 events +2026-02-04T19:15:38.967470Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69050/133889 blocks (51.6%), 0 events +2026-02-04T19:15:39.232145Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69060/133889 blocks (51.6%), 0 events +2026-02-04T19:15:39.448624Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69070/133889 blocks (51.6%), 0 events +2026-02-04T19:15:39.641354Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69080/133889 blocks (51.6%), 0 events +2026-02-04T19:15:39.941629Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69090/133889 blocks (51.6%), 0 events +2026-02-04T19:15:39.980767Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69100/133889 blocks (51.6%), 0 events +2026-02-04T19:15:40.249164Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69110/133889 blocks (51.6%), 0 events +2026-02-04T19:15:40.465617Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69120/133889 blocks (51.6%), 0 events +2026-02-04T19:15:40.635853Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69130/133889 blocks (51.6%), 0 events +2026-02-04T19:15:40.778353Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69140/133889 blocks (51.6%), 0 events +2026-02-04T19:15:41.031131Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69150/133889 blocks (51.6%), 0 events +2026-02-04T19:15:41.232443Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69160/133889 blocks (51.7%), 0 events +2026-02-04T19:15:41.376833Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69170/133889 blocks (51.7%), 0 events +2026-02-04T19:15:41.641908Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69180/133889 blocks (51.7%), 0 events +2026-02-04T19:15:41.780924Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69190/133889 blocks (51.7%), 0 events +2026-02-04T19:15:42.082534Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69200/133889 blocks (51.7%), 0 events +2026-02-04T19:15:42.232856Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69210/133889 blocks (51.7%), 0 events +2026-02-04T19:15:42.452060Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69220/133889 blocks (51.7%), 0 events +2026-02-04T19:15:42.598131Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69230/133889 blocks (51.7%), 0 events +2026-02-04T19:15:42.786847Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69240/133889 blocks (51.7%), 0 events +2026-02-04T19:15:43.124426Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69250/133889 blocks (51.7%), 0 events +2026-02-04T19:15:43.164203Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69260/133889 blocks (51.7%), 0 events +2026-02-04T19:15:43.409649Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69270/133889 blocks (51.7%), 0 events +2026-02-04T19:15:43.641950Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69280/133889 blocks (51.7%), 0 events +2026-02-04T19:15:43.790356Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69290/133889 blocks (51.8%), 0 events +2026-02-04T19:15:44.032245Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69300/133889 blocks (51.8%), 0 events +2026-02-04T19:15:44.249510Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69310/133889 blocks (51.8%), 0 events +2026-02-04T19:15:44.456278Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69320/133889 blocks (51.8%), 0 events +2026-02-04T19:15:44.691035Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69330/133889 blocks (51.8%), 0 events +2026-02-04T19:15:44.801357Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69340/133889 blocks (51.8%), 0 events +2026-02-04T19:15:44.994030Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69350/133889 blocks (51.8%), 0 events +2026-02-04T19:15:45.232464Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69360/133889 blocks (51.8%), 0 events +2026-02-04T19:15:45.387949Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69370/133889 blocks (51.8%), 0 events +2026-02-04T19:15:45.742485Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69380/133889 blocks (51.8%), 0 events +2026-02-04T19:15:45.783233Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69390/133889 blocks (51.8%), 0 events +2026-02-04T19:15:46.002064Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69400/133889 blocks (51.8%), 0 events +2026-02-04T19:15:46.264392Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69410/133889 blocks (51.8%), 0 events +2026-02-04T19:15:46.434809Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69420/133889 blocks (51.8%), 0 events +2026-02-04T19:15:46.642120Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69430/133889 blocks (51.9%), 0 events +2026-02-04T19:15:46.808868Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69440/133889 blocks (51.9%), 0 events +2026-02-04T19:15:46.966755Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69450/133889 blocks (51.9%), 0 events +2026-02-04T19:15:47.320689Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69460/133889 blocks (51.9%), 0 events +2026-02-04T19:15:47.362643Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69470/133889 blocks (51.9%), 0 events +2026-02-04T19:15:47.576222Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69480/133889 blocks (51.9%), 0 events +2026-02-04T19:15:47.850334Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69490/133889 blocks (51.9%), 0 events +2026-02-04T19:15:48.039346Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69500/133889 blocks (51.9%), 0 events +2026-02-04T19:15:48.328345Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69510/133889 blocks (51.9%), 0 events +2026-02-04T19:15:48.371514Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69520/133889 blocks (51.9%), 0 events +2026-02-04T19:15:48.564462Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69530/133889 blocks (51.9%), 0 events +2026-02-04T19:15:48.883482Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69540/133889 blocks (51.9%), 0 events +2026-02-04T19:15:49.087151Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69550/133889 blocks (51.9%), 0 events +2026-02-04T19:15:49.220419Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69560/133889 blocks (52.0%), 0 events +2026-02-04T19:15:49.427931Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69570/133889 blocks (52.0%), 0 events +2026-02-04T19:15:49.611922Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69580/133889 blocks (52.0%), 0 events +2026-02-04T19:15:49.796322Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69590/133889 blocks (52.0%), 0 events +2026-02-04T19:15:50.096172Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69600/133889 blocks (52.0%), 0 events +2026-02-04T19:15:50.242644Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69610/133889 blocks (52.0%), 0 events +2026-02-04T19:15:50.463784Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69620/133889 blocks (52.0%), 0 events +2026-02-04T19:15:50.652492Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69630/133889 blocks (52.0%), 0 events +2026-02-04T19:15:50.791571Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69640/133889 blocks (52.0%), 0 events +2026-02-04T19:15:51.034577Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69650/133889 blocks (52.0%), 0 events +2026-02-04T19:15:51.182666Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69660/133889 blocks (52.0%), 0 events +2026-02-04T19:15:51.518907Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69670/133889 blocks (52.0%), 0 events +2026-02-04T19:15:51.559329Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69680/133889 blocks (52.0%), 0 events +2026-02-04T19:15:51.828084Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69690/133889 blocks (52.1%), 0 events +2026-02-04T19:15:52.036148Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69700/133889 blocks (52.1%), 0 events +2026-02-04T19:15:52.168790Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69710/133889 blocks (52.1%), 0 events +2026-02-04T19:15:52.422306Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69720/133889 blocks (52.1%), 0 events +2026-02-04T19:15:52.600248Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69730/133889 blocks (52.1%), 0 events +2026-02-04T19:15:52.833308Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69740/133889 blocks (52.1%), 0 events +2026-02-04T19:15:53.080975Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69750/133889 blocks (52.1%), 0 events +2026-02-04T19:15:53.193541Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69760/133889 blocks (52.1%), 0 events +2026-02-04T19:15:53.418792Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69770/133889 blocks (52.1%), 0 events +2026-02-04T19:15:53.617756Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69780/133889 blocks (52.1%), 0 events +2026-02-04T19:15:53.822218Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69790/133889 blocks (52.1%), 0 events +2026-02-04T19:15:54.130525Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69800/133889 blocks (52.1%), 0 events +2026-02-04T19:15:54.175432Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69810/133889 blocks (52.1%), 0 events +2026-02-04T19:15:54.437907Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69820/133889 blocks (52.1%), 0 events +2026-02-04T19:15:54.654226Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69830/133889 blocks (52.2%), 0 events +2026-02-04T19:15:54.846422Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69840/133889 blocks (52.2%), 0 events +2026-02-04T19:15:55.031317Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69850/133889 blocks (52.2%), 0 events +2026-02-04T19:15:55.222991Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69860/133889 blocks (52.2%), 0 events +2026-02-04T19:15:55.380674Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69870/133889 blocks (52.2%), 0 events +2026-02-04T19:15:55.666088Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69880/133889 blocks (52.2%), 0 events +2026-02-04T19:15:55.843515Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69890/133889 blocks (52.2%), 0 events +2026-02-04T19:15:55.980770Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69900/133889 blocks (52.2%), 0 events +2026-02-04T19:15:56.245981Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69910/133889 blocks (52.2%), 0 events +2026-02-04T19:15:56.432653Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69920/133889 blocks (52.2%), 0 events +2026-02-04T19:15:56.565853Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69930/133889 blocks (52.2%), 0 events +2026-02-04T19:15:56.801519Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69940/133889 blocks (52.2%), 0 events +2026-02-04T19:15:56.994826Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69950/133889 blocks (52.2%), 0 events +2026-02-04T19:15:57.270271Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69960/133889 blocks (52.3%), 0 events +2026-02-04T19:15:57.406487Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69970/133889 blocks (52.3%), 0 events +2026-02-04T19:15:57.575964Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69980/133889 blocks (52.3%), 0 events +2026-02-04T19:15:57.825169Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69990/133889 blocks (52.3%), 0 events +2026-02-04T19:15:58.031362Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70000/133889 blocks (52.3%), 0 events +2026-02-04T19:15:58.288361Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70010/133889 blocks (52.3%), 0 events +2026-02-04T19:15:58.388761Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70020/133889 blocks (52.3%), 0 events +2026-02-04T19:15:58.659025Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70030/133889 blocks (52.3%), 0 events +2026-02-04T19:15:58.846910Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70040/133889 blocks (52.3%), 0 events +2026-02-04T19:15:59.052226Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70050/133889 blocks (52.3%), 0 events +2026-02-04T19:15:59.245454Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70060/133889 blocks (52.3%), 0 events +2026-02-04T19:15:59.400847Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70070/133889 blocks (52.3%), 0 events +2026-02-04T19:15:59.653192Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70080/133889 blocks (52.3%), 0 events +2026-02-04T19:15:59.862826Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70090/133889 blocks (52.3%), 0 events +2026-02-04T19:16:00.018046Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70100/133889 blocks (52.4%), 0 events +2026-02-04T19:16:00.171473Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70110/133889 blocks (52.4%), 0 events +2026-02-04T19:16:00.441641Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70120/133889 blocks (52.4%), 0 events +2026-02-04T19:16:00.620514Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70130/133889 blocks (52.4%), 0 events +2026-02-04T19:16:00.795626Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70140/133889 blocks (52.4%), 0 events +2026-02-04T19:16:01.013534Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70150/133889 blocks (52.4%), 0 events +2026-02-04T19:16:01.191893Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70160/133889 blocks (52.4%), 0 events +2026-02-04T19:16:01.470508Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70170/133889 blocks (52.4%), 0 events +2026-02-04T19:16:01.618882Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70180/133889 blocks (52.4%), 0 events +2026-02-04T19:16:01.824014Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70190/133889 blocks (52.4%), 0 events +2026-02-04T19:16:01.996098Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70200/133889 blocks (52.4%), 0 events +2026-02-04T19:16:02.245202Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70210/133889 blocks (52.4%), 0 events +2026-02-04T19:16:02.483790Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70220/133889 blocks (52.4%), 0 events +2026-02-04T19:16:02.650786Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70230/133889 blocks (52.5%), 0 events +2026-02-04T19:16:02.819209Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70240/133889 blocks (52.5%), 0 events +2026-02-04T19:16:03.053227Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70250/133889 blocks (52.5%), 0 events +2026-02-04T19:16:03.234264Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70260/133889 blocks (52.5%), 0 events +2026-02-04T19:16:03.434550Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70270/133889 blocks (52.5%), 0 events +2026-02-04T19:16:03.567241Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70280/133889 blocks (52.5%), 0 events +2026-02-04T19:16:03.760032Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70290/133889 blocks (52.5%), 0 events +2026-02-04T19:16:04.056086Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70300/133889 blocks (52.5%), 0 events +2026-02-04T19:16:04.257463Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70310/133889 blocks (52.5%), 0 events +2026-02-04T19:16:04.391770Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70320/133889 blocks (52.5%), 0 events +2026-02-04T19:16:04.640408Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70330/133889 blocks (52.5%), 0 events +2026-02-04T19:16:04.835006Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70340/133889 blocks (52.5%), 0 events +2026-02-04T19:16:05.103114Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70350/133889 blocks (52.5%), 0 events +2026-02-04T19:16:05.233472Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70360/133889 blocks (52.6%), 0 events +2026-02-04T19:16:05.450583Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70370/133889 blocks (52.6%), 0 events +2026-02-04T19:16:05.664590Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70380/133889 blocks (52.6%), 0 events +2026-02-04T19:16:05.821167Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70390/133889 blocks (52.6%), 0 events +2026-02-04T19:16:05.967025Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70400/133889 blocks (52.6%), 0 events +2026-02-04T19:16:06.234845Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70410/133889 blocks (52.6%), 0 events +2026-02-04T19:16:06.454467Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70420/133889 blocks (52.6%), 0 events +2026-02-04T19:16:06.679466Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70430/133889 blocks (52.6%), 0 events +2026-02-04T19:16:06.822922Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70440/133889 blocks (52.6%), 0 events +2026-02-04T19:16:06.970517Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70450/133889 blocks (52.6%), 0 events +2026-02-04T19:16:07.236148Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70460/133889 blocks (52.6%), 0 events +2026-02-04T19:16:07.429030Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70470/133889 blocks (52.6%), 0 events +2026-02-04T19:16:07.725901Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70480/133889 blocks (52.6%), 0 events +2026-02-04T19:16:07.767613Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70490/133889 blocks (52.6%), 0 events +2026-02-04T19:16:07.974747Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70500/133889 blocks (52.7%), 0 events +2026-02-04T19:16:08.280459Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70510/133889 blocks (52.7%), 0 events +2026-02-04T19:16:08.446064Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70520/133889 blocks (52.7%), 0 events +2026-02-04T19:16:08.608640Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70530/133889 blocks (52.7%), 0 events +2026-02-04T19:16:08.805683Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70540/133889 blocks (52.7%), 0 events +2026-02-04T19:16:09.035124Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70550/133889 blocks (52.7%), 0 events +2026-02-04T19:16:09.331977Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70560/133889 blocks (52.7%), 0 events +2026-02-04T19:16:09.369762Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70570/133889 blocks (52.7%), 0 events +2026-02-04T19:16:09.571103Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70580/133889 blocks (52.7%), 0 events +2026-02-04T19:16:09.866223Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70590/133889 blocks (52.7%), 0 events +2026-02-04T19:16:10.060454Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70600/133889 blocks (52.7%), 0 events +2026-02-04T19:16:10.200821Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70610/133889 blocks (52.7%), 0 events +2026-02-04T19:16:10.435412Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70620/133889 blocks (52.7%), 0 events +2026-02-04T19:16:10.642468Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70630/133889 blocks (52.8%), 0 events +2026-02-04T19:16:10.872118Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70640/133889 blocks (52.8%), 0 events +2026-02-04T19:16:10.961673Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70650/133889 blocks (52.8%), 0 events +2026-02-04T19:16:11.258045Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70660/133889 blocks (52.8%), 0 events +2026-02-04T19:16:11.442412Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70670/133889 blocks (52.8%), 0 events +2026-02-04T19:16:11.612022Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70680/133889 blocks (52.8%), 0 events +2026-02-04T19:16:11.920958Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70690/133889 blocks (52.8%), 0 events +2026-02-04T19:16:11.956051Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70700/133889 blocks (52.8%), 0 events +2026-02-04T19:16:12.221228Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70710/133889 blocks (52.8%), 0 events +2026-02-04T19:16:12.473535Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70720/133889 blocks (52.8%), 0 events +2026-02-04T19:16:12.679906Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70730/133889 blocks (52.8%), 0 events +2026-02-04T19:16:12.771535Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70740/133889 blocks (52.8%), 0 events +2026-02-04T19:16:13.039655Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70750/133889 blocks (52.8%), 0 events +2026-02-04T19:16:13.228748Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70760/133889 blocks (52.8%), 0 events +2026-02-04T19:16:13.494080Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70770/133889 blocks (52.9%), 0 events +2026-02-04T19:16:13.695299Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70780/133889 blocks (52.9%), 0 events +2026-02-04T19:16:13.813646Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70790/133889 blocks (52.9%), 0 events +2026-02-04T19:16:14.050494Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70800/133889 blocks (52.9%), 0 events +2026-02-04T19:16:14.244703Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70810/133889 blocks (52.9%), 0 events +2026-02-04T19:16:14.376076Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70820/133889 blocks (52.9%), 0 events +2026-02-04T19:16:14.639002Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70830/133889 blocks (52.9%), 0 events +2026-02-04T19:16:14.784878Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70840/133889 blocks (52.9%), 0 events +2026-02-04T19:16:15.064493Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70850/133889 blocks (52.9%), 0 events +2026-02-04T19:16:15.301066Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70860/133889 blocks (52.9%), 0 events +2026-02-04T19:16:15.421732Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70870/133889 blocks (52.9%), 0 events +2026-02-04T19:16:15.637155Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70880/133889 blocks (52.9%), 0 events +2026-02-04T19:16:15.856967Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70890/133889 blocks (52.9%), 0 events +2026-02-04T19:16:16.114409Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70900/133889 blocks (53.0%), 0 events +2026-02-04T19:16:16.219216Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70910/133889 blocks (53.0%), 0 events +2026-02-04T19:16:16.435834Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70920/133889 blocks (53.0%), 0 events +2026-02-04T19:16:16.674772Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70930/133889 blocks (53.0%), 0 events +2026-02-04T19:16:16.870768Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70940/133889 blocks (53.0%), 0 events +2026-02-04T19:16:17.003604Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70950/133889 blocks (53.0%), 0 events +2026-02-04T19:16:17.195462Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70960/133889 blocks (53.0%), 0 events +2026-02-04T19:16:17.456155Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70970/133889 blocks (53.0%), 0 events +2026-02-04T19:16:17.718687Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70980/133889 blocks (53.0%), 0 events +2026-02-04T19:16:17.762970Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70990/133889 blocks (53.0%), 0 events +2026-02-04T19:16:18.023103Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71000/133889 blocks (53.0%), 0 events +2026-02-04T19:16:18.241033Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71010/133889 blocks (53.0%), 0 events +2026-02-04T19:16:18.400387Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71020/133889 blocks (53.0%), 0 events +2026-02-04T19:16:18.629435Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71030/133889 blocks (53.1%), 0 events +2026-02-04T19:16:18.824851Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71040/133889 blocks (53.1%), 0 events +2026-02-04T19:16:19.006225Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71050/133889 blocks (53.1%), 0 events +2026-02-04T19:16:19.305253Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71060/133889 blocks (53.1%), 0 events +2026-02-04T19:16:19.421541Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71070/133889 blocks (53.1%), 0 events +2026-02-04T19:16:19.622833Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71080/133889 blocks (53.1%), 0 events +2026-02-04T19:16:19.846714Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71090/133889 blocks (53.1%), 0 events +2026-02-04T19:16:20.037925Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71100/133889 blocks (53.1%), 0 events +2026-02-04T19:16:20.205595Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71110/133889 blocks (53.1%), 0 events +2026-02-04T19:16:20.438302Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71120/133889 blocks (53.1%), 0 events +2026-02-04T19:16:20.598831Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71130/133889 blocks (53.1%), 0 events +2026-02-04T19:16:20.873143Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71140/133889 blocks (53.1%), 0 events +2026-02-04T19:16:21.022668Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71150/133889 blocks (53.1%), 0 events +2026-02-04T19:16:21.170657Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71160/133889 blocks (53.1%), 0 events +2026-02-04T19:16:21.386759Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71170/133889 blocks (53.2%), 0 events +2026-02-04T19:16:21.642696Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71180/133889 blocks (53.2%), 0 events +2026-02-04T19:16:21.881299Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71190/133889 blocks (53.2%), 0 events +2026-02-04T19:16:22.032944Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71200/133889 blocks (53.2%), 0 events +2026-02-04T19:16:22.205195Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71210/133889 blocks (53.2%), 0 events +2026-02-04T19:16:22.444398Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71220/133889 blocks (53.2%), 0 events +2026-02-04T19:16:22.614884Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71230/133889 blocks (53.2%), 0 events +2026-02-04T19:16:22.811291Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71240/133889 blocks (53.2%), 0 events +2026-02-04T19:16:23.030594Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71250/133889 blocks (53.2%), 0 events +2026-02-04T19:16:23.215739Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71260/133889 blocks (53.2%), 0 events +2026-02-04T19:16:23.452433Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71270/133889 blocks (53.2%), 0 events +2026-02-04T19:16:23.616255Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71280/133889 blocks (53.2%), 0 events +2026-02-04T19:16:23.776889Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71290/133889 blocks (53.2%), 0 events +2026-02-04T19:16:24.012618Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71300/133889 blocks (53.3%), 0 events +2026-02-04T19:16:24.183840Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71310/133889 blocks (53.3%), 0 events +2026-02-04T19:16:24.504767Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71320/133889 blocks (53.3%), 0 events +2026-02-04T19:16:24.595294Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71330/133889 blocks (53.3%), 0 events +2026-02-04T19:16:24.781301Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71340/133889 blocks (53.3%), 0 events +2026-02-04T19:16:25.024474Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71350/133889 blocks (53.3%), 0 events +2026-02-04T19:16:25.260481Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71360/133889 blocks (53.3%), 0 events +2026-02-04T19:16:25.397974Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71370/133889 blocks (53.3%), 0 events +2026-02-04T19:16:25.638336Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71380/133889 blocks (53.3%), 0 events +2026-02-04T19:16:25.835218Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71390/133889 blocks (53.3%), 0 events +2026-02-04T19:16:26.074253Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71400/133889 blocks (53.3%), 0 events +2026-02-04T19:16:26.242051Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71410/133889 blocks (53.3%), 0 events +2026-02-04T19:16:26.367028Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71420/133889 blocks (53.3%), 0 events +2026-02-04T19:16:26.641093Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71430/133889 blocks (53.3%), 0 events +2026-02-04T19:16:26.777831Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71440/133889 blocks (53.4%), 0 events +2026-02-04T19:16:26.979104Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71450/133889 blocks (53.4%), 0 events +2026-02-04T19:16:27.318038Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71460/133889 blocks (53.4%), 0 events +2026-02-04T19:16:27.357866Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71470/133889 blocks (53.4%), 0 events +2026-02-04T19:16:27.680009Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71480/133889 blocks (53.4%), 0 events +2026-02-04T19:16:27.874761Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71490/133889 blocks (53.4%), 0 events +2026-02-04T19:16:27.966685Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71500/133889 blocks (53.4%), 0 events +2026-02-04T19:16:28.423388Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71510/133889 blocks (53.4%), 0 events +2026-02-04T19:16:28.458554Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71520/133889 blocks (53.4%), 0 events +2026-02-04T19:16:28.728335Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71530/133889 blocks (53.4%), 0 events +2026-02-04T19:16:28.763950Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71540/133889 blocks (53.4%), 0 events +2026-02-04T19:16:29.036907Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71550/133889 blocks (53.4%), 0 events +2026-02-04T19:16:29.260557Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71560/133889 blocks (53.4%), 0 events +2026-02-04T19:16:29.427035Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71570/133889 blocks (53.5%), 0 events +2026-02-04T19:16:29.562679Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71580/133889 blocks (53.5%), 0 events +2026-02-04T19:16:29.804563Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71590/133889 blocks (53.5%), 0 events +2026-02-04T19:16:29.961205Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71600/133889 blocks (53.5%), 0 events +2026-02-04T19:16:30.271078Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71610/133889 blocks (53.5%), 0 events +2026-02-04T19:16:30.455169Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71620/133889 blocks (53.5%), 0 events +2026-02-04T19:16:30.571266Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71630/133889 blocks (53.5%), 0 events +2026-02-04T19:16:30.829022Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71640/133889 blocks (53.5%), 0 events +2026-02-04T19:16:31.039406Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71650/133889 blocks (53.5%), 0 events +2026-02-04T19:16:31.318759Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71660/133889 blocks (53.5%), 0 events +2026-02-04T19:16:31.619865Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71670/133889 blocks (53.5%), 0 events +2026-02-04T19:16:31.662855Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71680/133889 blocks (53.5%), 0 events +2026-02-04T19:16:31.842139Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71690/133889 blocks (53.5%), 0 events +2026-02-04T19:16:31.968120Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71700/133889 blocks (53.6%), 0 events +2026-02-04T19:16:32.261118Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71710/133889 blocks (53.6%), 0 events +2026-02-04T19:16:32.396546Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71720/133889 blocks (53.6%), 0 events +2026-02-04T19:16:32.592903Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71730/133889 blocks (53.6%), 0 events +2026-02-04T19:16:32.781343Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71740/133889 blocks (53.6%), 0 events +2026-02-04T19:16:33.065405Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71750/133889 blocks (53.6%), 0 events +2026-02-04T19:16:33.194685Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71760/133889 blocks (53.6%), 0 events +2026-02-04T19:16:33.447687Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71770/133889 blocks (53.6%), 0 events +2026-02-04T19:16:33.608170Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71780/133889 blocks (53.6%), 0 events +2026-02-04T19:16:33.832383Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71790/133889 blocks (53.6%), 0 events +2026-02-04T19:16:34.013223Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71800/133889 blocks (53.6%), 0 events +2026-02-04T19:16:34.199052Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71810/133889 blocks (53.6%), 0 events +2026-02-04T19:16:34.464892Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71820/133889 blocks (53.6%), 0 events +2026-02-04T19:16:34.570313Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71830/133889 blocks (53.6%), 0 events +2026-02-04T19:16:34.842218Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71840/133889 blocks (53.7%), 0 events +2026-02-04T19:16:35.025409Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71850/133889 blocks (53.7%), 0 events +2026-02-04T19:16:35.234314Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71860/133889 blocks (53.7%), 0 events +2026-02-04T19:16:35.368606Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71870/133889 blocks (53.7%), 0 events +2026-02-04T19:16:35.564829Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71880/133889 blocks (53.7%), 0 events +2026-02-04T19:16:35.786276Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71890/133889 blocks (53.7%), 0 events +2026-02-04T19:16:36.076546Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71900/133889 blocks (53.7%), 0 events +2026-02-04T19:16:36.169881Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71910/133889 blocks (53.7%), 0 events +2026-02-04T19:16:36.443042Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71920/133889 blocks (53.7%), 0 events +2026-02-04T19:16:36.659667Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71930/133889 blocks (53.7%), 0 events +2026-02-04T19:16:36.818803Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71940/133889 blocks (53.7%), 0 events +2026-02-04T19:16:37.087248Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71950/133889 blocks (53.7%), 0 events +2026-02-04T19:16:37.165871Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71960/133889 blocks (53.7%), 0 events +2026-02-04T19:16:37.388858Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71970/133889 blocks (53.8%), 0 events +2026-02-04T19:16:37.644471Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71980/133889 blocks (53.8%), 0 events +2026-02-04T19:16:37.848885Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71990/133889 blocks (53.8%), 0 events +2026-02-04T19:16:38.025493Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72000/133889 blocks (53.8%), 0 events +2026-02-04T19:16:38.189935Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72010/133889 blocks (53.8%), 0 events +2026-02-04T19:16:38.359376Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72020/133889 blocks (53.8%), 0 events +2026-02-04T19:16:38.658257Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72030/133889 blocks (53.8%), 0 events +2026-02-04T19:16:38.788494Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72040/133889 blocks (53.8%), 0 events +2026-02-04T19:16:38.995970Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72050/133889 blocks (53.8%), 0 events +2026-02-04T19:16:39.226405Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72060/133889 blocks (53.8%), 0 events +2026-02-04T19:16:39.395760Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72070/133889 blocks (53.8%), 0 events +2026-02-04T19:16:39.561436Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72080/133889 blocks (53.8%), 0 events +2026-02-04T19:16:39.835088Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72090/133889 blocks (53.8%), 0 events +2026-02-04T19:16:39.965563Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72100/133889 blocks (53.9%), 0 events +2026-02-04T19:16:40.269151Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72110/133889 blocks (53.9%), 0 events +2026-02-04T19:16:40.447111Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72120/133889 blocks (53.9%), 0 events +2026-02-04T19:16:40.646721Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72130/133889 blocks (53.9%), 0 events +2026-02-04T19:16:40.820605Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72140/133889 blocks (53.9%), 0 events +2026-02-04T19:16:41.010223Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72150/133889 blocks (53.9%), 0 events +2026-02-04T19:16:41.279775Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72160/133889 blocks (53.9%), 0 events +2026-02-04T19:16:41.415308Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72170/133889 blocks (53.9%), 0 events +2026-02-04T19:16:41.570088Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72180/133889 blocks (53.9%), 0 events +2026-02-04T19:16:41.842212Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72190/133889 blocks (53.9%), 0 events +2026-02-04T19:16:42.041972Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72200/133889 blocks (53.9%), 0 events +2026-02-04T19:16:42.221384Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72210/133889 blocks (53.9%), 0 events +2026-02-04T19:16:42.411086Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72220/133889 blocks (53.9%), 0 events +2026-02-04T19:16:42.655778Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72230/133889 blocks (53.9%), 0 events +2026-02-04T19:16:42.755381Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72240/133889 blocks (54.0%), 0 events +2026-02-04T19:16:43.058076Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72250/133889 blocks (54.0%), 0 events +2026-02-04T19:16:43.153312Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72260/133889 blocks (54.0%), 0 events +2026-02-04T19:16:43.423761Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72270/133889 blocks (54.0%), 0 events +2026-02-04T19:16:43.613245Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72280/133889 blocks (54.0%), 0 events +2026-02-04T19:16:43.900636Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72290/133889 blocks (54.0%), 0 events +2026-02-04T19:16:44.053294Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72300/133889 blocks (54.0%), 0 events +2026-02-04T19:16:44.223159Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72310/133889 blocks (54.0%), 0 events +2026-02-04T19:16:44.461555Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72320/133889 blocks (54.0%), 0 events +2026-02-04T19:16:44.630620Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72330/133889 blocks (54.0%), 0 events +2026-02-04T19:16:44.766249Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72340/133889 blocks (54.0%), 0 events +2026-02-04T19:16:44.992273Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72350/133889 blocks (54.0%), 0 events +2026-02-04T19:16:45.172483Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72360/133889 blocks (54.0%), 0 events +2026-02-04T19:16:45.504956Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72370/133889 blocks (54.1%), 0 events +2026-02-04T19:16:45.607475Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72380/133889 blocks (54.1%), 0 events +2026-02-04T19:16:45.847471Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72390/133889 blocks (54.1%), 0 events +2026-02-04T19:16:46.040606Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72400/133889 blocks (54.1%), 0 events +2026-02-04T19:16:46.215914Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72410/133889 blocks (54.1%), 0 events +2026-02-04T19:16:46.360451Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72420/133889 blocks (54.1%), 0 events +2026-02-04T19:16:46.656333Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72430/133889 blocks (54.1%), 0 events +2026-02-04T19:16:46.761153Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72440/133889 blocks (54.1%), 0 events +2026-02-04T19:16:47.076959Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72450/133889 blocks (54.1%), 0 events +2026-02-04T19:16:47.166117Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72460/133889 blocks (54.1%), 0 events +2026-02-04T19:16:47.385937Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72470/133889 blocks (54.1%), 0 events +2026-02-04T19:16:47.615086Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72480/133889 blocks (54.1%), 0 events +2026-02-04T19:16:47.844350Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72490/133889 blocks (54.1%), 0 events +2026-02-04T19:16:47.958258Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72500/133889 blocks (54.1%), 0 events +2026-02-04T19:16:48.217731Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72510/133889 blocks (54.2%), 0 events +2026-02-04T19:16:48.412229Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72520/133889 blocks (54.2%), 0 events +2026-02-04T19:16:48.618812Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72530/133889 blocks (54.2%), 0 events +2026-02-04T19:16:48.773590Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72540/133889 blocks (54.2%), 0 events +2026-02-04T19:16:49.141287Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72550/133889 blocks (54.2%), 0 events +2026-02-04T19:16:49.177354Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72560/133889 blocks (54.2%), 0 events +2026-02-04T19:16:49.378216Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72570/133889 blocks (54.2%), 0 events +2026-02-04T19:16:49.667904Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72580/133889 blocks (54.2%), 0 events +2026-02-04T19:16:49.767741Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72590/133889 blocks (54.2%), 0 events +2026-02-04T19:16:50.011077Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72600/133889 blocks (54.2%), 0 events +2026-02-04T19:16:50.227160Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72610/133889 blocks (54.2%), 0 events +2026-02-04T19:16:50.398876Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72620/133889 blocks (54.2%), 0 events +2026-02-04T19:16:50.751239Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72630/133889 blocks (54.2%), 0 events +2026-02-04T19:16:50.790520Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72640/133889 blocks (54.3%), 0 events +2026-02-04T19:16:51.032735Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72650/133889 blocks (54.3%), 0 events +2026-02-04T19:16:51.274652Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72660/133889 blocks (54.3%), 0 events +2026-02-04T19:16:51.365233Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72670/133889 blocks (54.3%), 0 events +2026-02-04T19:16:51.618532Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72680/133889 blocks (54.3%), 0 events +2026-02-04T19:16:51.810669Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72690/133889 blocks (54.3%), 0 events +2026-02-04T19:16:52.028666Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72700/133889 blocks (54.3%), 0 events +2026-02-04T19:16:52.289390Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72710/133889 blocks (54.3%), 0 events +2026-02-04T19:16:52.457277Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72720/133889 blocks (54.3%), 0 events +2026-02-04T19:16:52.660098Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72730/133889 blocks (54.3%), 0 events +2026-02-04T19:16:52.843324Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72740/133889 blocks (54.3%), 0 events +2026-02-04T19:16:52.963402Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72750/133889 blocks (54.3%), 0 events +2026-02-04T19:16:53.197860Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72760/133889 blocks (54.3%), 0 events +2026-02-04T19:16:53.371407Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72770/133889 blocks (54.4%), 0 events +2026-02-04T19:16:53.669654Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72780/133889 blocks (54.4%), 0 events +2026-02-04T19:16:53.895388Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72790/133889 blocks (54.4%), 0 events +2026-02-04T19:16:53.987283Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72800/133889 blocks (54.4%), 0 events +2026-02-04T19:16:54.217096Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72810/133889 blocks (54.4%), 0 events +2026-02-04T19:16:54.417866Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72820/133889 blocks (54.4%), 0 events +2026-02-04T19:16:54.645447Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72830/133889 blocks (54.4%), 0 events +2026-02-04T19:16:54.820919Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72840/133889 blocks (54.4%), 0 events +2026-02-04T19:16:55.055309Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72850/133889 blocks (54.4%), 0 events +2026-02-04T19:16:55.229809Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72860/133889 blocks (54.4%), 0 events +2026-02-04T19:16:55.464535Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72870/133889 blocks (54.4%), 0 events +2026-02-04T19:16:55.573768Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72880/133889 blocks (54.4%), 0 events +2026-02-04T19:16:55.819971Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72890/133889 blocks (54.4%), 0 events +2026-02-04T19:16:56.055724Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72900/133889 blocks (54.4%), 0 events +2026-02-04T19:16:56.226418Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72910/133889 blocks (54.5%), 0 events +2026-02-04T19:16:56.515634Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72920/133889 blocks (54.5%), 0 events +2026-02-04T19:16:56.554824Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72930/133889 blocks (54.5%), 0 events +2026-02-04T19:16:56.842153Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72940/133889 blocks (54.5%), 0 events +2026-02-04T19:16:57.036940Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72950/133889 blocks (54.5%), 0 events +2026-02-04T19:16:57.225399Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72960/133889 blocks (54.5%), 0 events +2026-02-04T19:16:57.368321Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72970/133889 blocks (54.5%), 0 events +2026-02-04T19:16:57.600410Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72980/133889 blocks (54.5%), 0 events +2026-02-04T19:16:57.779622Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72990/133889 blocks (54.5%), 0 events +2026-02-04T19:16:58.095297Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73000/133889 blocks (54.5%), 0 events +2026-02-04T19:16:58.228903Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73010/133889 blocks (54.5%), 0 events +2026-02-04T19:16:58.414645Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73020/133889 blocks (54.5%), 0 events +2026-02-04T19:16:58.611498Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73030/133889 blocks (54.5%), 0 events +2026-02-04T19:16:58.845968Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73040/133889 blocks (54.6%), 0 events +2026-02-04T19:16:59.010569Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73050/133889 blocks (54.6%), 0 events +2026-02-04T19:16:59.164377Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73060/133889 blocks (54.6%), 0 events +2026-02-04T19:16:59.445205Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73070/133889 blocks (54.6%), 0 events +2026-02-04T19:16:59.664312Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73080/133889 blocks (54.6%), 0 events +2026-02-04T19:16:59.828324Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73090/133889 blocks (54.6%), 0 events +2026-02-04T19:16:59.978478Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73100/133889 blocks (54.6%), 0 events +2026-02-04T19:17:00.210685Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73110/133889 blocks (54.6%), 0 events +2026-02-04T19:17:00.454432Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73120/133889 blocks (54.6%), 0 events +2026-02-04T19:17:00.677081Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73130/133889 blocks (54.6%), 0 events +2026-02-04T19:17:00.842956Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73140/133889 blocks (54.6%), 0 events +2026-02-04T19:17:00.986806Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73150/133889 blocks (54.6%), 0 events +2026-02-04T19:17:01.234194Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73160/133889 blocks (54.6%), 0 events +2026-02-04T19:17:01.419691Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73170/133889 blocks (54.6%), 0 events +2026-02-04T19:17:01.727191Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73180/133889 blocks (54.7%), 0 events +2026-02-04T19:17:01.770857Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73190/133889 blocks (54.7%), 0 events +2026-02-04T19:17:02.003722Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73200/133889 blocks (54.7%), 0 events +2026-02-04T19:17:02.286409Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73210/133889 blocks (54.7%), 0 events +2026-02-04T19:17:02.434360Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73220/133889 blocks (54.7%), 0 events +2026-02-04T19:17:02.610499Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73230/133889 blocks (54.7%), 0 events +2026-02-04T19:17:02.809965Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73240/133889 blocks (54.7%), 0 events +2026-02-04T19:17:02.984334Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73250/133889 blocks (54.7%), 0 events +2026-02-04T19:17:03.295939Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73260/133889 blocks (54.7%), 0 events +2026-02-04T19:17:03.435243Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73270/133889 blocks (54.7%), 0 events +2026-02-04T19:17:03.579069Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73280/133889 blocks (54.7%), 0 events +2026-02-04T19:17:03.857961Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73290/133889 blocks (54.7%), 0 events +2026-02-04T19:17:03.996958Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73300/133889 blocks (54.7%), 0 events +2026-02-04T19:17:04.222216Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73310/133889 blocks (54.8%), 0 events +2026-02-04T19:17:04.452444Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73320/133889 blocks (54.8%), 0 events +2026-02-04T19:17:04.642369Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73330/133889 blocks (54.8%), 0 events +2026-02-04T19:17:04.871248Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73340/133889 blocks (54.8%), 0 events +2026-02-04T19:17:05.046979Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73350/133889 blocks (54.8%), 0 events +2026-02-04T19:17:05.179802Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73360/133889 blocks (54.8%), 0 events +2026-02-04T19:17:05.455413Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73370/133889 blocks (54.8%), 0 events +2026-02-04T19:17:05.627330Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73380/133889 blocks (54.8%), 0 events +2026-02-04T19:17:05.795712Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73390/133889 blocks (54.8%), 0 events +2026-02-04T19:17:06.009528Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73400/133889 blocks (54.8%), 0 events +2026-02-04T19:17:06.200120Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73410/133889 blocks (54.8%), 0 events +2026-02-04T19:17:06.478901Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73420/133889 blocks (54.8%), 0 events +2026-02-04T19:17:06.622248Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73430/133889 blocks (54.8%), 0 events +2026-02-04T19:17:06.796307Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73440/133889 blocks (54.9%), 0 events +2026-02-04T19:17:07.055658Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73450/133889 blocks (54.9%), 0 events +2026-02-04T19:17:07.173076Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73460/133889 blocks (54.9%), 0 events +2026-02-04T19:17:07.395715Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73470/133889 blocks (54.9%), 0 events +2026-02-04T19:17:07.628190Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73480/133889 blocks (54.9%), 0 events +2026-02-04T19:17:07.768166Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73490/133889 blocks (54.9%), 0 events +2026-02-04T19:17:08.048550Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73500/133889 blocks (54.9%), 0 events +2026-02-04T19:17:08.171030Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73510/133889 blocks (54.9%), 0 events +2026-02-04T19:17:08.431191Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73520/133889 blocks (54.9%), 0 events +2026-02-04T19:17:08.614847Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73530/133889 blocks (54.9%), 0 events +2026-02-04T19:17:08.819344Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73540/133889 blocks (54.9%), 0 events +2026-02-04T19:17:09.098461Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73550/133889 blocks (54.9%), 0 events +2026-02-04T19:17:09.253260Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73560/133889 blocks (54.9%), 0 events +2026-02-04T19:17:09.448548Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73570/133889 blocks (54.9%), 0 events +2026-02-04T19:17:09.635882Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73580/133889 blocks (55.0%), 0 events +2026-02-04T19:17:09.808018Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73590/133889 blocks (55.0%), 0 events +2026-02-04T19:17:09.975703Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73600/133889 blocks (55.0%), 0 events +2026-02-04T19:17:10.221412Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73610/133889 blocks (55.0%), 0 events +2026-02-04T19:17:10.393502Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73620/133889 blocks (55.0%), 0 events +2026-02-04T19:17:10.686215Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73630/133889 blocks (55.0%), 0 events +2026-02-04T19:17:10.796674Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73640/133889 blocks (55.0%), 0 events +2026-02-04T19:17:11.028929Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73650/133889 blocks (55.0%), 0 events +2026-02-04T19:17:11.192517Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73660/133889 blocks (55.0%), 0 events +2026-02-04T19:17:11.447010Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73670/133889 blocks (55.0%), 0 events +2026-02-04T19:17:11.685326Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73680/133889 blocks (55.0%), 0 events +2026-02-04T19:17:11.829634Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73690/133889 blocks (55.0%), 0 events +2026-02-04T19:17:11.990430Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73700/133889 blocks (55.0%), 0 events +2026-02-04T19:17:12.260297Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73710/133889 blocks (55.1%), 0 events +2026-02-04T19:17:12.419513Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73720/133889 blocks (55.1%), 0 events +2026-02-04T19:17:12.605526Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73730/133889 blocks (55.1%), 0 events +2026-02-04T19:17:12.826475Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73740/133889 blocks (55.1%), 0 events +2026-02-04T19:17:13.002038Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73750/133889 blocks (55.1%), 0 events +2026-02-04T19:17:13.313371Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73760/133889 blocks (55.1%), 0 events +2026-02-04T19:17:13.366324Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73770/133889 blocks (55.1%), 0 events +2026-02-04T19:17:13.597287Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73780/133889 blocks (55.1%), 0 events +2026-02-04T19:17:13.815062Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73790/133889 blocks (55.1%), 0 events +2026-02-04T19:17:14.037088Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73800/133889 blocks (55.1%), 0 events +2026-02-04T19:17:14.175343Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73810/133889 blocks (55.1%), 0 events +2026-02-04T19:17:14.365197Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73820/133889 blocks (55.1%), 0 events +2026-02-04T19:17:14.573886Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73830/133889 blocks (55.1%), 0 events +2026-02-04T19:17:14.867862Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73840/133889 blocks (55.1%), 0 events +2026-02-04T19:17:15.039044Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73850/133889 blocks (55.2%), 0 events +2026-02-04T19:17:15.256239Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73860/133889 blocks (55.2%), 0 events +2026-02-04T19:17:15.397783Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73870/133889 blocks (55.2%), 0 events +2026-02-04T19:17:15.599497Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73880/133889 blocks (55.2%), 0 events +2026-02-04T19:17:15.787320Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73890/133889 blocks (55.2%), 0 events +2026-02-04T19:17:16.027761Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73900/133889 blocks (55.2%), 0 events +2026-02-04T19:17:16.174971Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73910/133889 blocks (55.2%), 0 events +2026-02-04T19:17:16.432083Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73920/133889 blocks (55.2%), 0 events +2026-02-04T19:17:16.605095Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73930/133889 blocks (55.2%), 0 events +2026-02-04T19:17:16.784657Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73940/133889 blocks (55.2%), 0 events +2026-02-04T19:17:16.989274Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73950/133889 blocks (55.2%), 0 events +2026-02-04T19:17:17.166913Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73960/133889 blocks (55.2%), 0 events +2026-02-04T19:17:17.484166Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73970/133889 blocks (55.2%), 0 events +2026-02-04T19:17:17.566208Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73980/133889 blocks (55.3%), 0 events +2026-02-04T19:17:17.823650Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73990/133889 blocks (55.3%), 0 events +2026-02-04T19:17:18.032399Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74000/133889 blocks (55.3%), 0 events +2026-02-04T19:17:18.245846Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74010/133889 blocks (55.3%), 0 events +2026-02-04T19:17:18.404271Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74020/133889 blocks (55.3%), 0 events +2026-02-04T19:17:18.607344Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74030/133889 blocks (55.3%), 0 events +2026-02-04T19:17:18.822833Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74040/133889 blocks (55.3%), 0 events +2026-02-04T19:17:19.060441Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74050/133889 blocks (55.3%), 0 events +2026-02-04T19:17:19.208672Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74060/133889 blocks (55.3%), 0 events +2026-02-04T19:17:19.403647Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74070/133889 blocks (55.3%), 0 events +2026-02-04T19:17:19.590955Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74080/133889 blocks (55.3%), 0 events +2026-02-04T19:17:19.854030Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74090/133889 blocks (55.3%), 0 events +2026-02-04T19:17:20.075577Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74100/133889 blocks (55.3%), 0 events +2026-02-04T19:17:20.221897Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74110/133889 blocks (55.4%), 0 events +2026-02-04T19:17:20.389834Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74120/133889 blocks (55.4%), 0 events +2026-02-04T19:17:20.633077Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74130/133889 blocks (55.4%), 0 events +2026-02-04T19:17:20.856919Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74140/133889 blocks (55.4%), 0 events +2026-02-04T19:17:21.120840Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74150/133889 blocks (55.4%), 0 events +2026-02-04T19:17:21.161351Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74160/133889 blocks (55.4%), 0 events +2026-02-04T19:17:21.411441Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74170/133889 blocks (55.4%), 0 events +2026-02-04T19:17:21.680583Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74180/133889 blocks (55.4%), 0 events +2026-02-04T19:17:21.825995Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74190/133889 blocks (55.4%), 0 events +2026-02-04T19:17:22.064260Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74200/133889 blocks (55.4%), 0 events +2026-02-04T19:17:22.205325Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74210/133889 blocks (55.4%), 0 events +2026-02-04T19:17:22.411994Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74220/133889 blocks (55.4%), 0 events +2026-02-04T19:17:22.590544Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74230/133889 blocks (55.4%), 0 events +2026-02-04T19:17:22.803525Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74240/133889 blocks (55.4%), 0 events +2026-02-04T19:17:23.013405Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74250/133889 blocks (55.5%), 0 events +2026-02-04T19:17:23.252699Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74260/133889 blocks (55.5%), 0 events +2026-02-04T19:17:23.422129Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74270/133889 blocks (55.5%), 0 events +2026-02-04T19:17:23.601651Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74280/133889 blocks (55.5%), 0 events +2026-02-04T19:17:23.803698Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74290/133889 blocks (55.5%), 0 events +2026-02-04T19:17:24.047496Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74300/133889 blocks (55.5%), 0 events +2026-02-04T19:17:24.305501Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74310/133889 blocks (55.5%), 0 events +2026-02-04T19:17:24.434010Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74320/133889 blocks (55.5%), 0 events +2026-02-04T19:17:24.877829Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74330/133889 blocks (55.5%), 0 events +2026-02-04T19:17:24.916018Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74340/133889 blocks (55.5%), 0 events +2026-02-04T19:17:24.950028Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74350/133889 blocks (55.5%), 0 events +2026-02-04T19:17:25.316726Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74360/133889 blocks (55.5%), 0 events +2026-02-04T19:17:25.358326Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74370/133889 blocks (55.5%), 0 events +2026-02-04T19:17:25.560019Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74380/133889 blocks (55.6%), 0 events +2026-02-04T19:17:25.878992Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74390/133889 blocks (55.6%), 0 events +2026-02-04T19:17:26.024418Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74400/133889 blocks (55.6%), 0 events +2026-02-04T19:17:26.232490Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74410/133889 blocks (55.6%), 0 events +2026-02-04T19:17:26.405770Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74420/133889 blocks (55.6%), 0 events +2026-02-04T19:17:26.613478Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74430/133889 blocks (55.6%), 0 events +2026-02-04T19:17:26.789431Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74440/133889 blocks (55.6%), 0 events +2026-02-04T19:17:26.989894Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74450/133889 blocks (55.6%), 0 events +2026-02-04T19:17:27.213618Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74460/133889 blocks (55.6%), 0 events +2026-02-04T19:17:27.445417Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74470/133889 blocks (55.6%), 0 events +2026-02-04T19:17:27.626512Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74480/133889 blocks (55.6%), 0 events +2026-02-04T19:17:27.836500Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74490/133889 blocks (55.6%), 0 events +2026-02-04T19:17:28.027522Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74500/133889 blocks (55.6%), 0 events +2026-02-04T19:17:28.236360Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74510/133889 blocks (55.7%), 0 events +2026-02-04T19:17:28.501315Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74520/133889 blocks (55.7%), 0 events +2026-02-04T19:17:28.620483Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74530/133889 blocks (55.7%), 0 events +2026-02-04T19:17:28.854396Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74540/133889 blocks (55.7%), 0 events +2026-02-04T19:17:29.022843Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74550/133889 blocks (55.7%), 0 events +2026-02-04T19:17:29.257876Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74560/133889 blocks (55.7%), 0 events +2026-02-04T19:17:29.508922Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74570/133889 blocks (55.7%), 0 events +2026-02-04T19:17:29.591389Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74580/133889 blocks (55.7%), 0 events +2026-02-04T19:17:29.784616Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74590/133889 blocks (55.7%), 0 events +2026-02-04T19:17:30.068397Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74600/133889 blocks (55.7%), 0 events +2026-02-04T19:17:30.200027Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74610/133889 blocks (55.7%), 0 events +2026-02-04T19:17:30.558180Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74620/133889 blocks (55.7%), 0 events +2026-02-04T19:17:30.596067Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74630/133889 blocks (55.7%), 0 events +2026-02-04T19:17:30.770234Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74640/133889 blocks (55.7%), 0 events +2026-02-04T19:17:31.084525Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74650/133889 blocks (55.8%), 0 events +2026-02-04T19:17:31.230064Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74660/133889 blocks (55.8%), 0 events +2026-02-04T19:17:31.377724Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74670/133889 blocks (55.8%), 0 events +2026-02-04T19:17:31.647584Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74680/133889 blocks (55.8%), 0 events +2026-02-04T19:17:31.808344Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74690/133889 blocks (55.8%), 0 events +2026-02-04T19:17:31.994130Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74700/133889 blocks (55.8%), 0 events +2026-02-04T19:17:32.163370Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74710/133889 blocks (55.8%), 0 events +2026-02-04T19:17:32.444539Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74720/133889 blocks (55.8%), 0 events +2026-02-04T19:17:32.691585Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74730/133889 blocks (55.8%), 0 events +2026-02-04T19:17:32.821374Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74740/133889 blocks (55.8%), 0 events +2026-02-04T19:17:32.971224Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74750/133889 blocks (55.8%), 0 events +2026-02-04T19:17:33.217457Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74760/133889 blocks (55.8%), 0 events +2026-02-04T19:17:33.405312Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74770/133889 blocks (55.8%), 0 events +2026-02-04T19:17:33.703928Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74780/133889 blocks (55.9%), 0 events +2026-02-04T19:17:33.770379Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74790/133889 blocks (55.9%), 0 events +2026-02-04T19:17:33.989372Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74800/133889 blocks (55.9%), 0 events +2026-02-04T19:17:34.289239Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74810/133889 blocks (55.9%), 0 events +2026-02-04T19:17:34.409836Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74820/133889 blocks (55.9%), 0 events +2026-02-04T19:17:34.618202Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74830/133889 blocks (55.9%), 0 events +2026-02-04T19:17:34.806544Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74840/133889 blocks (55.9%), 0 events +2026-02-04T19:17:35.014454Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74850/133889 blocks (55.9%), 0 events +2026-02-04T19:17:35.276700Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74860/133889 blocks (55.9%), 0 events +2026-02-04T19:17:35.417992Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74870/133889 blocks (55.9%), 0 events +2026-02-04T19:17:35.601973Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74880/133889 blocks (55.9%), 0 events +2026-02-04T19:17:35.860000Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74890/133889 blocks (55.9%), 0 events +2026-02-04T19:17:36.009794Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74900/133889 blocks (55.9%), 0 events +2026-02-04T19:17:36.324967Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74910/133889 blocks (55.9%), 0 events +2026-02-04T19:17:36.378052Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74920/133889 blocks (56.0%), 0 events +2026-02-04T19:17:36.632470Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74930/133889 blocks (56.0%), 0 events +2026-02-04T19:17:36.897438Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74940/133889 blocks (56.0%), 0 events +2026-02-04T19:17:36.995738Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74950/133889 blocks (56.0%), 0 events +2026-02-04T19:17:37.234434Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74960/133889 blocks (56.0%), 0 events +2026-02-04T19:17:37.461031Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74970/133889 blocks (56.0%), 0 events +2026-02-04T19:17:37.633850Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74980/133889 blocks (56.0%), 0 events +2026-02-04T19:17:37.797307Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74990/133889 blocks (56.0%), 0 events +2026-02-04T19:17:38.022369Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75000/133889 blocks (56.0%), 0 events +2026-02-04T19:17:38.167622Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75010/133889 blocks (56.0%), 0 events +2026-02-04T19:17:38.456457Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75020/133889 blocks (56.0%), 0 events +2026-02-04T19:17:38.584691Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75030/133889 blocks (56.0%), 0 events +2026-02-04T19:17:38.771832Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75040/133889 blocks (56.0%), 0 events +2026-02-04T19:17:38.980814Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75050/133889 blocks (56.1%), 0 events +2026-02-04T19:17:39.185104Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75060/133889 blocks (56.1%), 0 events +2026-02-04T19:17:39.365738Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75070/133889 blocks (56.1%), 0 events +2026-02-04T19:17:39.652994Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75080/133889 blocks (56.1%), 0 events +2026-02-04T19:17:39.848388Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75090/133889 blocks (56.1%), 0 events +2026-02-04T19:17:40.036512Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75100/133889 blocks (56.1%), 0 events +2026-02-04T19:17:40.186269Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75110/133889 blocks (56.1%), 0 events +2026-02-04T19:17:40.403765Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75120/133889 blocks (56.1%), 0 events +2026-02-04T19:17:40.659979Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75130/133889 blocks (56.1%), 0 events +2026-02-04T19:17:40.851069Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75140/133889 blocks (56.1%), 0 events +2026-02-04T19:17:41.045406Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75150/133889 blocks (56.1%), 0 events +2026-02-04T19:17:41.181622Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75160/133889 blocks (56.1%), 0 events +2026-02-04T19:17:41.366723Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75170/133889 blocks (56.1%), 0 events +2026-02-04T19:17:41.649081Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75180/133889 blocks (56.2%), 0 events +2026-02-04T19:17:41.849702Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75190/133889 blocks (56.2%), 0 events +2026-02-04T19:17:42.091885Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75200/133889 blocks (56.2%), 0 events +2026-02-04T19:17:42.157720Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75210/133889 blocks (56.2%), 0 events +2026-02-04T19:17:42.365763Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75220/133889 blocks (56.2%), 0 events +2026-02-04T19:17:42.649943Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75230/133889 blocks (56.2%), 0 events +2026-02-04T19:17:42.775603Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75240/133889 blocks (56.2%), 0 events +2026-02-04T19:17:42.979202Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75250/133889 blocks (56.2%), 0 events +2026-02-04T19:17:43.202029Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75260/133889 blocks (56.2%), 0 events +2026-02-04T19:17:43.453114Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75270/133889 blocks (56.2%), 0 events +2026-02-04T19:17:43.699863Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75280/133889 blocks (56.2%), 0 events +2026-02-04T19:17:43.760341Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75290/133889 blocks (56.2%), 0 events +2026-02-04T19:17:44.027390Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75300/133889 blocks (56.2%), 0 events +2026-02-04T19:17:44.222243Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75310/133889 blocks (56.2%), 0 events +2026-02-04T19:17:44.441599Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75320/133889 blocks (56.3%), 0 events +2026-02-04T19:17:44.585236Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75330/133889 blocks (56.3%), 0 events +2026-02-04T19:17:44.802186Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75340/133889 blocks (56.3%), 0 events +2026-02-04T19:17:45.008604Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75350/133889 blocks (56.3%), 0 events +2026-02-04T19:17:45.237105Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75360/133889 blocks (56.3%), 0 events +2026-02-04T19:17:45.441867Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75370/133889 blocks (56.3%), 0 events +2026-02-04T19:17:45.658595Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75380/133889 blocks (56.3%), 0 events +2026-02-04T19:17:45.792970Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75390/133889 blocks (56.3%), 0 events +2026-02-04T19:17:46.011953Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75400/133889 blocks (56.3%), 0 events +2026-02-04T19:17:46.320439Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75410/133889 blocks (56.3%), 0 events +2026-02-04T19:17:46.363556Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75420/133889 blocks (56.3%), 0 events +2026-02-04T19:17:46.574938Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75430/133889 blocks (56.3%), 0 events +2026-02-04T19:17:46.849142Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75440/133889 blocks (56.3%), 0 events +2026-02-04T19:17:46.987278Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75450/133889 blocks (56.4%), 0 events +2026-02-04T19:17:47.210640Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75460/133889 blocks (56.4%), 0 events +2026-02-04T19:17:47.440384Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75470/133889 blocks (56.4%), 0 events +2026-02-04T19:17:47.592776Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75480/133889 blocks (56.4%), 0 events +2026-02-04T19:17:47.861172Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75490/133889 blocks (56.4%), 0 events +2026-02-04T19:17:48.038555Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75500/133889 blocks (56.4%), 0 events +2026-02-04T19:17:48.251223Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75510/133889 blocks (56.4%), 0 events +2026-02-04T19:17:48.451008Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75520/133889 blocks (56.4%), 0 events +2026-02-04T19:17:48.601227Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75530/133889 blocks (56.4%), 0 events +2026-02-04T19:17:48.776749Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75540/133889 blocks (56.4%), 0 events +2026-02-04T19:17:48.989453Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75550/133889 blocks (56.4%), 0 events +2026-02-04T19:17:49.201868Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75560/133889 blocks (56.4%), 0 events +2026-02-04T19:17:49.468822Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75570/133889 blocks (56.4%), 0 events +2026-02-04T19:17:49.574227Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75580/133889 blocks (56.4%), 0 events +2026-02-04T19:17:49.782494Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75590/133889 blocks (56.5%), 0 events +2026-02-04T19:17:49.991041Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75600/133889 blocks (56.5%), 0 events +2026-02-04T19:17:50.249795Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75610/133889 blocks (56.5%), 0 events +2026-02-04T19:17:50.528801Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75620/133889 blocks (56.5%), 0 events +2026-02-04T19:17:50.569904Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75630/133889 blocks (56.5%), 0 events +2026-02-04T19:17:50.786502Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75640/133889 blocks (56.5%), 0 events +2026-02-04T19:17:51.036130Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75650/133889 blocks (56.5%), 0 events +2026-02-04T19:17:51.246355Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75660/133889 blocks (56.5%), 0 events +2026-02-04T19:17:51.529492Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75670/133889 blocks (56.5%), 0 events +2026-02-04T19:17:51.568889Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75680/133889 blocks (56.5%), 0 events +2026-02-04T19:17:51.761446Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75690/133889 blocks (56.5%), 0 events +2026-02-04T19:17:52.096945Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75700/133889 blocks (56.5%), 0 events +2026-02-04T19:17:52.258368Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75710/133889 blocks (56.5%), 0 events +2026-02-04T19:17:52.394933Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75720/133889 blocks (56.6%), 0 events +2026-02-04T19:17:52.610174Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75730/133889 blocks (56.6%), 0 events +2026-02-04T19:17:52.811861Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75740/133889 blocks (56.6%), 0 events +2026-02-04T19:17:53.106476Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75750/133889 blocks (56.6%), 0 events +2026-02-04T19:17:53.244155Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75760/133889 blocks (56.6%), 0 events +2026-02-04T19:17:53.446904Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75770/133889 blocks (56.6%), 0 events +2026-02-04T19:17:53.666819Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75780/133889 blocks (56.6%), 0 events +2026-02-04T19:17:53.774429Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75790/133889 blocks (56.6%), 0 events +2026-02-04T19:17:54.038104Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75800/133889 blocks (56.6%), 0 events +2026-02-04T19:17:54.186452Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75810/133889 blocks (56.6%), 0 events +2026-02-04T19:17:54.424102Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75820/133889 blocks (56.6%), 0 events +2026-02-04T19:17:54.708525Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75830/133889 blocks (56.6%), 0 events +2026-02-04T19:17:54.819427Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75840/133889 blocks (56.6%), 0 events +2026-02-04T19:17:55.062748Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75850/133889 blocks (56.7%), 0 events +2026-02-04T19:17:55.265141Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75860/133889 blocks (56.7%), 0 events +2026-02-04T19:17:55.420146Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75870/133889 blocks (56.7%), 0 events +2026-02-04T19:17:55.623607Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75880/133889 blocks (56.7%), 0 events +2026-02-04T19:17:55.792532Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75890/133889 blocks (56.7%), 0 events +2026-02-04T19:17:55.974953Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75900/133889 blocks (56.7%), 0 events +2026-02-04T19:17:56.248204Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75910/133889 blocks (56.7%), 0 events +2026-02-04T19:17:56.443252Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75920/133889 blocks (56.7%), 0 events +2026-02-04T19:17:56.609138Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75930/133889 blocks (56.7%), 0 events +2026-02-04T19:17:56.850580Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75940/133889 blocks (56.7%), 0 events +2026-02-04T19:17:57.017442Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75950/133889 blocks (56.7%), 0 events +2026-02-04T19:17:57.191608Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75960/133889 blocks (56.7%), 0 events +2026-02-04T19:17:57.454770Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75970/133889 blocks (56.7%), 0 events +2026-02-04T19:17:57.575697Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75980/133889 blocks (56.7%), 0 events +2026-02-04T19:17:57.861844Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75990/133889 blocks (56.8%), 0 events +2026-02-04T19:17:58.036985Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76000/133889 blocks (56.8%), 0 events +2026-02-04T19:17:58.224128Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76010/133889 blocks (56.8%), 0 events +2026-02-04T19:17:58.416402Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76020/133889 blocks (56.8%), 0 events +2026-02-04T19:17:58.596068Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76030/133889 blocks (56.8%), 0 events +2026-02-04T19:17:58.764980Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76040/133889 blocks (56.8%), 0 events +2026-02-04T19:17:58.992356Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76050/133889 blocks (56.8%), 0 events +2026-02-04T19:17:59.185415Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76060/133889 blocks (56.8%), 0 events +2026-02-04T19:17:59.424306Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76070/133889 blocks (56.8%), 0 events +2026-02-04T19:17:59.624257Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76080/133889 blocks (56.8%), 0 events +2026-02-04T19:17:59.820759Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76090/133889 blocks (56.8%), 0 events +2026-02-04T19:17:59.998904Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76100/133889 blocks (56.8%), 0 events +2026-02-04T19:18:00.231420Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76110/133889 blocks (56.8%), 0 events +2026-02-04T19:18:00.472279Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76120/133889 blocks (56.9%), 0 events +2026-02-04T19:18:00.592406Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76130/133889 blocks (56.9%), 0 events +2026-02-04T19:18:00.857045Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76140/133889 blocks (56.9%), 0 events +2026-02-04T19:18:00.997386Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76150/133889 blocks (56.9%), 0 events +2026-02-04T19:18:01.171330Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76160/133889 blocks (56.9%), 0 events +2026-02-04T19:18:01.382903Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76170/133889 blocks (56.9%), 0 events +2026-02-04T19:18:01.567353Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76180/133889 blocks (56.9%), 0 events +2026-02-04T19:18:01.815147Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76190/133889 blocks (56.9%), 0 events +2026-02-04T19:18:02.054574Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76200/133889 blocks (56.9%), 0 events +2026-02-04T19:18:02.184037Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76210/133889 blocks (56.9%), 0 events +2026-02-04T19:18:02.415947Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76220/133889 blocks (56.9%), 0 events +2026-02-04T19:18:02.573055Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76230/133889 blocks (56.9%), 0 events +2026-02-04T19:18:02.849118Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76240/133889 blocks (56.9%), 0 events +2026-02-04T19:18:02.969828Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76250/133889 blocks (56.9%), 0 events +2026-02-04T19:18:03.232669Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76260/133889 blocks (57.0%), 0 events +2026-02-04T19:18:03.424058Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76270/133889 blocks (57.0%), 0 events +2026-02-04T19:18:03.655990Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76280/133889 blocks (57.0%), 0 events +2026-02-04T19:18:03.820091Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76290/133889 blocks (57.0%), 0 events +2026-02-04T19:18:03.992361Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76300/133889 blocks (57.0%), 0 events +2026-02-04T19:18:04.226112Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76310/133889 blocks (57.0%), 0 events +2026-02-04T19:18:04.379780Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76320/133889 blocks (57.0%), 0 events +2026-02-04T19:18:04.667348Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76330/133889 blocks (57.0%), 0 events +2026-02-04T19:18:04.839827Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76340/133889 blocks (57.0%), 0 events +2026-02-04T19:18:04.966655Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76350/133889 blocks (57.0%), 0 events +2026-02-04T19:18:05.196023Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76360/133889 blocks (57.0%), 0 events +2026-02-04T19:18:05.449603Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76370/133889 blocks (57.0%), 0 events +2026-02-04T19:18:05.685858Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76380/133889 blocks (57.0%), 0 events +2026-02-04T19:18:05.848325Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76390/133889 blocks (57.1%), 0 events +2026-02-04T19:18:06.058240Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76400/133889 blocks (57.1%), 0 events +2026-02-04T19:18:06.242173Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76410/133889 blocks (57.1%), 0 events +2026-02-04T19:18:06.456506Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76420/133889 blocks (57.1%), 0 events +2026-02-04T19:18:06.635163Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76430/133889 blocks (57.1%), 0 events +2026-02-04T19:18:06.794159Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76440/133889 blocks (57.1%), 0 events +2026-02-04T19:18:06.994682Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76450/133889 blocks (57.1%), 0 events +2026-02-04T19:18:07.258222Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76460/133889 blocks (57.1%), 0 events +2026-02-04T19:18:07.418308Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76470/133889 blocks (57.1%), 0 events +2026-02-04T19:18:07.568686Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76480/133889 blocks (57.1%), 0 events +2026-02-04T19:18:07.813096Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76490/133889 blocks (57.1%), 0 events +2026-02-04T19:18:08.021425Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76500/133889 blocks (57.1%), 0 events +2026-02-04T19:18:08.335535Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76510/133889 blocks (57.1%), 0 events +2026-02-04T19:18:08.368886Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76520/133889 blocks (57.2%), 0 events +2026-02-04T19:18:08.644762Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76530/133889 blocks (57.2%), 0 events +2026-02-04T19:18:08.863286Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76540/133889 blocks (57.2%), 0 events +2026-02-04T19:18:08.993617Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76550/133889 blocks (57.2%), 0 events +2026-02-04T19:18:09.190476Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76560/133889 blocks (57.2%), 0 events +2026-02-04T19:18:09.424045Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76570/133889 blocks (57.2%), 0 events +2026-02-04T19:18:09.609449Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76580/133889 blocks (57.2%), 0 events +2026-02-04T19:18:09.887622Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76590/133889 blocks (57.2%), 0 events +2026-02-04T19:18:09.993425Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76600/133889 blocks (57.2%), 0 events +2026-02-04T19:18:10.254674Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76610/133889 blocks (57.2%), 0 events +2026-02-04T19:18:10.435363Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76620/133889 blocks (57.2%), 0 events +2026-02-04T19:18:10.597041Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76630/133889 blocks (57.2%), 0 events +2026-02-04T19:18:10.788267Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76640/133889 blocks (57.2%), 0 events +2026-02-04T19:18:11.001153Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76650/133889 blocks (57.2%), 0 events +2026-02-04T19:18:11.226271Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76660/133889 blocks (57.3%), 0 events +2026-02-04T19:18:11.449644Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76670/133889 blocks (57.3%), 0 events +2026-02-04T19:18:11.634080Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76680/133889 blocks (57.3%), 0 events +2026-02-04T19:18:11.823614Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76690/133889 blocks (57.3%), 0 events +2026-02-04T19:18:12.008251Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76700/133889 blocks (57.3%), 0 events +2026-02-04T19:18:12.246467Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76710/133889 blocks (57.3%), 0 events +2026-02-04T19:18:12.499837Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76720/133889 blocks (57.3%), 0 events +2026-02-04T19:18:12.574213Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76730/133889 blocks (57.3%), 0 events +2026-02-04T19:18:12.826524Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76740/133889 blocks (57.3%), 0 events +2026-02-04T19:18:13.024909Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76750/133889 blocks (57.3%), 0 events +2026-02-04T19:18:13.224157Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76760/133889 blocks (57.3%), 0 events +2026-02-04T19:18:13.401700Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76770/133889 blocks (57.3%), 0 events +2026-02-04T19:18:13.605804Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76780/133889 blocks (57.3%), 0 events +2026-02-04T19:18:13.775558Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76790/133889 blocks (57.4%), 0 events +2026-02-04T19:18:14.103840Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76800/133889 blocks (57.4%), 0 events +2026-02-04T19:18:14.235903Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76810/133889 blocks (57.4%), 0 events +2026-02-04T19:18:14.422480Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76820/133889 blocks (57.4%), 0 events +2026-02-04T19:18:14.630419Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76830/133889 blocks (57.4%), 0 events +2026-02-04T19:18:14.793610Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76840/133889 blocks (57.4%), 0 events +2026-02-04T19:18:15.000757Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76850/133889 blocks (57.4%), 0 events +2026-02-04T19:18:15.170244Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76860/133889 blocks (57.4%), 0 events +2026-02-04T19:18:15.430110Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76870/133889 blocks (57.4%), 0 events +2026-02-04T19:18:15.644673Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76880/133889 blocks (57.4%), 0 events +2026-02-04T19:18:15.839256Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76890/133889 blocks (57.4%), 0 events +2026-02-04T19:18:15.966682Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76900/133889 blocks (57.4%), 0 events +2026-02-04T19:18:16.204553Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76910/133889 blocks (57.4%), 0 events +2026-02-04T19:18:16.435081Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76920/133889 blocks (57.5%), 0 events +2026-02-04T19:18:16.693039Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76930/133889 blocks (57.5%), 0 events +2026-02-04T19:18:16.783970Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76940/133889 blocks (57.5%), 0 events +2026-02-04T19:18:17.019810Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76950/133889 blocks (57.5%), 0 events +2026-02-04T19:18:17.253821Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76960/133889 blocks (57.5%), 0 events +2026-02-04T19:18:17.387286Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76970/133889 blocks (57.5%), 0 events +2026-02-04T19:18:17.590828Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76980/133889 blocks (57.5%), 0 events +2026-02-04T19:18:17.817147Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76990/133889 blocks (57.5%), 0 events +2026-02-04T19:18:18.048162Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77000/133889 blocks (57.5%), 0 events +2026-02-04T19:18:18.174150Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77010/133889 blocks (57.5%), 0 events +2026-02-04T19:18:18.427437Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77020/133889 blocks (57.5%), 0 events +2026-02-04T19:18:18.635543Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77030/133889 blocks (57.5%), 0 events +2026-02-04T19:18:18.822217Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77040/133889 blocks (57.5%), 0 events +2026-02-04T19:18:18.992337Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77050/133889 blocks (57.5%), 0 events +2026-02-04T19:18:19.315184Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77060/133889 blocks (57.6%), 0 events +2026-02-04T19:18:19.356289Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77070/133889 blocks (57.6%), 0 events +2026-02-04T19:18:19.611053Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77080/133889 blocks (57.6%), 0 events +2026-02-04T19:18:19.873956Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77090/133889 blocks (57.6%), 0 events +2026-02-04T19:18:20.025506Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77100/133889 blocks (57.6%), 0 events +2026-02-04T19:18:20.232645Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77110/133889 blocks (57.6%), 0 events +2026-02-04T19:18:20.406230Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77120/133889 blocks (57.6%), 0 events +2026-02-04T19:18:20.621714Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77130/133889 blocks (57.6%), 0 events +2026-02-04T19:18:20.888459Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77140/133889 blocks (57.6%), 0 events +2026-02-04T19:18:21.059412Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77150/133889 blocks (57.6%), 0 events +2026-02-04T19:18:21.242372Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77160/133889 blocks (57.6%), 0 events +2026-02-04T19:18:21.446908Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77170/133889 blocks (57.6%), 0 events +2026-02-04T19:18:21.657222Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77180/133889 blocks (57.6%), 0 events +2026-02-04T19:18:21.826992Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77190/133889 blocks (57.7%), 0 events +2026-02-04T19:18:22.015355Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77200/133889 blocks (57.7%), 0 events +2026-02-04T19:18:22.213270Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77210/133889 blocks (57.7%), 0 events +2026-02-04T19:18:22.492903Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77220/133889 blocks (57.7%), 0 events +2026-02-04T19:18:22.592927Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77230/133889 blocks (57.7%), 0 events +2026-02-04T19:18:22.836508Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77240/133889 blocks (57.7%), 0 events +2026-02-04T19:18:23.053432Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77250/133889 blocks (57.7%), 0 events +2026-02-04T19:18:23.194216Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77260/133889 blocks (57.7%), 0 events +2026-02-04T19:18:23.399574Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77270/133889 blocks (57.7%), 0 events +2026-02-04T19:18:23.622327Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77280/133889 blocks (57.7%), 0 events +2026-02-04T19:18:23.796995Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77290/133889 blocks (57.7%), 0 events +2026-02-04T19:18:24.066361Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77300/133889 blocks (57.7%), 0 events +2026-02-04T19:18:24.175776Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77310/133889 blocks (57.7%), 0 events +2026-02-04T19:18:24.395614Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77320/133889 blocks (57.7%), 0 events +2026-02-04T19:18:24.611130Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77330/133889 blocks (57.8%), 0 events +2026-02-04T19:18:24.836767Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77340/133889 blocks (57.8%), 0 events +2026-02-04T19:18:25.081694Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77350/133889 blocks (57.8%), 0 events +2026-02-04T19:18:25.238227Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77360/133889 blocks (57.8%), 0 events +2026-02-04T19:18:25.378356Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77370/133889 blocks (57.8%), 0 events +2026-02-04T19:18:25.641623Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77380/133889 blocks (57.8%), 0 events +2026-02-04T19:18:25.843454Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77390/133889 blocks (57.8%), 0 events +2026-02-04T19:18:26.036798Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77400/133889 blocks (57.8%), 0 events +2026-02-04T19:18:26.259807Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77410/133889 blocks (57.8%), 0 events +2026-02-04T19:18:26.374078Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77420/133889 blocks (57.8%), 0 events +2026-02-04T19:18:26.658176Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77430/133889 blocks (57.8%), 0 events +2026-02-04T19:18:26.838937Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77440/133889 blocks (57.8%), 0 events +2026-02-04T19:18:26.972961Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77450/133889 blocks (57.8%), 0 events +2026-02-04T19:18:27.249393Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77460/133889 blocks (57.9%), 0 events +2026-02-04T19:18:27.449815Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77470/133889 blocks (57.9%), 0 events +2026-02-04T19:18:27.703281Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77480/133889 blocks (57.9%), 0 events +2026-02-04T19:18:27.857633Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77490/133889 blocks (57.9%), 0 events +2026-02-04T19:18:28.054964Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77500/133889 blocks (57.9%), 0 events +2026-02-04T19:18:28.257639Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77510/133889 blocks (57.9%), 0 events +2026-02-04T19:18:28.381489Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77520/133889 blocks (57.9%), 0 events +2026-02-04T19:18:28.634230Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77530/133889 blocks (57.9%), 0 events +2026-02-04T19:18:28.868343Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77540/133889 blocks (57.9%), 0 events +2026-02-04T19:18:29.012466Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77550/133889 blocks (57.9%), 0 events +2026-02-04T19:18:29.316740Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77560/133889 blocks (57.9%), 0 events +2026-02-04T19:18:29.355609Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77570/133889 blocks (57.9%), 0 events +2026-02-04T19:18:29.634500Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77580/133889 blocks (57.9%), 0 events +2026-02-04T19:18:29.836031Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77590/133889 blocks (58.0%), 0 events +2026-02-04T19:18:29.992071Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77600/133889 blocks (58.0%), 0 events +2026-02-04T19:18:30.326718Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77610/133889 blocks (58.0%), 0 events +2026-02-04T19:18:30.369843Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77620/133889 blocks (58.0%), 0 events +2026-02-04T19:18:30.599349Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77630/133889 blocks (58.0%), 0 events +2026-02-04T19:18:30.878226Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77640/133889 blocks (58.0%), 0 events +2026-02-04T19:18:31.057712Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77650/133889 blocks (58.0%), 0 events +2026-02-04T19:18:31.174832Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77660/133889 blocks (58.0%), 0 events +2026-02-04T19:18:31.413156Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77670/133889 blocks (58.0%), 0 events +2026-02-04T19:18:31.651950Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77680/133889 blocks (58.0%), 0 events +2026-02-04T19:18:31.899008Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77690/133889 blocks (58.0%), 0 events +2026-02-04T19:18:32.030060Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77700/133889 blocks (58.0%), 0 events +2026-02-04T19:18:32.163457Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77710/133889 blocks (58.0%), 0 events +2026-02-04T19:18:32.456841Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77720/133889 blocks (58.0%), 0 events +2026-02-04T19:18:32.583212Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77730/133889 blocks (58.1%), 0 events +2026-02-04T19:18:32.764475Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77740/133889 blocks (58.1%), 0 events +2026-02-04T19:18:33.023056Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77750/133889 blocks (58.1%), 0 events +2026-02-04T19:18:33.253704Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77760/133889 blocks (58.1%), 0 events +2026-02-04T19:18:33.510469Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77770/133889 blocks (58.1%), 0 events +2026-02-04T19:18:33.648979Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77780/133889 blocks (58.1%), 0 events +2026-02-04T19:18:33.764953Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77790/133889 blocks (58.1%), 0 events +2026-02-04T19:18:34.022702Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77800/133889 blocks (58.1%), 0 events +2026-02-04T19:18:34.226011Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77810/133889 blocks (58.1%), 0 events +2026-02-04T19:18:34.420534Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77820/133889 blocks (58.1%), 0 events +2026-02-04T19:18:34.605387Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77830/133889 blocks (58.1%), 0 events +2026-02-04T19:18:34.768543Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77840/133889 blocks (58.1%), 0 events +2026-02-04T19:18:35.078940Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77850/133889 blocks (58.1%), 0 events +2026-02-04T19:18:35.277814Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77860/133889 blocks (58.2%), 0 events +2026-02-04T19:18:35.450315Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77870/133889 blocks (58.2%), 0 events +2026-02-04T19:18:35.610615Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77880/133889 blocks (58.2%), 0 events +2026-02-04T19:18:35.976161Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77890/133889 blocks (58.2%), 0 events +2026-02-04T19:18:36.089670Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77900/133889 blocks (58.2%), 0 events +2026-02-04T19:18:36.185666Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77910/133889 blocks (58.2%), 0 events +2026-02-04T19:18:36.383406Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77920/133889 blocks (58.2%), 0 events +2026-02-04T19:18:36.669648Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77930/133889 blocks (58.2%), 0 events +2026-02-04T19:18:36.844807Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77940/133889 blocks (58.2%), 0 events +2026-02-04T19:18:37.008687Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77950/133889 blocks (58.2%), 0 events +2026-02-04T19:18:37.235061Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77960/133889 blocks (58.2%), 0 events +2026-02-04T19:18:37.421747Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77970/133889 blocks (58.2%), 0 events +2026-02-04T19:18:37.565927Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77980/133889 blocks (58.2%), 0 events +2026-02-04T19:18:37.894773Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77990/133889 blocks (58.2%), 0 events +2026-02-04T19:18:38.058366Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78000/133889 blocks (58.3%), 0 events +2026-02-04T19:18:38.218948Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78010/133889 blocks (58.3%), 0 events +2026-02-04T19:18:38.417154Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78020/133889 blocks (58.3%), 0 events +2026-02-04T19:18:38.600416Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78030/133889 blocks (58.3%), 0 events +2026-02-04T19:18:38.909544Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78040/133889 blocks (58.3%), 0 events +2026-02-04T19:18:38.991773Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78050/133889 blocks (58.3%), 0 events +2026-02-04T19:18:39.269278Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78060/133889 blocks (58.3%), 0 events +2026-02-04T19:18:39.478338Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78070/133889 blocks (58.3%), 0 events +2026-02-04T19:18:39.605979Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78080/133889 blocks (58.3%), 0 events +2026-02-04T19:18:39.800981Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78090/133889 blocks (58.3%), 0 events +2026-02-04T19:18:39.993978Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78100/133889 blocks (58.3%), 0 events +2026-02-04T19:18:40.165733Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78110/133889 blocks (58.3%), 0 events +2026-02-04T19:18:40.372820Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78120/133889 blocks (58.3%), 0 events +2026-02-04T19:18:40.561404Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78130/133889 blocks (58.4%), 0 events +2026-02-04T19:18:40.848127Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78140/133889 blocks (58.4%), 0 events +2026-02-04T19:18:40.997805Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78150/133889 blocks (58.4%), 0 events +2026-02-04T19:18:41.188877Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78160/133889 blocks (58.4%), 0 events +2026-02-04T19:18:41.368212Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78170/133889 blocks (58.4%), 0 events +2026-02-04T19:18:41.589209Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78180/133889 blocks (58.4%), 0 events +2026-02-04T19:18:41.895530Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78190/133889 blocks (58.4%), 0 events +2026-02-04T19:18:41.977975Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78200/133889 blocks (58.4%), 0 events +2026-02-04T19:18:42.168143Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78210/133889 blocks (58.4%), 0 events +2026-02-04T19:18:42.433554Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78220/133889 blocks (58.4%), 0 events +2026-02-04T19:18:42.592703Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78230/133889 blocks (58.4%), 0 events +2026-02-04T19:18:42.800263Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78240/133889 blocks (58.4%), 0 events +2026-02-04T19:18:42.998305Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78250/133889 blocks (58.4%), 0 events +2026-02-04T19:18:43.231574Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78260/133889 blocks (58.5%), 0 events +2026-02-04T19:18:43.473907Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78270/133889 blocks (58.5%), 0 events +2026-02-04T19:18:43.664634Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78280/133889 blocks (58.5%), 0 events +2026-02-04T19:18:43.834328Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78290/133889 blocks (58.5%), 0 events +2026-02-04T19:18:44.004245Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78300/133889 blocks (58.5%), 0 events +2026-02-04T19:18:44.226647Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78310/133889 blocks (58.5%), 0 events +2026-02-04T19:18:44.480584Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78320/133889 blocks (58.5%), 0 events +2026-02-04T19:18:44.677898Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78330/133889 blocks (58.5%), 0 events +2026-02-04T19:18:44.802403Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78340/133889 blocks (58.5%), 0 events +2026-02-04T19:18:45.036831Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78350/133889 blocks (58.5%), 0 events +2026-02-04T19:18:45.233104Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78360/133889 blocks (58.5%), 0 events +2026-02-04T19:18:45.419169Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78370/133889 blocks (58.5%), 0 events +2026-02-04T19:18:45.606053Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78380/133889 blocks (58.5%), 0 events +2026-02-04T19:18:45.785524Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78390/133889 blocks (58.5%), 0 events +2026-02-04T19:18:46.054617Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78400/133889 blocks (58.6%), 0 events +2026-02-04T19:18:46.173080Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78410/133889 blocks (58.6%), 0 events +2026-02-04T19:18:46.446276Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78420/133889 blocks (58.6%), 0 events +2026-02-04T19:18:46.644139Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78430/133889 blocks (58.6%), 0 events +2026-02-04T19:18:46.804626Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78440/133889 blocks (58.6%), 0 events +2026-02-04T19:18:46.974256Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78450/133889 blocks (58.6%), 0 events +2026-02-04T19:18:47.181480Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78460/133889 blocks (58.6%), 0 events +2026-02-04T19:18:47.440855Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78470/133889 blocks (58.6%), 0 events +2026-02-04T19:18:47.665946Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78480/133889 blocks (58.6%), 0 events +2026-02-04T19:18:47.852998Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78490/133889 blocks (58.6%), 0 events +2026-02-04T19:18:48.151837Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78500/133889 blocks (58.6%), 0 events +2026-02-04T19:18:48.195204Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78510/133889 blocks (58.6%), 0 events +2026-02-04T19:18:48.420745Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78520/133889 blocks (58.6%), 0 events +2026-02-04T19:18:48.675199Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78530/133889 blocks (58.7%), 0 events +2026-02-04T19:18:48.837164Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78540/133889 blocks (58.7%), 0 events +2026-02-04T19:18:48.986390Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78550/133889 blocks (58.7%), 0 events +2026-02-04T19:18:49.233070Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78560/133889 blocks (58.7%), 0 events +2026-02-04T19:18:49.409989Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78570/133889 blocks (58.7%), 0 events +2026-02-04T19:18:49.725243Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78580/133889 blocks (58.7%), 0 events +2026-02-04T19:18:49.778168Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78590/133889 blocks (58.7%), 0 events +2026-02-04T19:18:50.018842Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78600/133889 blocks (58.7%), 0 events +2026-02-04T19:18:50.247590Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78610/133889 blocks (58.7%), 0 events +2026-02-04T19:18:50.405481Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78620/133889 blocks (58.7%), 0 events +2026-02-04T19:18:50.608452Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78630/133889 blocks (58.7%), 0 events +2026-02-04T19:18:50.806441Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78640/133889 blocks (58.7%), 0 events +2026-02-04T19:18:51.020051Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78650/133889 blocks (58.7%), 0 events +2026-02-04T19:18:51.203815Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78660/133889 blocks (58.7%), 0 events +2026-02-04T19:18:51.372289Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78670/133889 blocks (58.8%), 0 events +2026-02-04T19:18:51.621302Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78680/133889 blocks (58.8%), 0 events +2026-02-04T19:18:51.852375Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78690/133889 blocks (58.8%), 0 events +2026-02-04T19:18:52.025671Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78700/133889 blocks (58.8%), 0 events +2026-02-04T19:18:52.170210Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78710/133889 blocks (58.8%), 0 events +2026-02-04T19:18:52.427089Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78720/133889 blocks (58.8%), 0 events +2026-02-04T19:18:52.580208Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78730/133889 blocks (58.8%), 0 events +2026-02-04T19:18:52.897313Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78740/133889 blocks (58.8%), 0 events +2026-02-04T19:18:53.096470Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78750/133889 blocks (58.8%), 0 events +2026-02-04T19:18:53.179693Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78760/133889 blocks (58.8%), 0 events +2026-02-04T19:18:53.453839Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78770/133889 blocks (58.8%), 0 events +2026-02-04T19:18:53.622346Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78780/133889 blocks (58.8%), 0 events +2026-02-04T19:18:53.915285Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78790/133889 blocks (58.8%), 0 events +2026-02-04T19:18:53.948590Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78800/133889 blocks (58.9%), 0 events +2026-02-04T19:18:54.242035Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78810/133889 blocks (58.9%), 0 events +2026-02-04T19:18:54.478513Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78820/133889 blocks (58.9%), 0 events +2026-02-04T19:18:54.655736Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78830/133889 blocks (58.9%), 0 events +2026-02-04T19:18:54.846878Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78840/133889 blocks (58.9%), 0 events +2026-02-04T19:18:55.016647Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78850/133889 blocks (58.9%), 0 events +2026-02-04T19:18:55.194869Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78860/133889 blocks (58.9%), 0 events +2026-02-04T19:18:55.366002Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78870/133889 blocks (58.9%), 0 events +2026-02-04T19:18:55.602348Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78880/133889 blocks (58.9%), 0 events +2026-02-04T19:18:55.781254Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78890/133889 blocks (58.9%), 0 events +2026-02-04T19:18:56.050639Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78900/133889 blocks (58.9%), 0 events +2026-02-04T19:18:56.187936Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78910/133889 blocks (58.9%), 0 events +2026-02-04T19:18:56.364626Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78920/133889 blocks (58.9%), 0 events +2026-02-04T19:18:56.617618Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78930/133889 blocks (59.0%), 0 events +2026-02-04T19:18:56.841348Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78940/133889 blocks (59.0%), 0 events +2026-02-04T19:18:57.062868Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78950/133889 blocks (59.0%), 0 events +2026-02-04T19:18:57.257545Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78960/133889 blocks (59.0%), 0 events +2026-02-04T19:18:57.377660Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78970/133889 blocks (59.0%), 0 events +2026-02-04T19:18:57.617817Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78980/133889 blocks (59.0%), 0 events +2026-02-04T19:18:57.764098Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78990/133889 blocks (59.0%), 0 events +2026-02-04T19:18:58.110194Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79000/133889 blocks (59.0%), 0 events +2026-02-04T19:18:58.307034Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79010/133889 blocks (59.0%), 0 events +2026-02-04T19:18:58.422226Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79020/133889 blocks (59.0%), 0 events +2026-02-04T19:18:58.666129Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79030/133889 blocks (59.0%), 0 events +2026-02-04T19:18:58.860925Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79040/133889 blocks (59.0%), 0 events +2026-02-04T19:18:59.033844Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79050/133889 blocks (59.0%), 0 events +2026-02-04T19:18:59.228441Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79060/133889 blocks (59.0%), 0 events +2026-02-04T19:18:59.387383Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79070/133889 blocks (59.1%), 0 events +2026-02-04T19:18:59.715752Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79080/133889 blocks (59.1%), 0 events +2026-02-04T19:18:59.753806Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79090/133889 blocks (59.1%), 0 events +2026-02-04T19:19:00.007726Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79100/133889 blocks (59.1%), 0 events +2026-02-04T19:19:00.242733Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79110/133889 blocks (59.1%), 0 events +2026-02-04T19:19:00.413709Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79120/133889 blocks (59.1%), 0 events +2026-02-04T19:19:00.586275Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79130/133889 blocks (59.1%), 0 events +2026-02-04T19:19:00.792932Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79140/133889 blocks (59.1%), 0 events +2026-02-04T19:19:01.048618Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79150/133889 blocks (59.1%), 0 events +2026-02-04T19:19:01.306726Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79160/133889 blocks (59.1%), 0 events +2026-02-04T19:19:01.425797Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79170/133889 blocks (59.1%), 0 events +2026-02-04T19:19:01.599287Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79180/133889 blocks (59.1%), 0 events +2026-02-04T19:19:01.826754Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79190/133889 blocks (59.1%), 0 events +2026-02-04T19:19:02.027027Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79200/133889 blocks (59.2%), 0 events +2026-02-04T19:19:02.172187Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79210/133889 blocks (59.2%), 0 events +2026-02-04T19:19:02.406132Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79220/133889 blocks (59.2%), 0 events +2026-02-04T19:19:02.574943Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79230/133889 blocks (59.2%), 0 events +2026-02-04T19:19:02.863070Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79240/133889 blocks (59.2%), 0 events +2026-02-04T19:19:02.964883Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79250/133889 blocks (59.2%), 0 events +2026-02-04T19:19:03.244089Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79260/133889 blocks (59.2%), 0 events +2026-02-04T19:19:03.384287Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79270/133889 blocks (59.2%), 0 events +2026-02-04T19:19:03.652626Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79280/133889 blocks (59.2%), 0 events +2026-02-04T19:19:03.910447Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79290/133889 blocks (59.2%), 0 events +2026-02-04T19:19:03.972475Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79300/133889 blocks (59.2%), 0 events +2026-02-04T19:19:04.191991Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79310/133889 blocks (59.2%), 0 events +2026-02-04T19:19:04.442655Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79320/133889 blocks (59.2%), 0 events +2026-02-04T19:19:04.618620Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79330/133889 blocks (59.3%), 0 events +2026-02-04T19:19:04.804420Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79340/133889 blocks (59.3%), 0 events +2026-02-04T19:19:04.994086Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79350/133889 blocks (59.3%), 0 events +2026-02-04T19:19:05.223982Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79360/133889 blocks (59.3%), 0 events +2026-02-04T19:19:05.488148Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79370/133889 blocks (59.3%), 0 events +2026-02-04T19:19:05.644260Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79380/133889 blocks (59.3%), 0 events +2026-02-04T19:19:05.849233Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79390/133889 blocks (59.3%), 0 events +2026-02-04T19:19:06.025104Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79400/133889 blocks (59.3%), 0 events +2026-02-04T19:19:06.188363Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79410/133889 blocks (59.3%), 0 events +2026-02-04T19:19:06.372872Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79420/133889 blocks (59.3%), 0 events +2026-02-04T19:19:06.600677Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79430/133889 blocks (59.3%), 0 events +2026-02-04T19:19:06.792290Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79440/133889 blocks (59.3%), 0 events +2026-02-04T19:19:07.063165Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79450/133889 blocks (59.3%), 0 events +2026-02-04T19:19:07.245281Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79460/133889 blocks (59.3%), 0 events +2026-02-04T19:19:07.435117Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79470/133889 blocks (59.4%), 0 events +2026-02-04T19:19:07.629895Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79480/133889 blocks (59.4%), 0 events +2026-02-04T19:19:07.773150Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79490/133889 blocks (59.4%), 0 events +2026-02-04T19:19:08.112292Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79500/133889 blocks (59.4%), 0 events +2026-02-04T19:19:08.186388Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79510/133889 blocks (59.4%), 0 events +2026-02-04T19:19:08.399426Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79520/133889 blocks (59.4%), 0 events +2026-02-04T19:19:08.627222Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79530/133889 blocks (59.4%), 0 events +2026-02-04T19:19:08.774225Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79540/133889 blocks (59.4%), 0 events +2026-02-04T19:19:09.005245Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79550/133889 blocks (59.4%), 0 events +2026-02-04T19:19:09.203971Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79560/133889 blocks (59.4%), 0 events +2026-02-04T19:19:09.416663Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79570/133889 blocks (59.4%), 0 events +2026-02-04T19:19:09.681532Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79580/133889 blocks (59.4%), 0 events +2026-02-04T19:19:09.838799Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79590/133889 blocks (59.4%), 0 events +2026-02-04T19:19:10.042321Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79600/133889 blocks (59.5%), 0 events +2026-02-04T19:19:10.209949Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79610/133889 blocks (59.5%), 0 events +2026-02-04T19:19:10.381948Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79620/133889 blocks (59.5%), 0 events +2026-02-04T19:19:10.586379Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79630/133889 blocks (59.5%), 0 events +2026-02-04T19:19:10.836303Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79640/133889 blocks (59.5%), 0 events +2026-02-04T19:19:11.015595Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79650/133889 blocks (59.5%), 0 events +2026-02-04T19:19:11.257108Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79660/133889 blocks (59.5%), 0 events +2026-02-04T19:19:11.416156Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79670/133889 blocks (59.5%), 0 events +2026-02-04T19:19:11.740855Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79680/133889 blocks (59.5%), 0 events +2026-02-04T19:19:11.790805Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79690/133889 blocks (59.5%), 0 events +2026-02-04T19:19:12.057543Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79700/133889 blocks (59.5%), 0 events +2026-02-04T19:19:12.298490Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79710/133889 blocks (59.5%), 0 events +2026-02-04T19:19:12.404053Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79720/133889 blocks (59.5%), 0 events +2026-02-04T19:19:12.575915Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79730/133889 blocks (59.5%), 0 events +2026-02-04T19:19:12.824712Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79740/133889 blocks (59.6%), 0 events +2026-02-04T19:19:13.032339Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79750/133889 blocks (59.6%), 0 events +2026-02-04T19:19:13.217397Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79760/133889 blocks (59.6%), 0 events +2026-02-04T19:19:13.461153Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79770/133889 blocks (59.6%), 0 events +2026-02-04T19:19:13.654803Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79780/133889 blocks (59.6%), 0 events +2026-02-04T19:19:13.872656Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79790/133889 blocks (59.6%), 0 events +2026-02-04T19:19:13.973537Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79800/133889 blocks (59.6%), 0 events +2026-02-04T19:19:14.254497Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79810/133889 blocks (59.6%), 0 events +2026-02-04T19:19:14.413419Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79820/133889 blocks (59.6%), 0 events +2026-02-04T19:19:14.581257Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79830/133889 blocks (59.6%), 0 events +2026-02-04T19:19:14.923647Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79840/133889 blocks (59.6%), 0 events +2026-02-04T19:19:14.964810Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79850/133889 blocks (59.6%), 0 events +2026-02-04T19:19:15.252069Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79860/133889 blocks (59.6%), 0 events +2026-02-04T19:19:15.442561Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79870/133889 blocks (59.7%), 0 events +2026-02-04T19:19:15.614033Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79880/133889 blocks (59.7%), 0 events +2026-02-04T19:19:15.937959Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79890/133889 blocks (59.7%), 0 events +2026-02-04T19:19:15.977593Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79900/133889 blocks (59.7%), 0 events +2026-02-04T19:19:16.186246Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79910/133889 blocks (59.7%), 0 events +2026-02-04T19:19:16.497048Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79920/133889 blocks (59.7%), 0 events +2026-02-04T19:19:16.580924Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79930/133889 blocks (59.7%), 0 events +2026-02-04T19:19:16.776419Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79940/133889 blocks (59.7%), 0 events +2026-02-04T19:19:17.026428Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79950/133889 blocks (59.7%), 0 events +2026-02-04T19:19:17.163553Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79960/133889 blocks (59.7%), 0 events +2026-02-04T19:19:17.509617Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79970/133889 blocks (59.7%), 0 events +2026-02-04T19:19:17.559406Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79980/133889 blocks (59.7%), 0 events +2026-02-04T19:19:17.840245Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79990/133889 blocks (59.7%), 0 events +2026-02-04T19:19:18.033915Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80000/133889 blocks (59.8%), 0 events +2026-02-04T19:19:18.168432Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80010/133889 blocks (59.8%), 0 events +2026-02-04T19:19:18.416420Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80020/133889 blocks (59.8%), 0 events +2026-02-04T19:19:18.587980Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80030/133889 blocks (59.8%), 0 events +2026-02-04T19:19:18.826816Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80040/133889 blocks (59.8%), 0 events +2026-02-04T19:19:19.111778Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80050/133889 blocks (59.8%), 0 events +2026-02-04T19:19:19.221140Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80060/133889 blocks (59.8%), 0 events +2026-02-04T19:19:19.452889Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80070/133889 blocks (59.8%), 0 events +2026-02-04T19:19:19.642509Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80080/133889 blocks (59.8%), 0 events +2026-02-04T19:19:19.766299Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80090/133889 blocks (59.8%), 0 events +2026-02-04T19:19:20.020161Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80100/133889 blocks (59.8%), 0 events +2026-02-04T19:19:20.212927Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80110/133889 blocks (59.8%), 0 events +2026-02-04T19:19:20.422476Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80120/133889 blocks (59.8%), 0 events +2026-02-04T19:19:20.652644Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80130/133889 blocks (59.8%), 0 events +2026-02-04T19:19:20.824782Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80140/133889 blocks (59.9%), 0 events +2026-02-04T19:19:20.959307Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80150/133889 blocks (59.9%), 0 events +2026-02-04T19:19:21.249263Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80160/133889 blocks (59.9%), 0 events +2026-02-04T19:19:21.456247Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80170/133889 blocks (59.9%), 0 events +2026-02-04T19:19:21.577492Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80180/133889 blocks (59.9%), 0 events +2026-02-04T19:19:21.788693Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80190/133889 blocks (59.9%), 0 events +2026-02-04T19:19:21.995550Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80200/133889 blocks (59.9%), 0 events +2026-02-04T19:19:22.261322Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80210/133889 blocks (59.9%), 0 events +2026-02-04T19:19:22.374797Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80220/133889 blocks (59.9%), 0 events +2026-02-04T19:19:22.596751Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80230/133889 blocks (59.9%), 0 events +2026-02-04T19:19:22.778993Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80240/133889 blocks (59.9%), 0 events +2026-02-04T19:19:23.023252Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80250/133889 blocks (59.9%), 0 events +2026-02-04T19:19:23.273940Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80260/133889 blocks (59.9%), 0 events +2026-02-04T19:19:23.466436Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80270/133889 blocks (60.0%), 0 events +2026-02-04T19:19:23.562933Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80280/133889 blocks (60.0%), 0 events +2026-02-04T19:19:23.860125Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80290/133889 blocks (60.0%), 0 events +2026-02-04T19:19:23.981491Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80300/133889 blocks (60.0%), 0 events +2026-02-04T19:19:24.177473Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80310/133889 blocks (60.0%), 0 events +2026-02-04T19:19:24.381372Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80320/133889 blocks (60.0%), 0 events +2026-02-04T19:19:24.559775Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80330/133889 blocks (60.0%), 0 events +2026-02-04T19:19:24.884724Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80340/133889 blocks (60.0%), 0 events +2026-02-04T19:19:24.990673Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80350/133889 blocks (60.0%), 0 events +2026-02-04T19:19:25.261328Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80360/133889 blocks (60.0%), 0 events +2026-02-04T19:19:25.407912Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80370/133889 blocks (60.0%), 0 events +2026-02-04T19:19:25.612134Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80380/133889 blocks (60.0%), 0 events +2026-02-04T19:19:25.789794Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80390/133889 blocks (60.0%), 0 events +2026-02-04T19:19:26.018189Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80400/133889 blocks (60.0%), 0 events +2026-02-04T19:19:26.184289Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80410/133889 blocks (60.1%), 0 events +2026-02-04T19:19:26.457008Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80420/133889 blocks (60.1%), 0 events +2026-02-04T19:19:26.596251Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80430/133889 blocks (60.1%), 0 events +2026-02-04T19:19:26.789954Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80440/133889 blocks (60.1%), 0 events +2026-02-04T19:19:26.988061Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80450/133889 blocks (60.1%), 0 events +2026-02-04T19:19:27.224733Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80460/133889 blocks (60.1%), 0 events +2026-02-04T19:19:27.510758Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80470/133889 blocks (60.1%), 0 events +2026-02-04T19:19:27.646328Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80480/133889 blocks (60.1%), 0 events +2026-02-04T19:19:27.787451Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80490/133889 blocks (60.1%), 0 events +2026-02-04T19:19:28.026847Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80500/133889 blocks (60.1%), 0 events +2026-02-04T19:19:28.250375Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80510/133889 blocks (60.1%), 0 events +2026-02-04T19:19:28.365970Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80520/133889 blocks (60.1%), 0 events +2026-02-04T19:19:28.609994Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80530/133889 blocks (60.1%), 0 events +2026-02-04T19:19:28.833021Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80540/133889 blocks (60.2%), 0 events +2026-02-04T19:19:29.075854Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80550/133889 blocks (60.2%), 0 events +2026-02-04T19:19:29.203031Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80560/133889 blocks (60.2%), 0 events +2026-02-04T19:19:29.422118Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80570/133889 blocks (60.2%), 0 events +2026-02-04T19:19:29.625883Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80580/133889 blocks (60.2%), 0 events +2026-02-04T19:19:29.783417Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80590/133889 blocks (60.2%), 0 events +2026-02-04T19:19:30.091492Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80600/133889 blocks (60.2%), 0 events +2026-02-04T19:19:30.254121Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80610/133889 blocks (60.2%), 0 events +2026-02-04T19:19:30.382336Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80620/133889 blocks (60.2%), 0 events +2026-02-04T19:19:30.649280Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80630/133889 blocks (60.2%), 0 events +2026-02-04T19:19:30.816094Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80640/133889 blocks (60.2%), 0 events +2026-02-04T19:19:31.025171Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80650/133889 blocks (60.2%), 0 events +2026-02-04T19:19:31.209391Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80660/133889 blocks (60.2%), 0 events +2026-02-04T19:19:31.379593Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80670/133889 blocks (60.3%), 0 events +2026-02-04T19:19:31.664341Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80680/133889 blocks (60.3%), 0 events +2026-02-04T19:19:31.807339Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80690/133889 blocks (60.3%), 0 events +2026-02-04T19:19:31.964418Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80700/133889 blocks (60.3%), 0 events +2026-02-04T19:19:32.233884Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80710/133889 blocks (60.3%), 0 events +2026-02-04T19:19:32.431893Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80720/133889 blocks (60.3%), 0 events +2026-02-04T19:19:32.711028Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80730/133889 blocks (60.3%), 0 events +2026-02-04T19:19:32.783031Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80740/133889 blocks (60.3%), 0 events +2026-02-04T19:19:32.993144Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80750/133889 blocks (60.3%), 0 events +2026-02-04T19:19:33.265858Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80760/133889 blocks (60.3%), 0 events +2026-02-04T19:19:33.411972Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80770/133889 blocks (60.3%), 0 events +2026-02-04T19:19:33.646132Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80780/133889 blocks (60.3%), 0 events +2026-02-04T19:19:33.823530Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80790/133889 blocks (60.3%), 0 events +2026-02-04T19:19:33.974873Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80800/133889 blocks (60.3%), 0 events +2026-02-04T19:19:34.189146Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80810/133889 blocks (60.4%), 0 events +2026-02-04T19:19:34.396027Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80820/133889 blocks (60.4%), 0 events +2026-02-04T19:19:34.585043Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80830/133889 blocks (60.4%), 0 events +2026-02-04T19:19:34.842333Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80840/133889 blocks (60.4%), 0 events +2026-02-04T19:19:34.981019Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80850/133889 blocks (60.4%), 0 events +2026-02-04T19:19:35.333086Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80860/133889 blocks (60.4%), 0 events +2026-02-04T19:19:35.369466Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80870/133889 blocks (60.4%), 0 events +2026-02-04T19:19:35.656227Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80880/133889 blocks (60.4%), 0 events +2026-02-04T19:19:35.856288Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80890/133889 blocks (60.4%), 0 events +2026-02-04T19:19:36.011191Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80900/133889 blocks (60.4%), 0 events +2026-02-04T19:19:36.215713Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80910/133889 blocks (60.4%), 0 events +2026-02-04T19:19:36.419346Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80920/133889 blocks (60.4%), 0 events +2026-02-04T19:19:36.557094Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80930/133889 blocks (60.4%), 0 events +2026-02-04T19:19:36.796372Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80940/133889 blocks (60.5%), 0 events +2026-02-04T19:19:37.026092Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80950/133889 blocks (60.5%), 0 events +2026-02-04T19:19:37.206431Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80960/133889 blocks (60.5%), 0 events +2026-02-04T19:19:37.470452Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80970/133889 blocks (60.5%), 0 events +2026-02-04T19:19:37.615215Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80980/133889 blocks (60.5%), 0 events +2026-02-04T19:19:37.860726Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80990/133889 blocks (60.5%), 0 events +2026-02-04T19:19:37.989887Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81000/133889 blocks (60.5%), 0 events +2026-02-04T19:19:38.184221Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81010/133889 blocks (60.5%), 0 events +2026-02-04T19:19:38.511884Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81020/133889 blocks (60.5%), 0 events +2026-02-04T19:19:38.619566Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81030/133889 blocks (60.5%), 0 events +2026-02-04T19:19:38.788724Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81040/133889 blocks (60.5%), 0 events +2026-02-04T19:19:39.039639Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81050/133889 blocks (60.5%), 0 events +2026-02-04T19:19:39.204951Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81060/133889 blocks (60.5%), 0 events +2026-02-04T19:19:39.585105Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81070/133889 blocks (60.5%), 0 events +2026-02-04T19:19:39.623271Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81080/133889 blocks (60.6%), 0 events +2026-02-04T19:19:39.808436Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81090/133889 blocks (60.6%), 0 events +2026-02-04T19:19:40.052670Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81100/133889 blocks (60.6%), 0 events +2026-02-04T19:19:40.273661Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81110/133889 blocks (60.6%), 0 events +2026-02-04T19:19:40.427345Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81120/133889 blocks (60.6%), 0 events +2026-02-04T19:19:40.616322Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81130/133889 blocks (60.6%), 0 events +2026-02-04T19:19:40.827372Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81140/133889 blocks (60.6%), 0 events +2026-02-04T19:19:40.974747Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81150/133889 blocks (60.6%), 0 events +2026-02-04T19:19:41.253199Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81160/133889 blocks (60.6%), 0 events +2026-02-04T19:19:41.403867Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81170/133889 blocks (60.6%), 0 events +2026-02-04T19:19:41.661938Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81180/133889 blocks (60.6%), 0 events +2026-02-04T19:19:41.799894Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81190/133889 blocks (60.6%), 0 events +2026-02-04T19:19:41.983062Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81200/133889 blocks (60.6%), 0 events +2026-02-04T19:19:42.209562Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81210/133889 blocks (60.7%), 0 events +2026-02-04T19:19:42.385259Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81220/133889 blocks (60.7%), 0 events +2026-02-04T19:19:42.704721Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81230/133889 blocks (60.7%), 0 events +2026-02-04T19:19:42.806216Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81240/133889 blocks (60.7%), 0 events +2026-02-04T19:19:43.041968Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81250/133889 blocks (60.7%), 0 events +2026-02-04T19:19:43.227094Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81260/133889 blocks (60.7%), 0 events +2026-02-04T19:19:43.454024Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81270/133889 blocks (60.7%), 0 events +2026-02-04T19:19:43.567341Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81280/133889 blocks (60.7%), 0 events +2026-02-04T19:19:43.770189Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81290/133889 blocks (60.7%), 0 events +2026-02-04T19:19:43.980346Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81300/133889 blocks (60.7%), 0 events +2026-02-04T19:19:44.280519Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81310/133889 blocks (60.7%), 0 events +2026-02-04T19:19:44.443985Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81320/133889 blocks (60.7%), 0 events +2026-02-04T19:19:44.563312Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81330/133889 blocks (60.7%), 0 events +2026-02-04T19:19:44.800432Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81340/133889 blocks (60.8%), 0 events +2026-02-04T19:19:44.992585Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81350/133889 blocks (60.8%), 0 events +2026-02-04T19:19:45.178223Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81360/133889 blocks (60.8%), 0 events +2026-02-04T19:19:45.423277Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81370/133889 blocks (60.8%), 0 events +2026-02-04T19:19:45.628643Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81380/133889 blocks (60.8%), 0 events +2026-02-04T19:19:45.882517Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81390/133889 blocks (60.8%), 0 events +2026-02-04T19:19:46.014998Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81400/133889 blocks (60.8%), 0 events +2026-02-04T19:19:46.207581Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81410/133889 blocks (60.8%), 0 events +2026-02-04T19:19:46.445474Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81420/133889 blocks (60.8%), 0 events +2026-02-04T19:19:46.587476Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81430/133889 blocks (60.8%), 0 events +2026-02-04T19:19:46.865809Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81440/133889 blocks (60.8%), 0 events +2026-02-04T19:19:47.031606Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81450/133889 blocks (60.8%), 0 events +2026-02-04T19:19:47.163336Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81460/133889 blocks (60.8%), 0 events +2026-02-04T19:19:47.422375Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81470/133889 blocks (60.8%), 0 events +2026-02-04T19:19:47.616855Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81480/133889 blocks (60.9%), 0 events +2026-02-04T19:19:47.811951Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81490/133889 blocks (60.9%), 0 events +2026-02-04T19:19:47.987564Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81500/133889 blocks (60.9%), 0 events +2026-02-04T19:19:48.252578Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81510/133889 blocks (60.9%), 0 events +2026-02-04T19:19:48.439320Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81520/133889 blocks (60.9%), 0 events +2026-02-04T19:19:48.628866Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81530/133889 blocks (60.9%), 0 events +2026-02-04T19:19:48.781641Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81540/133889 blocks (60.9%), 0 events +2026-02-04T19:19:49.012358Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81550/133889 blocks (60.9%), 0 events +2026-02-04T19:19:49.200787Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81560/133889 blocks (60.9%), 0 events +2026-02-04T19:19:49.490378Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81570/133889 blocks (60.9%), 0 events +2026-02-04T19:19:49.642718Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81580/133889 blocks (60.9%), 0 events +2026-02-04T19:19:49.825178Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81590/133889 blocks (60.9%), 0 events +2026-02-04T19:19:50.045691Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81600/133889 blocks (60.9%), 0 events +2026-02-04T19:19:50.182258Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81610/133889 blocks (61.0%), 0 events +2026-02-04T19:19:50.361677Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81620/133889 blocks (61.0%), 0 events +2026-02-04T19:19:50.653529Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81630/133889 blocks (61.0%), 0 events +2026-02-04T19:19:50.919047Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81640/133889 blocks (61.0%), 0 events +2026-02-04T19:19:50.954072Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81650/133889 blocks (61.0%), 0 events +2026-02-04T19:19:51.236161Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81660/133889 blocks (61.0%), 0 events +2026-02-04T19:19:51.365549Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81670/133889 blocks (61.0%), 0 events +2026-02-04T19:19:51.619246Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81680/133889 blocks (61.0%), 0 events +2026-02-04T19:19:51.848032Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81690/133889 blocks (61.0%), 0 events +2026-02-04T19:19:51.981431Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81700/133889 blocks (61.0%), 0 events +2026-02-04T19:19:52.233541Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81710/133889 blocks (61.0%), 0 events +2026-02-04T19:19:52.371407Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81720/133889 blocks (61.0%), 0 events +2026-02-04T19:19:52.672571Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81730/133889 blocks (61.0%), 0 events +2026-02-04T19:19:52.825967Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81740/133889 blocks (61.1%), 0 events +2026-02-04T19:19:53.007721Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81750/133889 blocks (61.1%), 0 events +2026-02-04T19:19:53.220459Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81760/133889 blocks (61.1%), 0 events +2026-02-04T19:19:53.444086Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81770/133889 blocks (61.1%), 0 events +2026-02-04T19:19:53.681653Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81780/133889 blocks (61.1%), 0 events +2026-02-04T19:19:53.765256Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81790/133889 blocks (61.1%), 0 events +2026-02-04T19:19:54.016004Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81800/133889 blocks (61.1%), 0 events +2026-02-04T19:19:54.237262Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81810/133889 blocks (61.1%), 0 events +2026-02-04T19:19:54.432582Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81820/133889 blocks (61.1%), 0 events +2026-02-04T19:19:54.573317Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81830/133889 blocks (61.1%), 0 events +2026-02-04T19:19:54.841810Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81840/133889 blocks (61.1%), 0 events +2026-02-04T19:19:55.018048Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81850/133889 blocks (61.1%), 0 events +2026-02-04T19:19:55.287862Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81860/133889 blocks (61.1%), 0 events +2026-02-04T19:19:55.377552Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81870/133889 blocks (61.1%), 0 events +2026-02-04T19:19:55.648309Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81880/133889 blocks (61.2%), 0 events +2026-02-04T19:19:55.824202Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81890/133889 blocks (61.2%), 0 events +2026-02-04T19:19:56.033829Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81900/133889 blocks (61.2%), 0 events +2026-02-04T19:19:56.303197Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81910/133889 blocks (61.2%), 0 events +2026-02-04T19:19:56.445461Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81920/133889 blocks (61.2%), 0 events +2026-02-04T19:19:56.594263Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81930/133889 blocks (61.2%), 0 events +2026-02-04T19:19:56.863301Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81940/133889 blocks (61.2%), 0 events +2026-02-04T19:19:57.003554Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81950/133889 blocks (61.2%), 0 events +2026-02-04T19:19:57.196049Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81960/133889 blocks (61.2%), 0 events +2026-02-04T19:19:57.444023Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81970/133889 blocks (61.2%), 0 events +2026-02-04T19:19:57.575236Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81980/133889 blocks (61.2%), 0 events +2026-02-04T19:19:57.876502Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81990/133889 blocks (61.2%), 0 events +2026-02-04T19:19:58.028519Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82000/133889 blocks (61.2%), 0 events +2026-02-04T19:19:58.169293Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82010/133889 blocks (61.3%), 0 events +2026-02-04T19:19:58.433099Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82020/133889 blocks (61.3%), 0 events +2026-02-04T19:19:58.563479Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82030/133889 blocks (61.3%), 0 events +2026-02-04T19:19:58.783092Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82040/133889 blocks (61.3%), 0 events +2026-02-04T19:19:59.061942Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82050/133889 blocks (61.3%), 0 events +2026-02-04T19:19:59.246636Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82060/133889 blocks (61.3%), 0 events +2026-02-04T19:19:59.448969Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82070/133889 blocks (61.3%), 0 events +2026-02-04T19:19:59.627804Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82080/133889 blocks (61.3%), 0 events +2026-02-04T19:19:59.772759Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82090/133889 blocks (61.3%), 0 events +2026-02-04T19:20:00.020053Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82100/133889 blocks (61.3%), 0 events +2026-02-04T19:20:00.256797Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82110/133889 blocks (61.3%), 0 events +2026-02-04T19:20:00.390224Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82120/133889 blocks (61.3%), 0 events +2026-02-04T19:20:00.661238Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82130/133889 blocks (61.3%), 0 events +2026-02-04T19:20:00.828871Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82140/133889 blocks (61.3%), 0 events +2026-02-04T19:20:01.075335Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82150/133889 blocks (61.4%), 0 events +2026-02-04T19:20:01.186367Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82160/133889 blocks (61.4%), 0 events +2026-02-04T19:20:01.442960Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82170/133889 blocks (61.4%), 0 events +2026-02-04T19:20:01.659794Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82180/133889 blocks (61.4%), 0 events +2026-02-04T19:20:01.796535Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82190/133889 blocks (61.4%), 0 events +2026-02-04T19:20:02.069901Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82200/133889 blocks (61.4%), 0 events +2026-02-04T19:20:02.271256Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82210/133889 blocks (61.4%), 0 events +2026-02-04T19:20:02.415500Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82220/133889 blocks (61.4%), 0 events +2026-02-04T19:20:02.627826Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82230/133889 blocks (61.4%), 0 events +2026-02-04T19:20:02.797236Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82240/133889 blocks (61.4%), 0 events +2026-02-04T19:20:02.965523Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82250/133889 blocks (61.4%), 0 events +2026-02-04T19:20:03.195579Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82260/133889 blocks (61.4%), 0 events +2026-02-04T19:20:03.444982Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82270/133889 blocks (61.4%), 0 events +2026-02-04T19:20:03.644785Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82280/133889 blocks (61.5%), 0 events +2026-02-04T19:20:03.780636Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82290/133889 blocks (61.5%), 0 events +2026-02-04T19:20:04.005608Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82300/133889 blocks (61.5%), 0 events +2026-02-04T19:20:04.236642Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82310/133889 blocks (61.5%), 0 events +2026-02-04T19:20:04.380542Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82320/133889 blocks (61.5%), 0 events +2026-02-04T19:20:04.693989Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82330/133889 blocks (61.5%), 0 events +2026-02-04T19:20:04.835856Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82340/133889 blocks (61.5%), 0 events +2026-02-04T19:20:05.015059Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82350/133889 blocks (61.5%), 0 events +2026-02-04T19:20:05.260146Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82360/133889 blocks (61.5%), 0 events +2026-02-04T19:20:05.414686Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82370/133889 blocks (61.5%), 0 events +2026-02-04T19:20:05.740447Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82380/133889 blocks (61.5%), 0 events +2026-02-04T19:20:05.785722Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82390/133889 blocks (61.5%), 0 events +2026-02-04T19:20:06.046086Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82400/133889 blocks (61.5%), 0 events +2026-02-04T19:20:06.265949Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82410/133889 blocks (61.6%), 0 events +2026-02-04T19:20:06.451320Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82420/133889 blocks (61.6%), 0 events +2026-02-04T19:20:06.652128Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82430/133889 blocks (61.6%), 0 events +2026-02-04T19:20:06.838533Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82440/133889 blocks (61.6%), 0 events +2026-02-04T19:20:07.004574Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82450/133889 blocks (61.6%), 0 events +2026-02-04T19:20:07.348740Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82460/133889 blocks (61.6%), 0 events +2026-02-04T19:20:07.391707Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82470/133889 blocks (61.6%), 0 events +2026-02-04T19:20:07.610077Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82480/133889 blocks (61.6%), 0 events +2026-02-04T19:20:07.837277Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82490/133889 blocks (61.6%), 0 events +2026-02-04T19:20:07.972965Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82500/133889 blocks (61.6%), 0 events +2026-02-04T19:20:08.243772Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82510/133889 blocks (61.6%), 0 events +2026-02-04T19:20:08.393748Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82520/133889 blocks (61.6%), 0 events +2026-02-04T19:20:08.601156Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82530/133889 blocks (61.6%), 0 events +2026-02-04T19:20:08.884611Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82540/133889 blocks (61.6%), 0 events +2026-02-04T19:20:09.021358Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82550/133889 blocks (61.7%), 0 events +2026-02-04T19:20:09.219831Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82560/133889 blocks (61.7%), 0 events +2026-02-04T19:20:09.446509Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82570/133889 blocks (61.7%), 0 events +2026-02-04T19:20:09.576064Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82580/133889 blocks (61.7%), 0 events +2026-02-04T19:20:09.781582Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82590/133889 blocks (61.7%), 0 events +2026-02-04T19:20:10.030019Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82600/133889 blocks (61.7%), 0 events +2026-02-04T19:20:10.276059Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82610/133889 blocks (61.7%), 0 events +2026-02-04T19:20:10.457428Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82620/133889 blocks (61.7%), 0 events +2026-02-04T19:20:10.567497Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82630/133889 blocks (61.7%), 0 events +2026-02-04T19:20:10.854709Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82640/133889 blocks (61.7%), 0 events +2026-02-04T19:20:11.014890Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82650/133889 blocks (61.7%), 0 events +2026-02-04T19:20:11.189619Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82660/133889 blocks (61.7%), 0 events +2026-02-04T19:20:11.506976Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82670/133889 blocks (61.7%), 0 events +2026-02-04T19:20:11.645372Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82680/133889 blocks (61.8%), 0 events +2026-02-04T19:20:11.808283Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82690/133889 blocks (61.8%), 0 events +2026-02-04T19:20:12.070228Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82700/133889 blocks (61.8%), 0 events +2026-02-04T19:20:12.213825Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82710/133889 blocks (61.8%), 0 events +2026-02-04T19:20:12.460544Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82720/133889 blocks (61.8%), 0 events +2026-02-04T19:20:12.635754Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82730/133889 blocks (61.8%), 0 events +2026-02-04T19:20:12.828606Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82740/133889 blocks (61.8%), 0 events +2026-02-04T19:20:12.981021Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82750/133889 blocks (61.8%), 0 events +2026-02-04T19:20:13.189070Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82760/133889 blocks (61.8%), 0 events +2026-02-04T19:20:13.401528Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82770/133889 blocks (61.8%), 0 events +2026-02-04T19:20:13.641419Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82780/133889 blocks (61.8%), 0 events +2026-02-04T19:20:13.828447Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82790/133889 blocks (61.8%), 0 events +2026-02-04T19:20:13.979884Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82800/133889 blocks (61.8%), 0 events +2026-02-04T19:20:14.212152Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82810/133889 blocks (61.8%), 0 events +2026-02-04T19:20:14.390336Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82820/133889 blocks (61.9%), 0 events +2026-02-04T19:20:14.715298Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82830/133889 blocks (61.9%), 0 events +2026-02-04T19:20:14.749724Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82840/133889 blocks (61.9%), 0 events +2026-02-04T19:20:15.042394Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82850/133889 blocks (61.9%), 0 events +2026-02-04T19:20:15.239266Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82860/133889 blocks (61.9%), 0 events +2026-02-04T19:20:15.413557Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82870/133889 blocks (61.9%), 0 events +2026-02-04T19:20:15.702056Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82880/133889 blocks (61.9%), 0 events +2026-02-04T19:20:15.898043Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82890/133889 blocks (61.9%), 0 events +2026-02-04T19:20:16.041828Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82900/133889 blocks (61.9%), 0 events +2026-02-04T19:20:16.256523Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82910/133889 blocks (61.9%), 0 events +2026-02-04T19:20:16.455346Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82920/133889 blocks (61.9%), 0 events +2026-02-04T19:20:16.614052Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82930/133889 blocks (61.9%), 0 events +2026-02-04T19:20:16.784421Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82940/133889 blocks (61.9%), 0 events +2026-02-04T19:20:17.044538Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82950/133889 blocks (62.0%), 0 events +2026-02-04T19:20:17.274730Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82960/133889 blocks (62.0%), 0 events +2026-02-04T19:20:17.514407Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82970/133889 blocks (62.0%), 0 events +2026-02-04T19:20:17.562486Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82980/133889 blocks (62.0%), 0 events +2026-02-04T19:20:17.831354Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82990/133889 blocks (62.0%), 0 events +2026-02-04T19:20:18.041884Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83000/133889 blocks (62.0%), 0 events +2026-02-04T19:20:18.323192Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83010/133889 blocks (62.0%), 0 events +2026-02-04T19:20:18.409298Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83020/133889 blocks (62.0%), 0 events +2026-02-04T19:20:18.558016Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83030/133889 blocks (62.0%), 0 events +2026-02-04T19:20:18.883513Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83040/133889 blocks (62.0%), 0 events +2026-02-04T19:20:19.081586Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83050/133889 blocks (62.0%), 0 events +2026-02-04T19:20:19.170250Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83060/133889 blocks (62.0%), 0 events +2026-02-04T19:20:19.421965Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83070/133889 blocks (62.0%), 0 events +2026-02-04T19:20:19.619065Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83080/133889 blocks (62.1%), 0 events +2026-02-04T19:20:19.894348Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83090/133889 blocks (62.1%), 0 events +2026-02-04T19:20:19.971615Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83100/133889 blocks (62.1%), 0 events +2026-02-04T19:20:20.455905Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83110/133889 blocks (62.1%), 0 events +2026-02-04T19:20:20.506926Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83120/133889 blocks (62.1%), 0 events +2026-02-04T19:20:20.651088Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83130/133889 blocks (62.1%), 0 events +2026-02-04T19:20:20.825767Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83140/133889 blocks (62.1%), 0 events +2026-02-04T19:20:21.032040Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83150/133889 blocks (62.1%), 0 events +2026-02-04T19:20:21.186527Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83160/133889 blocks (62.1%), 0 events +2026-02-04T19:20:21.469360Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83170/133889 blocks (62.1%), 0 events +2026-02-04T19:20:21.698680Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83180/133889 blocks (62.1%), 0 events +2026-02-04T19:20:21.819772Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83190/133889 blocks (62.1%), 0 events +2026-02-04T19:20:22.024059Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83200/133889 blocks (62.1%), 0 events +2026-02-04T19:20:22.221255Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83210/133889 blocks (62.1%), 0 events +2026-02-04T19:20:22.379668Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83220/133889 blocks (62.2%), 0 events +2026-02-04T19:20:22.598931Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83230/133889 blocks (62.2%), 0 events +2026-02-04T19:20:22.836006Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83240/133889 blocks (62.2%), 0 events +2026-02-04T19:20:23.043950Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83250/133889 blocks (62.2%), 0 events +2026-02-04T19:20:23.237240Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83260/133889 blocks (62.2%), 0 events +2026-02-04T19:20:23.420472Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83270/133889 blocks (62.2%), 0 events +2026-02-04T19:20:23.604652Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83280/133889 blocks (62.2%), 0 events +2026-02-04T19:20:23.827138Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83290/133889 blocks (62.2%), 0 events +2026-02-04T19:20:23.963166Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83300/133889 blocks (62.2%), 0 events +2026-02-04T19:20:24.288520Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83310/133889 blocks (62.2%), 0 events +2026-02-04T19:20:24.401702Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83320/133889 blocks (62.2%), 0 events +2026-02-04T19:20:24.650939Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83330/133889 blocks (62.2%), 0 events +2026-02-04T19:20:24.841929Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83340/133889 blocks (62.2%), 0 events +2026-02-04T19:20:25.044114Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83350/133889 blocks (62.3%), 0 events +2026-02-04T19:20:25.202382Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83360/133889 blocks (62.3%), 0 events +2026-02-04T19:20:25.410915Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83370/133889 blocks (62.3%), 0 events +2026-02-04T19:20:25.703170Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83380/133889 blocks (62.3%), 0 events +2026-02-04T19:20:25.858528Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83390/133889 blocks (62.3%), 0 events +2026-02-04T19:20:25.998824Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83400/133889 blocks (62.3%), 0 events +2026-02-04T19:20:26.227047Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83410/133889 blocks (62.3%), 0 events +2026-02-04T19:20:26.441104Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83420/133889 blocks (62.3%), 0 events +2026-02-04T19:20:26.710645Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83430/133889 blocks (62.3%), 0 events +2026-02-04T19:20:26.809696Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83440/133889 blocks (62.3%), 0 events +2026-02-04T19:20:27.040029Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83450/133889 blocks (62.3%), 0 events +2026-02-04T19:20:27.268724Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83460/133889 blocks (62.3%), 0 events +2026-02-04T19:20:27.462861Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83470/133889 blocks (62.3%), 0 events +2026-02-04T19:20:27.577269Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83480/133889 blocks (62.3%), 0 events +2026-02-04T19:20:27.794536Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83490/133889 blocks (62.4%), 0 events +2026-02-04T19:20:27.990724Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83500/133889 blocks (62.4%), 0 events +2026-02-04T19:20:28.282344Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83510/133889 blocks (62.4%), 0 events +2026-02-04T19:20:28.529001Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83520/133889 blocks (62.4%), 0 events +2026-02-04T19:20:28.570592Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83530/133889 blocks (62.4%), 0 events +2026-02-04T19:20:28.843985Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83540/133889 blocks (62.4%), 0 events +2026-02-04T19:20:29.040039Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83550/133889 blocks (62.4%), 0 events +2026-02-04T19:20:29.169725Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83560/133889 blocks (62.4%), 0 events +2026-02-04T19:20:29.527677Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83570/133889 blocks (62.4%), 0 events +2026-02-04T19:20:29.570606Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83580/133889 blocks (62.4%), 0 events +2026-02-04T19:20:29.856395Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83590/133889 blocks (62.4%), 0 events +2026-02-04T19:20:30.063380Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83600/133889 blocks (62.4%), 0 events +2026-02-04T19:20:30.239722Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83610/133889 blocks (62.4%), 0 events +2026-02-04T19:20:30.413616Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83620/133889 blocks (62.5%), 0 events +2026-02-04T19:20:30.564455Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83630/133889 blocks (62.5%), 0 events +2026-02-04T19:20:30.940509Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83640/133889 blocks (62.5%), 0 events +2026-02-04T19:20:30.980564Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83650/133889 blocks (62.5%), 0 events +2026-02-04T19:20:31.213606Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83660/133889 blocks (62.5%), 0 events +2026-02-04T19:20:31.460912Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83670/133889 blocks (62.5%), 0 events +2026-02-04T19:20:31.645865Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83680/133889 blocks (62.5%), 0 events +2026-02-04T19:20:31.847593Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83690/133889 blocks (62.5%), 0 events +2026-02-04T19:20:32.046744Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83700/133889 blocks (62.5%), 0 events +2026-02-04T19:20:32.245546Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83710/133889 blocks (62.5%), 0 events +2026-02-04T19:20:32.516885Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83720/133889 blocks (62.5%), 0 events +2026-02-04T19:20:32.558226Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83730/133889 blocks (62.5%), 0 events +2026-02-04T19:20:32.810063Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83740/133889 blocks (62.5%), 0 events +2026-02-04T19:20:33.036283Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83750/133889 blocks (62.6%), 0 events +2026-02-04T19:20:33.181840Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83760/133889 blocks (62.6%), 0 events +2026-02-04T19:20:33.413809Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83770/133889 blocks (62.6%), 0 events +2026-02-04T19:20:33.582448Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83780/133889 blocks (62.6%), 0 events +2026-02-04T19:20:34.052453Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83790/133889 blocks (62.6%), 0 events +2026-02-04T19:20:34.091640Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83800/133889 blocks (62.6%), 0 events +2026-02-04T19:20:34.170544Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83810/133889 blocks (62.6%), 0 events +2026-02-04T19:20:34.437978Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83820/133889 blocks (62.6%), 0 events +2026-02-04T19:20:34.612514Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83830/133889 blocks (62.6%), 0 events +2026-02-04T19:20:34.809145Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83840/133889 blocks (62.6%), 0 events +2026-02-04T19:20:34.992671Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83850/133889 blocks (62.6%), 0 events +2026-02-04T19:20:35.246278Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83860/133889 blocks (62.6%), 0 events +2026-02-04T19:20:35.436221Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83870/133889 blocks (62.6%), 0 events +2026-02-04T19:20:35.660970Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83880/133889 blocks (62.6%), 0 events +2026-02-04T19:20:35.847151Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83890/133889 blocks (62.7%), 0 events +2026-02-04T19:20:35.996528Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83900/133889 blocks (62.7%), 0 events +2026-02-04T19:20:36.252666Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83910/133889 blocks (62.7%), 0 events +2026-02-04T19:20:36.457464Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83920/133889 blocks (62.7%), 0 events +2026-02-04T19:20:36.686615Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83930/133889 blocks (62.7%), 0 events +2026-02-04T19:20:36.824498Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83940/133889 blocks (62.7%), 0 events +2026-02-04T19:20:37.071636Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83950/133889 blocks (62.7%), 0 events +2026-02-04T19:20:37.230760Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83960/133889 blocks (62.7%), 0 events +2026-02-04T19:20:37.437839Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83970/133889 blocks (62.7%), 0 events +2026-02-04T19:20:37.720947Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83980/133889 blocks (62.7%), 0 events +2026-02-04T19:20:37.760485Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83990/133889 blocks (62.7%), 0 events +2026-02-04T19:20:37.978732Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84000/133889 blocks (62.7%), 0 events +2026-02-04T19:20:38.280450Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84010/133889 blocks (62.7%), 0 events +2026-02-04T19:20:38.412422Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84020/133889 blocks (62.8%), 0 events +2026-02-04T19:20:38.592381Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84030/133889 blocks (62.8%), 0 events +2026-02-04T19:20:38.808946Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84040/133889 blocks (62.8%), 0 events +2026-02-04T19:20:38.990969Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84050/133889 blocks (62.8%), 0 events +2026-02-04T19:20:39.165641Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84060/133889 blocks (62.8%), 0 events +2026-02-04T19:20:39.410022Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84070/133889 blocks (62.8%), 0 events +2026-02-04T19:20:39.657226Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84080/133889 blocks (62.8%), 0 events +2026-02-04T19:20:39.853097Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84090/133889 blocks (62.8%), 0 events +2026-02-04T19:20:40.019785Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84100/133889 blocks (62.8%), 0 events +2026-02-04T19:20:40.162782Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84110/133889 blocks (62.8%), 0 events +2026-02-04T19:20:40.372174Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84120/133889 blocks (62.8%), 0 events +2026-02-04T19:20:40.583372Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84130/133889 blocks (62.8%), 0 events +2026-02-04T19:20:40.897451Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84140/133889 blocks (62.8%), 0 events +2026-02-04T19:20:40.986822Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84150/133889 blocks (62.9%), 0 events +2026-02-04T19:20:41.256982Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84160/133889 blocks (62.9%), 0 events +2026-02-04T19:20:41.441226Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84170/133889 blocks (62.9%), 0 events +2026-02-04T19:20:41.566639Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84180/133889 blocks (62.9%), 0 events +2026-02-04T19:20:41.914351Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84190/133889 blocks (62.9%), 0 events +2026-02-04T19:20:41.952092Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84200/133889 blocks (62.9%), 0 events +2026-02-04T19:20:42.170905Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84210/133889 blocks (62.9%), 0 events +2026-02-04T19:20:42.438232Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84220/133889 blocks (62.9%), 0 events +2026-02-04T19:20:42.605651Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84230/133889 blocks (62.9%), 0 events +2026-02-04T19:20:42.831311Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84240/133889 blocks (62.9%), 0 events +2026-02-04T19:20:43.049604Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84250/133889 blocks (62.9%), 0 events +2026-02-04T19:20:43.216258Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84260/133889 blocks (62.9%), 0 events +2026-02-04T19:20:43.364732Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84270/133889 blocks (62.9%), 0 events +2026-02-04T19:20:43.599916Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84280/133889 blocks (62.9%), 0 events +2026-02-04T19:20:43.857000Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84290/133889 blocks (63.0%), 0 events +2026-02-04T19:20:44.052735Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84300/133889 blocks (63.0%), 0 events +2026-02-04T19:20:44.181808Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84310/133889 blocks (63.0%), 0 events +2026-02-04T19:20:44.538875Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84320/133889 blocks (63.0%), 0 events +2026-02-04T19:20:44.579591Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84330/133889 blocks (63.0%), 0 events +2026-02-04T19:20:44.776350Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84340/133889 blocks (63.0%), 0 events +2026-02-04T19:20:45.062448Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84350/133889 blocks (63.0%), 0 events +2026-02-04T19:20:45.234040Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84360/133889 blocks (63.0%), 0 events +2026-02-04T19:20:45.355497Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84370/133889 blocks (63.0%), 0 events +2026-02-04T19:20:45.614715Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84380/133889 blocks (63.0%), 0 events +2026-02-04T19:20:45.835549Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84390/133889 blocks (63.0%), 0 events +2026-02-04T19:20:46.107794Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84400/133889 blocks (63.0%), 0 events +2026-02-04T19:20:46.213918Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84410/133889 blocks (63.0%), 0 events +2026-02-04T19:20:46.412314Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84420/133889 blocks (63.1%), 0 events +2026-02-04T19:20:46.676907Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84430/133889 blocks (63.1%), 0 events +2026-02-04T19:20:46.806901Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84440/133889 blocks (63.1%), 0 events +2026-02-04T19:20:46.962139Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84450/133889 blocks (63.1%), 0 events +2026-02-04T19:20:47.259249Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84460/133889 blocks (63.1%), 0 events +2026-02-04T19:20:47.418471Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84470/133889 blocks (63.1%), 0 events +2026-02-04T19:20:47.579852Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84480/133889 blocks (63.1%), 0 events +2026-02-04T19:20:47.752193Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84490/133889 blocks (63.1%), 0 events +2026-02-04T19:20:47.990233Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84500/133889 blocks (63.1%), 0 events +2026-02-04T19:20:48.238092Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84510/133889 blocks (63.1%), 0 events +2026-02-04T19:20:48.420085Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84520/133889 blocks (63.1%), 0 events +2026-02-04T19:20:48.626147Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84530/133889 blocks (63.1%), 0 events +2026-02-04T19:20:48.763862Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84540/133889 blocks (63.1%), 0 events +2026-02-04T19:20:49.010108Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84550/133889 blocks (63.1%), 0 events +2026-02-04T19:20:49.286945Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84560/133889 blocks (63.2%), 0 events +2026-02-04T19:20:49.350769Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84570/133889 blocks (63.2%), 0 events +2026-02-04T19:20:49.571043Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84580/133889 blocks (63.2%), 0 events +2026-02-04T19:20:49.839383Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84590/133889 blocks (63.2%), 0 events +2026-02-04T19:20:49.970072Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84600/133889 blocks (63.2%), 0 events +2026-02-04T19:20:50.301935Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84610/133889 blocks (63.2%), 0 events +2026-02-04T19:20:50.418749Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84620/133889 blocks (63.2%), 0 events +2026-02-04T19:20:50.647106Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84630/133889 blocks (63.2%), 0 events +2026-02-04T19:20:50.874973Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84640/133889 blocks (63.2%), 0 events +2026-02-04T19:20:50.958215Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84650/133889 blocks (63.2%), 0 events +2026-02-04T19:20:51.193047Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84660/133889 blocks (63.2%), 0 events +2026-02-04T19:20:51.403071Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84670/133889 blocks (63.2%), 0 events +2026-02-04T19:20:51.637082Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84680/133889 blocks (63.2%), 0 events +2026-02-04T19:20:51.913687Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84690/133889 blocks (63.3%), 0 events +2026-02-04T19:20:52.007783Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84700/133889 blocks (63.3%), 0 events +2026-02-04T19:20:52.189677Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84710/133889 blocks (63.3%), 0 events +2026-02-04T19:20:52.432305Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84720/133889 blocks (63.3%), 0 events +2026-02-04T19:20:52.560338Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84730/133889 blocks (63.3%), 0 events +2026-02-04T19:20:52.922122Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84740/133889 blocks (63.3%), 0 events +2026-02-04T19:20:52.956421Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84750/133889 blocks (63.3%), 0 events +2026-02-04T19:20:53.219461Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84760/133889 blocks (63.3%), 0 events +2026-02-04T19:20:53.485784Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84770/133889 blocks (63.3%), 0 events +2026-02-04T19:20:53.652318Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84780/133889 blocks (63.3%), 0 events +2026-02-04T19:20:53.829294Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84790/133889 blocks (63.3%), 0 events +2026-02-04T19:20:54.025230Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84800/133889 blocks (63.3%), 0 events +2026-02-04T19:20:54.235721Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84810/133889 blocks (63.3%), 0 events +2026-02-04T19:20:54.359097Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84820/133889 blocks (63.4%), 0 events +2026-02-04T19:20:54.607236Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84830/133889 blocks (63.4%), 0 events +2026-02-04T19:20:54.833960Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84840/133889 blocks (63.4%), 0 events +2026-02-04T19:20:55.056334Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84850/133889 blocks (63.4%), 0 events +2026-02-04T19:20:55.165985Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84860/133889 blocks (63.4%), 0 events +2026-02-04T19:20:55.449814Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84870/133889 blocks (63.4%), 0 events +2026-02-04T19:20:55.657050Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84880/133889 blocks (63.4%), 0 events +2026-02-04T19:20:55.809477Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84890/133889 blocks (63.4%), 0 events +2026-02-04T19:20:56.070966Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84900/133889 blocks (63.4%), 0 events +2026-02-04T19:20:56.187746Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84910/133889 blocks (63.4%), 0 events +2026-02-04T19:20:56.408789Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84920/133889 blocks (63.4%), 0 events +2026-02-04T19:20:56.628232Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84930/133889 blocks (63.4%), 0 events +2026-02-04T19:20:56.849015Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84940/133889 blocks (63.4%), 0 events +2026-02-04T19:20:57.118392Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84950/133889 blocks (63.4%), 0 events +2026-02-04T19:20:57.161068Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84960/133889 blocks (63.5%), 0 events +2026-02-04T19:20:57.442251Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84970/133889 blocks (63.5%), 0 events +2026-02-04T19:20:57.640693Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84980/133889 blocks (63.5%), 0 events +2026-02-04T19:20:57.856248Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84990/133889 blocks (63.5%), 0 events +2026-02-04T19:20:57.976142Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85000/133889 blocks (63.5%), 0 events +2026-02-04T19:20:58.240357Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85010/133889 blocks (63.5%), 0 events +2026-02-04T19:20:58.370113Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85020/133889 blocks (63.5%), 0 events +2026-02-04T19:20:58.693372Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85030/133889 blocks (63.5%), 0 events +2026-02-04T19:20:58.853131Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85040/133889 blocks (63.5%), 0 events +2026-02-04T19:20:59.038434Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85050/133889 blocks (63.5%), 0 events +2026-02-04T19:20:59.249597Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85060/133889 blocks (63.5%), 0 events +2026-02-04T19:20:59.447328Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85070/133889 blocks (63.5%), 0 events +2026-02-04T19:20:59.604670Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85080/133889 blocks (63.5%), 0 events +2026-02-04T19:20:59.776281Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85090/133889 blocks (63.6%), 0 events +2026-02-04T19:20:59.992829Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85100/133889 blocks (63.6%), 0 events +2026-02-04T19:21:00.264479Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85110/133889 blocks (63.6%), 0 events +2026-02-04T19:21:00.492453Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85120/133889 blocks (63.6%), 0 events +2026-02-04T19:21:00.564719Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85130/133889 blocks (63.6%), 0 events +2026-02-04T19:21:00.817246Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85140/133889 blocks (63.6%), 0 events +2026-02-04T19:21:01.042622Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85150/133889 blocks (63.6%), 0 events +2026-02-04T19:21:01.183107Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85160/133889 blocks (63.6%), 0 events +2026-02-04T19:21:01.445645Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85170/133889 blocks (63.6%), 0 events +2026-02-04T19:21:01.586147Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85180/133889 blocks (63.6%), 0 events +2026-02-04T19:21:01.869235Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85190/133889 blocks (63.6%), 0 events +2026-02-04T19:21:02.064663Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85200/133889 blocks (63.6%), 0 events +2026-02-04T19:21:02.251568Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85210/133889 blocks (63.6%), 0 events +2026-02-04T19:21:02.425562Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85220/133889 blocks (63.6%), 0 events +2026-02-04T19:21:02.587938Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85230/133889 blocks (63.7%), 0 events +2026-02-04T19:21:02.924851Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85240/133889 blocks (63.7%), 0 events +2026-02-04T19:21:02.966139Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85250/133889 blocks (63.7%), 0 events +2026-02-04T19:21:03.188896Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85260/133889 blocks (63.7%), 0 events +2026-02-04T19:21:03.440425Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85270/133889 blocks (63.7%), 0 events +2026-02-04T19:21:03.644460Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85280/133889 blocks (63.7%), 0 events +2026-02-04T19:21:03.777657Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85290/133889 blocks (63.7%), 0 events +2026-02-04T19:21:04.029879Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85300/133889 blocks (63.7%), 0 events +2026-02-04T19:21:04.250568Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85310/133889 blocks (63.7%), 0 events +2026-02-04T19:21:04.491080Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85320/133889 blocks (63.7%), 0 events +2026-02-04T19:21:04.654891Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85330/133889 blocks (63.7%), 0 events +2026-02-04T19:21:04.847584Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85340/133889 blocks (63.7%), 0 events +2026-02-04T19:21:05.031645Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85350/133889 blocks (63.7%), 0 events +2026-02-04T19:21:05.210310Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85360/133889 blocks (63.8%), 0 events +2026-02-04T19:21:05.389742Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85370/133889 blocks (63.8%), 0 events +2026-02-04T19:21:05.592500Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85380/133889 blocks (63.8%), 0 events +2026-02-04T19:21:05.755137Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85390/133889 blocks (63.8%), 0 events +2026-02-04T19:21:06.067083Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85400/133889 blocks (63.8%), 0 events +2026-02-04T19:21:06.258300Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85410/133889 blocks (63.8%), 0 events +2026-02-04T19:21:06.383040Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85420/133889 blocks (63.8%), 0 events +2026-02-04T19:21:06.603084Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85430/133889 blocks (63.8%), 0 events +2026-02-04T19:21:06.832611Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85440/133889 blocks (63.8%), 0 events +2026-02-04T19:21:07.113014Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85450/133889 blocks (63.8%), 0 events +2026-02-04T19:21:07.317575Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85460/133889 blocks (63.8%), 0 events +2026-02-04T19:21:07.362578Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85470/133889 blocks (63.8%), 0 events +2026-02-04T19:21:07.647288Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85480/133889 blocks (63.8%), 0 events +2026-02-04T19:21:07.832607Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85490/133889 blocks (63.9%), 0 events +2026-02-04T19:21:08.001105Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85500/133889 blocks (63.9%), 0 events +2026-02-04T19:21:08.232443Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85510/133889 blocks (63.9%), 0 events +2026-02-04T19:21:08.373144Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85520/133889 blocks (63.9%), 0 events +2026-02-04T19:21:08.684625Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85530/133889 blocks (63.9%), 0 events +2026-02-04T19:21:08.847523Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85540/133889 blocks (63.9%), 0 events +2026-02-04T19:21:08.968525Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85550/133889 blocks (63.9%), 0 events +2026-02-04T19:21:09.209429Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85560/133889 blocks (63.9%), 0 events +2026-02-04T19:21:09.422077Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85570/133889 blocks (63.9%), 0 events +2026-02-04T19:21:09.581946Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85580/133889 blocks (63.9%), 0 events +2026-02-04T19:21:09.899407Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85590/133889 blocks (63.9%), 0 events +2026-02-04T19:21:10.012081Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85600/133889 blocks (63.9%), 0 events +2026-02-04T19:21:10.260963Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85610/133889 blocks (63.9%), 0 events +2026-02-04T19:21:10.413838Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85620/133889 blocks (63.9%), 0 events +2026-02-04T19:21:10.558677Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85630/133889 blocks (64.0%), 0 events +2026-02-04T19:21:10.794115Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85640/133889 blocks (64.0%), 0 events +2026-02-04T19:21:11.059157Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85650/133889 blocks (64.0%), 0 events +2026-02-04T19:21:11.274865Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85660/133889 blocks (64.0%), 0 events +2026-02-04T19:21:11.382493Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85670/133889 blocks (64.0%), 0 events +2026-02-04T19:21:11.576785Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85680/133889 blocks (64.0%), 0 events +2026-02-04T19:21:11.904776Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85690/133889 blocks (64.0%), 0 events +2026-02-04T19:21:11.974092Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85700/133889 blocks (64.0%), 0 events +2026-02-04T19:21:12.321395Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85710/133889 blocks (64.0%), 0 events +2026-02-04T19:21:12.354744Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85720/133889 blocks (64.0%), 0 events +2026-02-04T19:21:12.653638Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85730/133889 blocks (64.0%), 0 events +2026-02-04T19:21:12.881802Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85740/133889 blocks (64.0%), 0 events +2026-02-04T19:21:13.044534Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85750/133889 blocks (64.0%), 0 events +2026-02-04T19:21:13.172676Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85760/133889 blocks (64.1%), 0 events +2026-02-04T19:21:13.403553Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85770/133889 blocks (64.1%), 0 events +2026-02-04T19:21:13.635505Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85780/133889 blocks (64.1%), 0 events +2026-02-04T19:21:13.793888Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85790/133889 blocks (64.1%), 0 events +2026-02-04T19:21:13.991782Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85800/133889 blocks (64.1%), 0 events +2026-02-04T19:21:14.263434Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85810/133889 blocks (64.1%), 0 events +2026-02-04T19:21:14.419844Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85820/133889 blocks (64.1%), 0 events +2026-02-04T19:21:14.603777Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85830/133889 blocks (64.1%), 0 events +2026-02-04T19:21:14.806727Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85840/133889 blocks (64.1%), 0 events +2026-02-04T19:21:15.018652Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85850/133889 blocks (64.1%), 0 events +2026-02-04T19:21:15.185759Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85860/133889 blocks (64.1%), 0 events +2026-02-04T19:21:15.504680Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85870/133889 blocks (64.1%), 0 events +2026-02-04T19:21:15.569853Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85880/133889 blocks (64.1%), 0 events +2026-02-04T19:21:15.786283Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85890/133889 blocks (64.1%), 0 events +2026-02-04T19:21:16.026302Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85900/133889 blocks (64.2%), 0 events +2026-02-04T19:21:16.221208Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85910/133889 blocks (64.2%), 0 events +2026-02-04T19:21:16.520490Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85920/133889 blocks (64.2%), 0 events +2026-02-04T19:21:16.558166Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85930/133889 blocks (64.2%), 0 events +2026-02-04T19:21:16.810219Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85940/133889 blocks (64.2%), 0 events +2026-02-04T19:21:17.072861Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85950/133889 blocks (64.2%), 0 events +2026-02-04T19:21:17.273299Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85960/133889 blocks (64.2%), 0 events +2026-02-04T19:21:17.449448Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85970/133889 blocks (64.2%), 0 events +2026-02-04T19:21:17.595294Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85980/133889 blocks (64.2%), 0 events +2026-02-04T19:21:17.818741Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85990/133889 blocks (64.2%), 0 events +2026-02-04T19:21:17.984747Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86000/133889 blocks (64.2%), 0 events +2026-02-04T19:21:18.325648Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86010/133889 blocks (64.2%), 0 events +2026-02-04T19:21:18.361261Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86020/133889 blocks (64.2%), 0 events +2026-02-04T19:21:18.646879Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86030/133889 blocks (64.3%), 0 events +2026-02-04T19:21:18.848479Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86040/133889 blocks (64.3%), 0 events +2026-02-04T19:21:18.982514Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86050/133889 blocks (64.3%), 0 events +2026-02-04T19:21:19.239826Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86060/133889 blocks (64.3%), 0 events +2026-02-04T19:21:19.462452Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86070/133889 blocks (64.3%), 0 events +2026-02-04T19:21:19.695539Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86080/133889 blocks (64.3%), 0 events +2026-02-04T19:21:19.861899Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86090/133889 blocks (64.3%), 0 events +2026-02-04T19:21:19.982250Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86100/133889 blocks (64.3%), 0 events +2026-02-04T19:21:20.223748Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86110/133889 blocks (64.3%), 0 events +2026-02-04T19:21:20.389345Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86120/133889 blocks (64.3%), 0 events +2026-02-04T19:21:20.586153Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86130/133889 blocks (64.3%), 0 events +2026-02-04T19:21:20.776426Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86140/133889 blocks (64.3%), 0 events +2026-02-04T19:21:21.049107Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86150/133889 blocks (64.3%), 0 events +2026-02-04T19:21:21.236461Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86160/133889 blocks (64.4%), 0 events +2026-02-04T19:21:21.469708Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86170/133889 blocks (64.4%), 0 events +2026-02-04T19:21:21.619523Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86180/133889 blocks (64.4%), 0 events +2026-02-04T19:21:21.804317Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86190/133889 blocks (64.4%), 0 events +2026-02-04T19:21:21.989849Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86200/133889 blocks (64.4%), 0 events +2026-02-04T19:21:22.318667Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86210/133889 blocks (64.4%), 0 events +2026-02-04T19:21:22.362919Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86220/133889 blocks (64.4%), 0 events +2026-02-04T19:21:22.579431Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86230/133889 blocks (64.4%), 0 events +2026-02-04T19:21:22.843991Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86240/133889 blocks (64.4%), 0 events +2026-02-04T19:21:22.984802Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86250/133889 blocks (64.4%), 0 events +2026-02-04T19:21:23.210691Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86260/133889 blocks (64.4%), 0 events +2026-02-04T19:21:23.411584Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86270/133889 blocks (64.4%), 0 events +2026-02-04T19:21:23.629848Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86280/133889 blocks (64.4%), 0 events +2026-02-04T19:21:23.888493Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86290/133889 blocks (64.4%), 0 events +2026-02-04T19:21:23.971920Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86300/133889 blocks (64.5%), 0 events +2026-02-04T19:21:24.221679Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86310/133889 blocks (64.5%), 0 events +2026-02-04T19:21:24.431402Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86320/133889 blocks (64.5%), 0 events +2026-02-04T19:21:24.607225Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86330/133889 blocks (64.5%), 0 events +2026-02-04T19:21:24.786225Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86340/133889 blocks (64.5%), 0 events +2026-02-04T19:21:25.036472Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86350/133889 blocks (64.5%), 0 events +2026-02-04T19:21:25.208819Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86360/133889 blocks (64.5%), 0 events +2026-02-04T19:21:25.464884Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86370/133889 blocks (64.5%), 0 events +2026-02-04T19:21:25.644519Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86380/133889 blocks (64.5%), 0 events +2026-02-04T19:21:25.863369Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86390/133889 blocks (64.5%), 0 events +2026-02-04T19:21:25.990171Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86400/133889 blocks (64.5%), 0 events +2026-02-04T19:21:26.161716Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86410/133889 blocks (64.5%), 0 events +2026-02-04T19:21:26.547487Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86420/133889 blocks (64.5%), 0 events +2026-02-04T19:21:26.602471Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86430/133889 blocks (64.6%), 0 events +2026-02-04T19:21:26.789321Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86440/133889 blocks (64.6%), 0 events +2026-02-04T19:21:27.038891Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86450/133889 blocks (64.6%), 0 events +2026-02-04T19:21:27.218615Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86460/133889 blocks (64.6%), 0 events +2026-02-04T19:21:27.381796Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86470/133889 blocks (64.6%), 0 events +2026-02-04T19:21:27.650182Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86480/133889 blocks (64.6%), 0 events +2026-02-04T19:21:27.820550Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86490/133889 blocks (64.6%), 0 events +2026-02-04T19:21:28.049978Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86500/133889 blocks (64.6%), 0 events +2026-02-04T19:21:28.178691Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86510/133889 blocks (64.6%), 0 events +2026-02-04T19:21:28.381710Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86520/133889 blocks (64.6%), 0 events +2026-02-04T19:21:28.645846Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86530/133889 blocks (64.6%), 0 events +2026-02-04T19:21:28.813338Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86540/133889 blocks (64.6%), 0 events +2026-02-04T19:21:28.988696Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86550/133889 blocks (64.6%), 0 events +2026-02-04T19:21:29.224268Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86560/133889 blocks (64.7%), 0 events +2026-02-04T19:21:29.402738Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86570/133889 blocks (64.7%), 0 events +2026-02-04T19:21:29.665332Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86580/133889 blocks (64.7%), 0 events +2026-02-04T19:21:29.810767Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86590/133889 blocks (64.7%), 0 events +2026-02-04T19:21:30.035718Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86600/133889 blocks (64.7%), 0 events +2026-02-04T19:21:30.180397Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86610/133889 blocks (64.7%), 0 events +2026-02-04T19:21:30.446516Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86620/133889 blocks (64.7%), 0 events +2026-02-04T19:21:30.709348Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86630/133889 blocks (64.7%), 0 events +2026-02-04T19:21:30.897959Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86640/133889 blocks (64.7%), 0 events +2026-02-04T19:21:31.030460Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86650/133889 blocks (64.7%), 0 events +2026-02-04T19:21:31.230911Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86660/133889 blocks (64.7%), 0 events +2026-02-04T19:21:31.430063Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86670/133889 blocks (64.7%), 0 events +2026-02-04T19:21:31.580814Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86680/133889 blocks (64.7%), 0 events +2026-02-04T19:21:31.777917Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86690/133889 blocks (64.7%), 0 events +2026-02-04T19:21:32.010803Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86700/133889 blocks (64.8%), 0 events +2026-02-04T19:21:32.281710Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86710/133889 blocks (64.8%), 0 events +2026-02-04T19:21:32.473256Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86720/133889 blocks (64.8%), 0 events +2026-02-04T19:21:32.566651Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86730/133889 blocks (64.8%), 0 events +2026-02-04T19:21:32.801297Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86740/133889 blocks (64.8%), 0 events +2026-02-04T19:21:33.034503Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86750/133889 blocks (64.8%), 0 events +2026-02-04T19:21:33.324962Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86760/133889 blocks (64.8%), 0 events +2026-02-04T19:21:33.359410Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86770/133889 blocks (64.8%), 0 events +2026-02-04T19:21:33.585611Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86780/133889 blocks (64.8%), 0 events +2026-02-04T19:21:33.847635Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86790/133889 blocks (64.8%), 0 events +2026-02-04T19:21:33.965585Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86800/133889 blocks (64.8%), 0 events +2026-02-04T19:21:34.223698Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86810/133889 blocks (64.8%), 0 events +2026-02-04T19:21:34.445222Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86820/133889 blocks (64.8%), 0 events +2026-02-04T19:21:34.588973Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86830/133889 blocks (64.9%), 0 events +2026-02-04T19:21:34.902060Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86840/133889 blocks (64.9%), 0 events +2026-02-04T19:21:35.060066Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86850/133889 blocks (64.9%), 0 events +2026-02-04T19:21:35.225398Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86860/133889 blocks (64.9%), 0 events +2026-02-04T19:21:35.419832Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86870/133889 blocks (64.9%), 0 events +2026-02-04T19:21:35.791769Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86880/133889 blocks (64.9%), 0 events +2026-02-04T19:21:35.912727Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86890/133889 blocks (64.9%), 0 events +2026-02-04T19:21:35.963817Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86900/133889 blocks (64.9%), 0 events +2026-02-04T19:21:36.193207Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86910/133889 blocks (64.9%), 0 events +2026-02-04T19:21:36.441018Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86920/133889 blocks (64.9%), 0 events +2026-02-04T19:21:36.633551Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86930/133889 blocks (64.9%), 0 events +2026-02-04T19:21:36.799908Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86940/133889 blocks (64.9%), 0 events +2026-02-04T19:21:37.014498Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86950/133889 blocks (64.9%), 0 events +2026-02-04T19:21:37.191870Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86960/133889 blocks (64.9%), 0 events +2026-02-04T19:21:37.368475Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86970/133889 blocks (65.0%), 0 events +2026-02-04T19:21:37.719648Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86980/133889 blocks (65.0%), 0 events +2026-02-04T19:21:37.754619Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86990/133889 blocks (65.0%), 0 events +2026-02-04T19:21:38.042540Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87000/133889 blocks (65.0%), 0 events +2026-02-04T19:21:38.245542Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87010/133889 blocks (65.0%), 0 events +2026-02-04T19:21:38.411285Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87020/133889 blocks (65.0%), 0 events +2026-02-04T19:21:38.568513Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87030/133889 blocks (65.0%), 0 events +2026-02-04T19:21:38.850662Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87040/133889 blocks (65.0%), 0 events +2026-02-04T19:21:39.107209Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87050/133889 blocks (65.0%), 0 events +2026-02-04T19:21:39.254931Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87060/133889 blocks (65.0%), 0 events +2026-02-04T19:21:39.429821Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87070/133889 blocks (65.0%), 0 events +2026-02-04T19:21:39.653900Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87080/133889 blocks (65.0%), 0 events +2026-02-04T19:21:39.814234Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87090/133889 blocks (65.0%), 0 events +2026-02-04T19:21:40.106858Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87100/133889 blocks (65.1%), 0 events +2026-02-04T19:21:40.177062Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87110/133889 blocks (65.1%), 0 events +2026-02-04T19:21:40.412774Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87120/133889 blocks (65.1%), 0 events +2026-02-04T19:21:40.665532Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87130/133889 blocks (65.1%), 0 events +2026-02-04T19:21:40.867465Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87140/133889 blocks (65.1%), 0 events +2026-02-04T19:21:40.958652Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87150/133889 blocks (65.1%), 0 events +2026-02-04T19:21:41.252283Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87160/133889 blocks (65.1%), 0 events +2026-02-04T19:21:41.453544Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87170/133889 blocks (65.1%), 0 events +2026-02-04T19:21:41.713474Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87180/133889 blocks (65.1%), 0 events +2026-02-04T19:21:41.911814Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87190/133889 blocks (65.1%), 0 events +2026-02-04T19:21:42.040782Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87200/133889 blocks (65.1%), 0 events +2026-02-04T19:21:42.242884Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87210/133889 blocks (65.1%), 0 events +2026-02-04T19:21:42.437003Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87220/133889 blocks (65.1%), 0 events +2026-02-04T19:21:42.729777Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87230/133889 blocks (65.2%), 0 events +2026-02-04T19:21:42.771372Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87240/133889 blocks (65.2%), 0 events +2026-02-04T19:21:43.256024Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87250/133889 blocks (65.2%), 0 events +2026-02-04T19:21:43.294606Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87260/133889 blocks (65.2%), 0 events +2026-02-04T19:21:43.483045Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87270/133889 blocks (65.2%), 0 events +2026-02-04T19:21:43.584274Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87280/133889 blocks (65.2%), 0 events +2026-02-04T19:21:43.812662Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87290/133889 blocks (65.2%), 0 events +2026-02-04T19:21:44.007853Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87300/133889 blocks (65.2%), 0 events +2026-02-04T19:21:44.181271Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87310/133889 blocks (65.2%), 0 events +2026-02-04T19:21:44.363071Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87320/133889 blocks (65.2%), 0 events +2026-02-04T19:21:44.639722Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87330/133889 blocks (65.2%), 0 events +2026-02-04T19:21:44.856800Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87340/133889 blocks (65.2%), 0 events +2026-02-04T19:21:45.062770Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87350/133889 blocks (65.2%), 0 events +2026-02-04T19:21:45.243427Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87360/133889 blocks (65.2%), 0 events +2026-02-04T19:21:45.445360Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87370/133889 blocks (65.3%), 0 events +2026-02-04T19:21:45.635202Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87380/133889 blocks (65.3%), 0 events +2026-02-04T19:21:45.912176Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87390/133889 blocks (65.3%), 0 events +2026-02-04T19:21:45.951755Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87400/133889 blocks (65.3%), 0 events +2026-02-04T19:21:46.241016Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87410/133889 blocks (65.3%), 0 events +2026-02-04T19:21:46.432599Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87420/133889 blocks (65.3%), 0 events +2026-02-04T19:21:46.604391Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87430/133889 blocks (65.3%), 0 events +2026-02-04T19:21:46.794342Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87440/133889 blocks (65.3%), 0 events +2026-02-04T19:21:47.065700Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87450/133889 blocks (65.3%), 0 events +2026-02-04T19:21:47.202364Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87460/133889 blocks (65.3%), 0 events +2026-02-04T19:21:47.485351Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87470/133889 blocks (65.3%), 0 events +2026-02-04T19:21:47.595809Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87480/133889 blocks (65.3%), 0 events +2026-02-04T19:21:47.836610Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87490/133889 blocks (65.3%), 0 events +2026-02-04T19:21:48.007132Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87500/133889 blocks (65.4%), 0 events +2026-02-04T19:21:48.201117Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87510/133889 blocks (65.4%), 0 events +2026-02-04T19:21:48.396830Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87520/133889 blocks (65.4%), 0 events +2026-02-04T19:21:48.641778Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87530/133889 blocks (65.4%), 0 events +2026-02-04T19:21:48.856589Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87540/133889 blocks (65.4%), 0 events +2026-02-04T19:21:49.075984Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87550/133889 blocks (65.4%), 0 events +2026-02-04T19:21:49.180231Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87560/133889 blocks (65.4%), 0 events +2026-02-04T19:21:49.396391Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87570/133889 blocks (65.4%), 0 events +2026-02-04T19:21:49.630965Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87580/133889 blocks (65.4%), 0 events +2026-02-04T19:21:49.777385Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87590/133889 blocks (65.4%), 0 events +2026-02-04T19:21:50.103956Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87600/133889 blocks (65.4%), 0 events +2026-02-04T19:21:50.274059Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87610/133889 blocks (65.4%), 0 events +2026-02-04T19:21:50.382488Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87620/133889 blocks (65.4%), 0 events +2026-02-04T19:21:50.632503Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87630/133889 blocks (65.4%), 0 events +2026-02-04T19:21:50.766178Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87640/133889 blocks (65.5%), 0 events +2026-02-04T19:21:50.993879Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87650/133889 blocks (65.5%), 0 events +2026-02-04T19:21:51.244238Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87660/133889 blocks (65.5%), 0 events +2026-02-04T19:21:51.409003Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87670/133889 blocks (65.5%), 0 events +2026-02-04T19:21:51.677655Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87680/133889 blocks (65.5%), 0 events +2026-02-04T19:21:51.847061Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87690/133889 blocks (65.5%), 0 events +2026-02-04T19:21:52.231011Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87700/133889 blocks (65.5%), 0 events +2026-02-04T19:21:52.312623Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87710/133889 blocks (65.5%), 0 events +2026-02-04T19:21:52.388131Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87720/133889 blocks (65.5%), 0 events +2026-02-04T19:21:52.690221Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87730/133889 blocks (65.5%), 0 events +2026-02-04T19:21:52.818889Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87740/133889 blocks (65.5%), 0 events +2026-02-04T19:21:53.013247Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87750/133889 blocks (65.5%), 0 events +2026-02-04T19:21:53.268087Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87760/133889 blocks (65.5%), 0 events +2026-02-04T19:21:53.401100Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87770/133889 blocks (65.6%), 0 events +2026-02-04T19:21:53.739527Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87780/133889 blocks (65.6%), 0 events +2026-02-04T19:21:53.779356Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87790/133889 blocks (65.6%), 0 events +2026-02-04T19:21:53.968663Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87800/133889 blocks (65.6%), 0 events +2026-02-04T19:21:54.263303Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87810/133889 blocks (65.6%), 0 events +2026-02-04T19:21:54.374415Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87820/133889 blocks (65.6%), 0 events +2026-02-04T19:21:54.630442Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87830/133889 blocks (65.6%), 0 events +2026-02-04T19:21:54.838728Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87840/133889 blocks (65.6%), 0 events +2026-02-04T19:21:55.057027Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87850/133889 blocks (65.6%), 0 events +2026-02-04T19:21:55.158752Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87860/133889 blocks (65.6%), 0 events +2026-02-04T19:21:55.442908Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87870/133889 blocks (65.6%), 0 events +2026-02-04T19:21:55.610930Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87880/133889 blocks (65.6%), 0 events +2026-02-04T19:21:55.836505Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87890/133889 blocks (65.6%), 0 events +2026-02-04T19:21:56.040880Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87900/133889 blocks (65.7%), 0 events +2026-02-04T19:21:56.216746Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87910/133889 blocks (65.7%), 0 events +2026-02-04T19:21:56.428351Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87920/133889 blocks (65.7%), 0 events +2026-02-04T19:21:56.661630Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87930/133889 blocks (65.7%), 0 events +2026-02-04T19:21:56.884600Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87940/133889 blocks (65.7%), 0 events +2026-02-04T19:21:57.021311Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87950/133889 blocks (65.7%), 0 events +2026-02-04T19:21:57.218263Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87960/133889 blocks (65.7%), 0 events +2026-02-04T19:21:57.442292Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87970/133889 blocks (65.7%), 0 events +2026-02-04T19:21:57.554606Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87980/133889 blocks (65.7%), 0 events +2026-02-04T19:21:57.767430Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87990/133889 blocks (65.7%), 0 events +2026-02-04T19:21:58.012823Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88000/133889 blocks (65.7%), 0 events +2026-02-04T19:21:58.213828Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88010/133889 blocks (65.7%), 0 events +2026-02-04T19:21:58.488232Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88020/133889 blocks (65.7%), 0 events +2026-02-04T19:21:58.615063Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88030/133889 blocks (65.7%), 0 events +2026-02-04T19:21:58.834957Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88040/133889 blocks (65.8%), 0 events +2026-02-04T19:21:59.012168Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88050/133889 blocks (65.8%), 0 events +2026-02-04T19:21:59.227136Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88060/133889 blocks (65.8%), 0 events +2026-02-04T19:21:59.398299Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88070/133889 blocks (65.8%), 0 events +2026-02-04T19:21:59.614517Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88080/133889 blocks (65.8%), 0 events +2026-02-04T19:21:59.845538Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88090/133889 blocks (65.8%), 0 events +2026-02-04T19:22:00.109396Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88100/133889 blocks (65.8%), 0 events +2026-02-04T19:22:00.231689Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88110/133889 blocks (65.8%), 0 events +2026-02-04T19:22:00.402306Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88120/133889 blocks (65.8%), 0 events +2026-02-04T19:22:00.617528Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88130/133889 blocks (65.8%), 0 events +2026-02-04T19:22:00.808270Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88140/133889 blocks (65.8%), 0 events +2026-02-04T19:22:01.078086Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88150/133889 blocks (65.8%), 0 events +2026-02-04T19:22:01.271075Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88160/133889 blocks (65.8%), 0 events +2026-02-04T19:22:01.431099Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88170/133889 blocks (65.9%), 0 events +2026-02-04T19:22:01.637928Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88180/133889 blocks (65.9%), 0 events +2026-02-04T19:22:01.810176Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88190/133889 blocks (65.9%), 0 events +2026-02-04T19:22:01.999015Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88200/133889 blocks (65.9%), 0 events +2026-02-04T19:22:02.204705Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88210/133889 blocks (65.9%), 0 events +2026-02-04T19:22:02.435705Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88220/133889 blocks (65.9%), 0 events +2026-02-04T19:22:02.654230Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88230/133889 blocks (65.9%), 0 events +2026-02-04T19:22:02.833894Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88240/133889 blocks (65.9%), 0 events +2026-02-04T19:22:03.031236Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88250/133889 blocks (65.9%), 0 events +2026-02-04T19:22:03.205963Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88260/133889 blocks (65.9%), 0 events +2026-02-04T19:22:03.383486Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88270/133889 blocks (65.9%), 0 events +2026-02-04T19:22:03.698882Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88280/133889 blocks (65.9%), 0 events +2026-02-04T19:22:03.804852Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88290/133889 blocks (65.9%), 0 events +2026-02-04T19:22:03.967319Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88300/133889 blocks (65.9%), 0 events +2026-02-04T19:22:04.264085Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88310/133889 blocks (66.0%), 0 events +2026-02-04T19:22:04.438903Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88320/133889 blocks (66.0%), 0 events +2026-02-04T19:22:04.640863Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88330/133889 blocks (66.0%), 0 events +2026-02-04T19:22:04.833328Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88340/133889 blocks (66.0%), 0 events +2026-02-04T19:22:05.026899Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88350/133889 blocks (66.0%), 0 events +2026-02-04T19:22:05.271802Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88360/133889 blocks (66.0%), 0 events +2026-02-04T19:22:05.433144Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88370/133889 blocks (66.0%), 0 events +2026-02-04T19:22:05.611942Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88380/133889 blocks (66.0%), 0 events +2026-02-04T19:22:05.839501Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88390/133889 blocks (66.0%), 0 events +2026-02-04T19:22:05.985426Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88400/133889 blocks (66.0%), 0 events +2026-02-04T19:22:06.320979Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88410/133889 blocks (66.0%), 0 events +2026-02-04T19:22:06.366067Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88420/133889 blocks (66.0%), 0 events +2026-02-04T19:22:06.625089Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88430/133889 blocks (66.0%), 0 events +2026-02-04T19:22:06.881350Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88440/133889 blocks (66.1%), 0 events +2026-02-04T19:22:06.988436Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88450/133889 blocks (66.1%), 0 events +2026-02-04T19:22:07.168450Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88460/133889 blocks (66.1%), 0 events +2026-02-04T19:22:07.429921Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88470/133889 blocks (66.1%), 0 events +2026-02-04T19:22:07.561166Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88480/133889 blocks (66.1%), 0 events +2026-02-04T19:22:07.893951Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88490/133889 blocks (66.1%), 0 events +2026-02-04T19:22:07.998676Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88500/133889 blocks (66.1%), 0 events +2026-02-04T19:22:08.243616Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88510/133889 blocks (66.1%), 0 events +2026-02-04T19:22:08.450370Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88520/133889 blocks (66.1%), 0 events +2026-02-04T19:22:08.653519Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88530/133889 blocks (66.1%), 0 events +2026-02-04T19:22:08.769691Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88540/133889 blocks (66.1%), 0 events +2026-02-04T19:22:09.042894Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88550/133889 blocks (66.1%), 0 events +2026-02-04T19:22:09.190314Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88560/133889 blocks (66.1%), 0 events +2026-02-04T19:22:09.497964Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88570/133889 blocks (66.2%), 0 events +2026-02-04T19:22:09.578602Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88580/133889 blocks (66.2%), 0 events +2026-02-04T19:22:09.844906Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88590/133889 blocks (66.2%), 0 events +2026-02-04T19:22:10.028373Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88600/133889 blocks (66.2%), 0 events +2026-02-04T19:22:10.189286Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88610/133889 blocks (66.2%), 0 events +2026-02-04T19:22:10.403811Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88620/133889 blocks (66.2%), 0 events +2026-02-04T19:22:10.609151Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88630/133889 blocks (66.2%), 0 events +2026-02-04T19:22:10.784289Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88640/133889 blocks (66.2%), 0 events +2026-02-04T19:22:11.167717Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88650/133889 blocks (66.2%), 0 events +2026-02-04T19:22:11.205223Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88660/133889 blocks (66.2%), 0 events +2026-02-04T19:22:11.383973Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88670/133889 blocks (66.2%), 0 events +2026-02-04T19:22:11.601958Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88680/133889 blocks (66.2%), 0 events +2026-02-04T19:22:11.847633Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88690/133889 blocks (66.2%), 0 events +2026-02-04T19:22:12.122231Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88700/133889 blocks (66.2%), 0 events +2026-02-04T19:22:12.164356Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88710/133889 blocks (66.3%), 0 events +2026-02-04T19:22:12.403879Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88720/133889 blocks (66.3%), 0 events +2026-02-04T19:22:12.648065Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88730/133889 blocks (66.3%), 0 events +2026-02-04T19:22:12.852996Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88740/133889 blocks (66.3%), 0 events +2026-02-04T19:22:12.976178Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88750/133889 blocks (66.3%), 0 events +2026-02-04T19:22:13.167689Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88760/133889 blocks (66.3%), 0 events +2026-02-04T19:22:13.416691Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88770/133889 blocks (66.3%), 0 events +2026-02-04T19:22:13.659823Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88780/133889 blocks (66.3%), 0 events +2026-02-04T19:22:13.803328Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88790/133889 blocks (66.3%), 0 events +2026-02-04T19:22:14.005564Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88800/133889 blocks (66.3%), 0 events +2026-02-04T19:22:14.222801Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88810/133889 blocks (66.3%), 0 events +2026-02-04T19:22:14.394194Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88820/133889 blocks (66.3%), 0 events +2026-02-04T19:22:14.712024Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88830/133889 blocks (66.3%), 0 events +2026-02-04T19:22:14.835091Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88840/133889 blocks (66.4%), 0 events +2026-02-04T19:22:14.961149Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88850/133889 blocks (66.4%), 0 events +2026-02-04T19:22:15.268717Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88860/133889 blocks (66.4%), 0 events +2026-02-04T19:22:15.393758Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88870/133889 blocks (66.4%), 0 events +2026-02-04T19:22:15.573981Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88880/133889 blocks (66.4%), 0 events +2026-02-04T19:22:15.795584Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88890/133889 blocks (66.4%), 0 events +2026-02-04T19:22:15.958137Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88900/133889 blocks (66.4%), 0 events +2026-02-04T19:22:16.280482Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88910/133889 blocks (66.4%), 0 events +2026-02-04T19:22:16.427576Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88920/133889 blocks (66.4%), 0 events +2026-02-04T19:22:16.618204Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88930/133889 blocks (66.4%), 0 events +2026-02-04T19:22:16.857745Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88940/133889 blocks (66.4%), 0 events +2026-02-04T19:22:17.032792Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88950/133889 blocks (66.4%), 0 events +2026-02-04T19:22:17.210124Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88960/133889 blocks (66.4%), 0 events +2026-02-04T19:22:17.376931Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88970/133889 blocks (66.5%), 0 events +2026-02-04T19:22:17.651785Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88980/133889 blocks (66.5%), 0 events +2026-02-04T19:22:17.889761Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88990/133889 blocks (66.5%), 0 events +2026-02-04T19:22:18.030149Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 89000/133889 blocks (66.5%), 0 events +2026-02-04T19:22:18.245657Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 89010/133889 blocks (66.5%), 0 events +2026-02-04T19:22:18.418612Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 89020/133889 blocks (66.5%), 0 events +2026-02-04T19:22:18.628828Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 89030/133889 blocks (66.5%), 0 events diff --git a/apps/verbeth-indexer/src/api/health.rs b/apps/verbeth-indexer/src/api/health.rs new file mode 100644 index 0000000..b28c86f --- /dev/null +++ b/apps/verbeth-indexer/src/api/health.rs @@ -0,0 +1,48 @@ +use axum::{extract::State, http::StatusCode, Json}; +use serde::Serialize; + +use crate::db::models::EventCounts; +use crate::db::queries::{get_event_counts, get_last_processed_block}; + +use super::state::AppState; + +#[derive(Serialize)] +pub struct HealthResponse { + pub status: &'static str, + pub last_block: Option, + pub uptime_seconds: u64, + pub counts: EventCountsResponse, +} + +#[derive(Serialize)] +pub struct EventCountsResponse { + pub messages: i64, + pub handshakes: i64, + pub handshake_responses: i64, +} + +impl From for EventCountsResponse { + fn from(c: EventCounts) -> Self { + Self { + messages: c.messages, + handshakes: c.handshakes, + handshake_responses: c.handshake_responses, + } + } +} + +pub async fn health(State(state): State) -> Result, StatusCode> { + let conn = state.pool.get().map_err(|_| StatusCode::SERVICE_UNAVAILABLE)?; + + let last_block = get_last_processed_block(&conn).map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?; + let counts = get_event_counts(&conn).map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?; + + let status = if last_block.is_some() { "ok" } else { "syncing" }; + + Ok(Json(HealthResponse { + status, + last_block, + uptime_seconds: state.uptime_seconds(), + counts: counts.into(), + })) +} diff --git a/apps/verbeth-indexer/src/api/mod.rs b/apps/verbeth-indexer/src/api/mod.rs new file mode 100644 index 0000000..26acef3 --- /dev/null +++ b/apps/verbeth-indexer/src/api/mod.rs @@ -0,0 +1,21 @@ +use axum::{routing::get, Router}; +use tower_http::cors::{Any, CorsLayer}; +use tower_http::trace::TraceLayer; + +pub mod health; +pub mod state; + +pub use state::AppState; + +pub fn create_router(state: AppState) -> Router { + let cors = CorsLayer::new() + .allow_origin(Any) + .allow_methods(Any) + .allow_headers(Any); + + Router::new() + .route("/health", get(health::health)) + .layer(cors) + .layer(TraceLayer::new_for_http()) + .with_state(state) +} diff --git a/apps/verbeth-indexer/src/api/state.rs b/apps/verbeth-indexer/src/api/state.rs new file mode 100644 index 0000000..05a2f41 --- /dev/null +++ b/apps/verbeth-indexer/src/api/state.rs @@ -0,0 +1,26 @@ +use std::sync::Arc; +use std::time::Instant; + +use crate::config::Config; +use crate::db::DbPool; + +#[derive(Clone)] +pub struct AppState { + pub pool: DbPool, + pub config: Arc, + pub start_time: Instant, +} + +impl AppState { + pub fn new(pool: DbPool, config: Config) -> Self { + Self { + pool, + config: Arc::new(config), + start_time: Instant::now(), + } + } + + pub fn uptime_seconds(&self) -> u64 { + self.start_time.elapsed().as_secs() + } +} diff --git a/apps/verbeth-indexer/src/config.rs b/apps/verbeth-indexer/src/config.rs new file mode 100644 index 0000000..d3d0923 --- /dev/null +++ b/apps/verbeth-indexer/src/config.rs @@ -0,0 +1,74 @@ +use alloy::primitives::Address; +use std::str::FromStr; + +use crate::error::{IndexerError, Result}; + +#[allow(dead_code)] +pub struct Config { + pub rpc_ws_url: String, + pub rpc_http_url: Option, + pub contract_address: Address, + pub creation_block: u64, + pub database_path: String, + pub server_port: u16, + pub backfill_days: u32, + pub retention_days: u32, + pub rpc_chunk_size: u64, +} + +impl Config { + pub fn from_env() -> Result { + dotenvy::dotenv().ok(); + + let rpc_ws_url = std::env::var("RPC_WS_URL") + .map_err(|_| IndexerError::Config("RPC_WS_URL is required".into()))?; + + let rpc_http_url = std::env::var("RPC_HTTP_URL").ok(); + + let contract_address = std::env::var("CONTRACT_ADDRESS") + .unwrap_or_else(|_| "0x82C9c5475D63e4C9e959280e9066aBb24973a663".into()); + let contract_address = Address::from_str(&contract_address) + .map_err(|e| IndexerError::Config(format!("Invalid CONTRACT_ADDRESS: {e}")))?; + + let creation_block = std::env::var("CREATION_BLOCK") + .unwrap_or_else(|_| "37097547".into()) + .parse::() + .map_err(|e| IndexerError::Config(format!("Invalid CREATION_BLOCK: {e}")))?; + + let database_path = std::env::var("DATABASE_PATH") + .unwrap_or_else(|_| "./data/indexer.db".into()); + + let server_port = std::env::var("SERVER_PORT") + .unwrap_or_else(|_| "3000".into()) + .parse::() + .map_err(|e| IndexerError::Config(format!("Invalid SERVER_PORT: {e}")))?; + + let backfill_days = std::env::var("BACKFILL_DAYS") + .unwrap_or_else(|_| "7".into()) + .parse::() + .map_err(|e| IndexerError::Config(format!("Invalid BACKFILL_DAYS: {e}")))?; + + let retention_days = std::env::var("RETENTION_DAYS") + .unwrap_or_else(|_| "7".into()) + .parse::() + .map_err(|e| IndexerError::Config(format!("Invalid RETENTION_DAYS: {e}")))?; + + // Default to 10 for Alchemy free tier compatibility + let rpc_chunk_size = std::env::var("RPC_CHUNK_SIZE") + .unwrap_or_else(|_| "10".into()) + .parse::() + .map_err(|e| IndexerError::Config(format!("Invalid RPC_CHUNK_SIZE: {e}")))?; + + Ok(Self { + rpc_ws_url, + rpc_http_url, + contract_address, + creation_block, + database_path, + server_port, + backfill_days, + retention_days, + rpc_chunk_size, + }) + } +} diff --git a/apps/verbeth-indexer/src/db/mod.rs b/apps/verbeth-indexer/src/db/mod.rs new file mode 100644 index 0000000..589f477 --- /dev/null +++ b/apps/verbeth-indexer/src/db/mod.rs @@ -0,0 +1,31 @@ +use r2d2::Pool; +use r2d2_sqlite::SqliteConnectionManager; +use std::path::Path; + +use crate::error::Result; + +pub mod models; +pub mod queries; +pub mod schema; + +pub type DbPool = Pool; + +pub fn create_pool(database_path: &str) -> Result { + if let Some(parent) = Path::new(database_path).parent() { + std::fs::create_dir_all(parent).ok(); + } + + let manager = SqliteConnectionManager::file(database_path); + let pool = Pool::builder().max_size(4).build(manager)?; + + let conn = pool.get()?; + conn.execute_batch( + "PRAGMA journal_mode=WAL; + PRAGMA synchronous=NORMAL; + PRAGMA foreign_keys=ON;", + )?; + + schema::run_migrations(&conn)?; + + Ok(pool) +} diff --git a/apps/verbeth-indexer/src/db/models.rs b/apps/verbeth-indexer/src/db/models.rs new file mode 100644 index 0000000..b4dc940 --- /dev/null +++ b/apps/verbeth-indexer/src/db/models.rs @@ -0,0 +1,40 @@ +pub struct MessageRow { + pub topic: [u8; 32], + pub seq: i64, + pub sender: [u8; 20], + pub ciphertext: Vec, + pub timestamp: i64, + pub nonce: i64, + pub block_number: i64, + pub log_index: i64, + pub block_timestamp: i64, +} + +pub struct HandshakeRow { + pub recipient_hash: [u8; 32], + pub seq: i64, + pub sender: [u8; 20], + pub pub_keys: Vec, + pub ephemeral_pub_key: Vec, + pub plaintext_payload: Vec, + pub block_number: i64, + pub log_index: i64, + pub block_timestamp: i64, +} + +pub struct HsrRow { + pub global_seq: i64, + pub in_response_to: [u8; 32], + pub responder: [u8; 20], + pub responder_ephemeral_r: [u8; 32], + pub ciphertext: Vec, + pub block_number: i64, + pub log_index: i64, + pub block_timestamp: i64, +} + +pub struct EventCounts { + pub messages: i64, + pub handshakes: i64, + pub handshake_responses: i64, +} diff --git a/apps/verbeth-indexer/src/db/queries.rs b/apps/verbeth-indexer/src/db/queries.rs new file mode 100644 index 0000000..830e541 --- /dev/null +++ b/apps/verbeth-indexer/src/db/queries.rs @@ -0,0 +1,128 @@ +use rusqlite::{params, Connection, OptionalExtension}; + +use crate::error::Result; + +use super::models::{EventCounts, HandshakeRow, HsrRow, MessageRow}; + +pub fn get_and_increment_seq( + conn: &Connection, + key_type: &str, + key_hash: Option<&[u8; 32]>, +) -> Result { + let seq: i64 = conn + .query_row( + "SELECT next_seq FROM seq_counters WHERE key_type = ?1 AND key_hash IS ?2", + params![key_type, key_hash.map(|h| h.as_slice())], + |row| row.get(0), + ) + .optional()? + .unwrap_or(0); + + conn.execute( + "INSERT INTO seq_counters (key_type, key_hash, next_seq) VALUES (?1, ?2, ?3) + ON CONFLICT(key_type, key_hash) DO UPDATE SET next_seq = ?3", + params![key_type, key_hash.map(|h| h.as_slice()), seq + 1], + )?; + + Ok(seq) +} + +pub fn insert_message(conn: &Connection, row: &MessageRow) -> Result { + let inserted = conn.execute( + "INSERT OR IGNORE INTO messages + (topic, seq, sender, ciphertext, timestamp, nonce, block_number, log_index, block_timestamp) + VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9)", + params![ + row.topic.as_slice(), + row.seq, + row.sender.as_slice(), + &row.ciphertext, + row.timestamp, + row.nonce, + row.block_number, + row.log_index, + row.block_timestamp, + ], + )?; + Ok(inserted > 0) +} + +pub fn insert_handshake(conn: &Connection, row: &HandshakeRow) -> Result { + let inserted = conn.execute( + "INSERT OR IGNORE INTO handshakes + (recipient_hash, seq, sender, pub_keys, ephemeral_pub_key, plaintext_payload, block_number, log_index, block_timestamp) + VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9)", + params![ + row.recipient_hash.as_slice(), + row.seq, + row.sender.as_slice(), + &row.pub_keys, + &row.ephemeral_pub_key, + &row.plaintext_payload, + row.block_number, + row.log_index, + row.block_timestamp, + ], + )?; + Ok(inserted > 0) +} + +pub fn insert_hsr(conn: &Connection, row: &HsrRow) -> Result { + let inserted = conn.execute( + "INSERT OR IGNORE INTO handshake_responses + (global_seq, in_response_to, responder, responder_ephemeral_r, ciphertext, block_number, log_index, block_timestamp) + VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8)", + params![ + row.global_seq, + row.in_response_to.as_slice(), + row.responder.as_slice(), + row.responder_ephemeral_r.as_slice(), + &row.ciphertext, + row.block_number, + row.log_index, + row.block_timestamp, + ], + )?; + Ok(inserted > 0) +} + +pub fn get_last_processed_block(conn: &Connection) -> Result> { + let value = conn + .query_row( + "SELECT value FROM indexer_state WHERE key = 'last_block'", + [], + |row| row.get::<_, String>(0), + ) + .optional()? + .and_then(|v| v.parse::().ok()); + + Ok(value) +} + +pub fn set_last_processed_block(conn: &Connection, block: i64) -> Result<()> { + conn.execute( + "INSERT OR REPLACE INTO indexer_state (key, value) VALUES ('last_block', ?1)", + params![block.to_string()], + )?; + Ok(()) +} + +pub fn get_event_counts(conn: &Connection) -> Result { + let messages: i64 = + conn.query_row("SELECT COUNT(*) FROM messages", [], |row| row.get(0))?; + let handshakes: i64 = + conn.query_row("SELECT COUNT(*) FROM handshakes", [], |row| row.get(0))?; + let handshake_responses: i64 = + conn.query_row("SELECT COUNT(*) FROM handshake_responses", [], |row| row.get(0))?; + + Ok(EventCounts { + messages, + handshakes, + handshake_responses, + }) +} + +pub fn is_db_empty(conn: &Connection) -> Result { + let counts = get_event_counts(conn)?; + Ok(counts.messages == 0 && counts.handshakes == 0 && counts.handshake_responses == 0) +} diff --git a/apps/verbeth-indexer/src/db/schema.rs b/apps/verbeth-indexer/src/db/schema.rs new file mode 100644 index 0000000..e904001 --- /dev/null +++ b/apps/verbeth-indexer/src/db/schema.rs @@ -0,0 +1,81 @@ +use rusqlite::Connection; + +use crate::error::Result; + +const SCHEMA_VERSION: i64 = 1; + +pub fn run_migrations(conn: &Connection) -> Result<()> { + conn.execute_batch( + r#" + CREATE TABLE IF NOT EXISTS schema_version (version INTEGER PRIMARY KEY); + INSERT OR IGNORE INTO schema_version VALUES (1); + + CREATE TABLE IF NOT EXISTS messages ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + topic BLOB NOT NULL, + seq INTEGER NOT NULL, + sender BLOB NOT NULL, + ciphertext BLOB NOT NULL, + timestamp INTEGER NOT NULL, + nonce INTEGER NOT NULL, + block_number INTEGER NOT NULL, + log_index INTEGER NOT NULL, + block_timestamp INTEGER NOT NULL, + UNIQUE(topic, seq) + ); + CREATE INDEX IF NOT EXISTS idx_msg_topic_seq ON messages(topic, seq); + CREATE INDEX IF NOT EXISTS idx_msg_block ON messages(block_number, log_index); + + CREATE TABLE IF NOT EXISTS handshakes ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + recipient_hash BLOB NOT NULL, + seq INTEGER NOT NULL, + sender BLOB NOT NULL, + pub_keys BLOB NOT NULL, + ephemeral_pub_key BLOB NOT NULL, + plaintext_payload BLOB NOT NULL, + block_number INTEGER NOT NULL, + log_index INTEGER NOT NULL, + block_timestamp INTEGER NOT NULL, + UNIQUE(recipient_hash, seq) + ); + CREATE INDEX IF NOT EXISTS idx_hs_recipient_seq ON handshakes(recipient_hash, seq); + + CREATE TABLE IF NOT EXISTS handshake_responses ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + global_seq INTEGER NOT NULL UNIQUE, + in_response_to BLOB NOT NULL, + responder BLOB NOT NULL, + responder_ephemeral_r BLOB NOT NULL, + ciphertext BLOB NOT NULL, + block_number INTEGER NOT NULL, + log_index INTEGER NOT NULL, + block_timestamp INTEGER NOT NULL + ); + CREATE INDEX IF NOT EXISTS idx_hsr_seq ON handshake_responses(global_seq); + + CREATE TABLE IF NOT EXISTS seq_counters ( + key_type TEXT NOT NULL, + key_hash BLOB, + next_seq INTEGER NOT NULL DEFAULT 0, + PRIMARY KEY(key_type, key_hash) + ); + + CREATE TABLE IF NOT EXISTS indexer_state ( + key TEXT PRIMARY KEY, + value TEXT NOT NULL + ); + "#, + )?; + + let version: i64 = conn.query_row( + "SELECT version FROM schema_version ORDER BY version DESC LIMIT 1", + [], + |row| row.get(0), + )?; + + tracing::info!(schema_version = version, "Database initialized"); + assert_eq!(version, SCHEMA_VERSION, "Schema version mismatch"); + + Ok(()) +} diff --git a/apps/verbeth-indexer/src/error.rs b/apps/verbeth-indexer/src/error.rs new file mode 100644 index 0000000..bf8ad81 --- /dev/null +++ b/apps/verbeth-indexer/src/error.rs @@ -0,0 +1,28 @@ +use thiserror::Error; + +#[derive(Error, Debug)] +#[allow(dead_code)] +pub enum IndexerError { + #[error("database error: {0}")] + Database(#[from] rusqlite::Error), + + #[error("pool error: {0}")] + Pool(#[from] r2d2::Error), + + #[error("RPC error: {0}")] + Rpc(#[from] alloy::transports::TransportError), + + #[error("config error: {0}")] + Config(String), + + #[error("event decode error: {0}")] + Decode(String), + + #[error("block not found: {0}")] + BlockNotFound(u64), + + #[error("task join error: {0}")] + Join(#[from] tokio::task::JoinError), +} + +pub type Result = std::result::Result; diff --git a/apps/verbeth-indexer/src/indexer/backfill.rs b/apps/verbeth-indexer/src/indexer/backfill.rs new file mode 100644 index 0000000..859f288 --- /dev/null +++ b/apps/verbeth-indexer/src/indexer/backfill.rs @@ -0,0 +1,218 @@ +use std::collections::HashMap; +use std::num::NonZeroU32; +use std::time::Duration; + +use alloy::eips::BlockNumberOrTag; +use alloy::primitives::Address; +use alloy::providers::{Provider, ProviderBuilder, RootProvider}; +use alloy::rpc::types::{BlockTransactionsKind, Filter, Log}; +use alloy::transports::http::{Client, Http}; +use governor::{Jitter, Quota, RateLimiter}; + +use crate::db::queries::set_last_processed_block; +use crate::db::DbPool; +use crate::error::{IndexerError, Result}; + +use super::processor::{decode_log, EventProcessor, LogWithMeta}; + +// Alchemy Free tier: 500 CU/s, eth_getLogs = 75 CU โ†’ max ~6 req/s +const REQUESTS_PER_SECOND: u32 = 5; +const MAX_RETRIES: u32 = 5; +const INITIAL_BACKOFF_MS: u64 = 1000; + +pub struct BackfillStats { + pub blocks_processed: u64, + pub events_processed: u64, + pub events_skipped: u64, +} + +pub async fn run_backfill( + rpc_url: &str, + contract_address: Address, + from_block: u64, + to_block: u64, + chunk_size: u64, + pool: DbPool, +) -> Result { + tracing::info!( + "Starting backfill from block {} to {}", + from_block, + to_block + ); + + let provider = ProviderBuilder::new().on_http(rpc_url.parse().map_err(|e| { + IndexerError::Config(format!("Invalid RPC URL: {e}")) + })?); + + let processor = EventProcessor::new(pool.clone()); + + let limiter = RateLimiter::direct(Quota::per_second( + NonZeroU32::new(REQUESTS_PER_SECOND).unwrap(), + )); + + let mut block_timestamps: HashMap = HashMap::new(); + let mut stats = BackfillStats { + blocks_processed: 0, + events_processed: 0, + events_skipped: 0, + }; + + for chunk_start in (from_block..=to_block).step_by(chunk_size as usize) { + let chunk_end = (chunk_start + chunk_size - 1).min(to_block); + + limiter + .until_ready_with_jitter(Jitter::up_to(Duration::from_millis(100))) + .await; + + // Note: Don't use .events() for multiple signatures - it doesn't work as OR filter + // Filter in code via decode_log() instead + let filter = Filter::new() + .address(contract_address) + .from_block(chunk_start) + .to_block(chunk_end); + + let logs = get_logs_with_retry(&provider, &filter).await?; + + let mut logs: Vec<_> = logs.into_iter().collect(); + logs.sort_by_key(|l| (l.block_number, l.log_index)); + + let unique_blocks: Vec = logs + .iter() + .filter_map(|l| l.block_number) + .filter(|b| !block_timestamps.contains_key(b)) + .collect::>() + .into_iter() + .collect(); + + for block_num in unique_blocks { + limiter.until_ready().await; + let timestamp = fetch_block_timestamp_with_retry(&provider, block_num).await?; + block_timestamps.insert(block_num, timestamp); + } + + for log in logs { + tracing::debug!("Got log with topic: {:?}", log.topics().first()); + let Some(event) = decode_log(&log) else { + // Non-Verbeth events (Upgraded, OwnershipTransferred, etc.) - skip silently + continue; + }; + + let block_number = log.block_number.unwrap_or(0); + let log_index = log.log_index.unwrap_or(0); + let block_timestamp = *block_timestamps.get(&block_number).unwrap_or(&0); + + let log_with_meta = LogWithMeta { + event, + block_number, + log_index, + block_timestamp, + }; + + match processor.process(log_with_meta) { + Ok(true) => stats.events_processed += 1, + Ok(false) => stats.events_skipped += 1, + Err(e) => { + tracing::error!("Failed to process event: {e}"); + } + } + } + + let conn = pool.get()?; + set_last_processed_block(&conn, chunk_end as i64)?; + + stats.blocks_processed = chunk_end - from_block + 1; + + let progress = (chunk_end - from_block) as f64 / (to_block - from_block).max(1) as f64 * 100.0; + tracing::info!( + "Backfill progress: {}/{} blocks ({:.1}%), {} events", + stats.blocks_processed, + to_block - from_block + 1, + progress, + stats.events_processed + ); + } + + tracing::info!( + "Backfill complete: {} blocks, {} events processed, {} skipped", + stats.blocks_processed, + stats.events_processed, + stats.events_skipped + ); + + Ok(stats) +} + +async fn get_logs_with_retry( + provider: &RootProvider>, + filter: &Filter, +) -> Result> { + let mut attempt = 0; + loop { + match provider.get_logs(filter).await { + Ok(logs) => return Ok(logs), + Err(e) => { + let is_rate_limit = e.to_string().contains("429") + || e.to_string().contains("exceeded") + || e.to_string().contains("rate"); + + if is_rate_limit && attempt < MAX_RETRIES { + attempt += 1; + let backoff = Duration::from_millis(INITIAL_BACKOFF_MS * 2u64.pow(attempt - 1)); + tracing::warn!( + "Rate limited, retrying in {:?} (attempt {}/{})", + backoff, + attempt, + MAX_RETRIES + ); + tokio::time::sleep(backoff).await; + } else { + return Err(e.into()); + } + } + } + } +} + +async fn fetch_block_timestamp_with_retry( + provider: &RootProvider>, + block_num: u64, +) -> Result { + let mut attempt = 0; + loop { + match provider + .get_block_by_number( + BlockNumberOrTag::Number(block_num), + BlockTransactionsKind::Hashes, + ) + .await + { + Ok(Some(block)) => return Ok(block.header.timestamp), + Ok(None) => return Err(IndexerError::BlockNotFound(block_num)), + Err(e) => { + let is_rate_limit = e.to_string().contains("429") + || e.to_string().contains("exceeded") + || e.to_string().contains("rate"); + + if is_rate_limit && attempt < MAX_RETRIES { + attempt += 1; + let backoff = Duration::from_millis(INITIAL_BACKOFF_MS * 2u64.pow(attempt - 1)); + tracing::warn!( + "Rate limited fetching block {}, retrying in {:?} (attempt {}/{})", + block_num, + backoff, + attempt, + MAX_RETRIES + ); + tokio::time::sleep(backoff).await; + } else { + return Err(e.into()); + } + } + } + } +} + +#[allow(dead_code)] +pub async fn get_chain_head(provider: &RootProvider>) -> Result { + Ok(provider.get_block_number().await?) +} diff --git a/apps/verbeth-indexer/src/indexer/events.rs b/apps/verbeth-indexer/src/indexer/events.rs new file mode 100644 index 0000000..1c57180 --- /dev/null +++ b/apps/verbeth-indexer/src/indexer/events.rs @@ -0,0 +1,26 @@ +use alloy::sol; + +sol! { + event MessageSent( + address indexed sender, + bytes ciphertext, + uint256 timestamp, + bytes32 indexed topic, + uint256 nonce + ); + + event Handshake( + bytes32 indexed recipientHash, + address indexed sender, + bytes pubKeys, + bytes ephemeralPubKey, + bytes plaintextPayload + ); + + event HandshakeResponse( + bytes32 indexed inResponseTo, + address indexed responder, + bytes32 responderEphemeralR, + bytes ciphertext + ); +} diff --git a/apps/verbeth-indexer/src/indexer/mod.rs b/apps/verbeth-indexer/src/indexer/mod.rs new file mode 100644 index 0000000..2772f2d --- /dev/null +++ b/apps/verbeth-indexer/src/indexer/mod.rs @@ -0,0 +1,4 @@ +pub mod backfill; +pub mod events; +pub mod processor; +pub mod subscriber; diff --git a/apps/verbeth-indexer/src/indexer/processor.rs b/apps/verbeth-indexer/src/indexer/processor.rs new file mode 100644 index 0000000..b1cf257 --- /dev/null +++ b/apps/verbeth-indexer/src/indexer/processor.rs @@ -0,0 +1,176 @@ +use alloy::primitives::{Address, B256}; +use alloy::rpc::types::Log; + +use crate::db::models::{HandshakeRow, HsrRow, MessageRow}; +use crate::db::queries::{ + get_and_increment_seq, insert_handshake, insert_hsr, insert_message, +}; +use crate::db::DbPool; +use crate::error::Result; + +use super::events::{Handshake, HandshakeResponse, MessageSent}; + +pub enum VerbethEvent { + MessageSent { + sender: Address, + ciphertext: Vec, + timestamp: u64, + topic: B256, + nonce: u64, + }, + Handshake { + recipient_hash: B256, + sender: Address, + pub_keys: Vec, + ephemeral_pub_key: Vec, + plaintext_payload: Vec, + }, + HandshakeResponse { + in_response_to: B256, + responder: Address, + responder_ephemeral_r: B256, + ciphertext: Vec, + }, +} + +pub struct LogWithMeta { + pub event: VerbethEvent, + pub block_number: u64, + pub log_index: u64, + pub block_timestamp: u64, +} + +pub struct EventProcessor { + pool: DbPool, +} + +impl EventProcessor { + pub fn new(pool: DbPool) -> Self { + Self { pool } + } + + pub fn process(&self, log: LogWithMeta) -> Result { + let conn = self.pool.get()?; + + match log.event { + VerbethEvent::MessageSent { + sender, + ciphertext, + timestamp, + topic, + nonce, + } => { + let topic_bytes: [u8; 32] = topic.0; + let seq = get_and_increment_seq(&conn, "message", Some(&topic_bytes))?; + + insert_message( + &conn, + &MessageRow { + topic: topic_bytes, + seq, + sender: sender.0 .0, + ciphertext, + timestamp: timestamp as i64, + nonce: nonce as i64, + block_number: log.block_number as i64, + log_index: log.log_index as i64, + block_timestamp: log.block_timestamp as i64, + }, + ) + } + VerbethEvent::Handshake { + recipient_hash, + sender, + pub_keys, + ephemeral_pub_key, + plaintext_payload, + } => { + let recipient_hash_bytes: [u8; 32] = recipient_hash.0; + let seq = + get_and_increment_seq(&conn, "handshake", Some(&recipient_hash_bytes))?; + + insert_handshake( + &conn, + &HandshakeRow { + recipient_hash: recipient_hash_bytes, + seq, + sender: sender.0 .0, + pub_keys, + ephemeral_pub_key, + plaintext_payload, + block_number: log.block_number as i64, + log_index: log.log_index as i64, + block_timestamp: log.block_timestamp as i64, + }, + ) + } + VerbethEvent::HandshakeResponse { + in_response_to, + responder, + responder_ephemeral_r, + ciphertext, + } => { + let global_seq = get_and_increment_seq(&conn, "hsr", None)?; + + insert_hsr( + &conn, + &HsrRow { + global_seq, + in_response_to: in_response_to.0, + responder: responder.0 .0, + responder_ephemeral_r: responder_ephemeral_r.0, + ciphertext, + block_number: log.block_number as i64, + log_index: log.log_index as i64, + block_timestamp: log.block_timestamp as i64, + }, + ) + } + } + } +} + +pub fn decode_log(log: &Log) -> Option { + use alloy::sol_types::SolEvent; + + let topics = log.topics(); + if topics.is_empty() { + return None; + } + + let sig = topics[0]; + + if sig == MessageSent::SIGNATURE_HASH { + let decoded = MessageSent::decode_log(log.inner.as_ref(), true).ok()?; + return Some(VerbethEvent::MessageSent { + sender: decoded.sender, + ciphertext: decoded.ciphertext.to_vec(), + timestamp: decoded.timestamp.try_into().ok()?, + topic: decoded.topic, + nonce: decoded.nonce.try_into().ok()?, + }); + } + + if sig == Handshake::SIGNATURE_HASH { + let decoded = Handshake::decode_log(log.inner.as_ref(), true).ok()?; + return Some(VerbethEvent::Handshake { + recipient_hash: decoded.recipientHash, + sender: decoded.sender, + pub_keys: decoded.pubKeys.to_vec(), + ephemeral_pub_key: decoded.ephemeralPubKey.to_vec(), + plaintext_payload: decoded.plaintextPayload.to_vec(), + }); + } + + if sig == HandshakeResponse::SIGNATURE_HASH { + let decoded = HandshakeResponse::decode_log(log.inner.as_ref(), true).ok()?; + return Some(VerbethEvent::HandshakeResponse { + in_response_to: decoded.inResponseTo, + responder: decoded.responder, + responder_ephemeral_r: decoded.responderEphemeralR, + ciphertext: decoded.ciphertext.to_vec(), + }); + } + + None +} diff --git a/apps/verbeth-indexer/src/indexer/subscriber.rs b/apps/verbeth-indexer/src/indexer/subscriber.rs new file mode 100644 index 0000000..148ad49 --- /dev/null +++ b/apps/verbeth-indexer/src/indexer/subscriber.rs @@ -0,0 +1,145 @@ +use std::time::Duration; + +use alloy::eips::BlockNumberOrTag; +use alloy::primitives::Address; +use alloy::providers::{Provider, ProviderBuilder, RootProvider, WsConnect}; +use alloy::pubsub::PubSubFrontend; +use alloy::rpc::types::{BlockTransactionsKind, Filter}; +use alloy::sol_types::SolEvent; +use tokio::sync::watch; + +use crate::db::queries::set_last_processed_block; +use crate::db::DbPool; +use crate::error::Result; + +use super::events::{Handshake, HandshakeResponse, MessageSent}; +use super::processor::{decode_log, EventProcessor, LogWithMeta}; + +pub async fn subscribe_with_reconnect( + ws_url: String, + contract_address: Address, + pool: DbPool, + mut shutdown: watch::Receiver, +) { + let processor = EventProcessor::new(pool.clone()); + let mut backoff = Duration::from_secs(1); + + loop { + if *shutdown.borrow() { + tracing::info!("Subscriber received shutdown signal"); + break; + } + + match connect_and_subscribe(&ws_url, contract_address, &processor, &pool, &mut shutdown) + .await + { + Ok(()) => { + tracing::info!("Subscriber shut down gracefully"); + break; + } + Err(e) => { + tracing::warn!("Subscriber error: {e}, reconnecting in {:?}", backoff); + tokio::select! { + _ = tokio::time::sleep(backoff) => {} + _ = shutdown.changed() => { + if *shutdown.borrow() { + break; + } + } + } + backoff = (backoff * 2).min(Duration::from_secs(60)); + } + } + } +} + +async fn connect_and_subscribe( + ws_url: &str, + contract_address: Address, + processor: &EventProcessor, + pool: &DbPool, + shutdown: &mut watch::Receiver, +) -> Result<()> { + tracing::info!("Connecting to WebSocket: {}", ws_url); + + let ws = WsConnect::new(ws_url); + let provider = ProviderBuilder::new().on_ws(ws).await?; + + tracing::info!("Connected, subscribing to events..."); + + let filter = Filter::new().address(contract_address).events([ + MessageSent::SIGNATURE_HASH, + Handshake::SIGNATURE_HASH, + HandshakeResponse::SIGNATURE_HASH, + ]); + + let sub = provider.subscribe_logs(&filter).await?; + let mut stream = sub.into_stream(); + + tracing::info!("Subscribed to Verbeth events"); + + loop { + tokio::select! { + _ = shutdown.changed() => { + if *shutdown.borrow() { + return Ok(()); + } + } + log_opt = futures_lite::StreamExt::next(&mut stream) => { + let log = match log_opt { + Some(log) => log, + None => { + tracing::warn!("WebSocket stream ended"); + return Err(crate::error::IndexerError::Config("Stream ended".into())); + } + }; + + let block_number = log.block_number.unwrap_or(0); + let log_index = log.log_index.unwrap_or(0); + + let Some(event) = decode_log(&log) else { + tracing::debug!("Unknown event at block {}", block_number); + continue; + }; + + let block_timestamp = fetch_block_timestamp(&provider, block_number).await?; + + let log_with_meta = LogWithMeta { + event, + block_number, + log_index, + block_timestamp, + }; + + match processor.process(log_with_meta) { + Ok(true) => { + tracing::debug!("Processed event at block {}", block_number); + let conn = pool.get()?; + set_last_processed_block(&conn, block_number as i64)?; + } + Ok(false) => { + tracing::debug!("Duplicate event at block {}", block_number); + } + Err(e) => { + tracing::error!("Failed to process event: {e}"); + } + } + } + } + } +} + +async fn fetch_block_timestamp( + provider: &RootProvider, + block_number: u64, +) -> Result { + let block = provider + .get_block_by_number( + BlockNumberOrTag::Number(block_number), + BlockTransactionsKind::Hashes, + ) + .await? + .ok_or(crate::error::IndexerError::BlockNotFound(block_number))?; + + Ok(block.header.timestamp) +} diff --git a/apps/verbeth-indexer/src/main.rs b/apps/verbeth-indexer/src/main.rs new file mode 100644 index 0000000..e69a049 --- /dev/null +++ b/apps/verbeth-indexer/src/main.rs @@ -0,0 +1,150 @@ +use std::net::SocketAddr; + +use alloy::providers::{Provider, ProviderBuilder}; +use tokio::sync::watch; +use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt, EnvFilter}; + +mod api; +mod config; +mod db; +mod error; +mod indexer; + +use api::AppState; +use config::Config; +use db::{create_pool, queries}; +use error::Result; +use indexer::{backfill, subscriber}; + +#[tokio::main] +async fn main() -> Result<()> { + tracing_subscriber::registry() + .with(EnvFilter::try_from_default_env().unwrap_or_else(|_| "info".into())) + .with(tracing_subscriber::fmt::layer()) + .init(); + + let config = Config::from_env()?; + + tracing::info!( + "Starting Verbeth Indexer v{}", + env!("CARGO_PKG_VERSION") + ); + tracing::info!("Contract: {}", config.contract_address); + tracing::info!("Database: {}", config.database_path); + tracing::info!("RPC chunk size: {} blocks", config.rpc_chunk_size); + + let pool = create_pool(&config.database_path)?; + + let (shutdown_tx, shutdown_rx) = watch::channel(false); + + let conn = pool.get()?; + let is_empty = queries::is_db_empty(&conn)?; + let last_block = queries::get_last_processed_block(&conn)?; + drop(conn); + + let rpc_url = config.rpc_http_url.clone().unwrap_or_else(|| { + config.rpc_ws_url.replace("wss://", "https://").replace("ws://", "http://") + }); + + let http_provider = ProviderBuilder::new() + .on_http(rpc_url.parse().map_err(|e| { + error::IndexerError::Config(format!("Invalid RPC URL: {e}")) + })?); + + let chain_head = http_provider.get_block_number().await?; + tracing::info!("Chain head: {}", chain_head); + + let start_block = if is_empty { + let blocks_per_day = 43200u64; // ~2s blocks on Base + let days_back = config.backfill_days as u64; + chain_head.saturating_sub(blocks_per_day * days_back).max(config.creation_block) + } else { + (last_block.unwrap_or(config.creation_block as i64) as u64) + 1 + }; + + if start_block < chain_head { + tracing::info!("Running backfill from block {} to {}", start_block, chain_head); + backfill::run_backfill( + &rpc_url, + config.contract_address, + start_block, + chain_head, + config.rpc_chunk_size, + pool.clone(), + ) + .await?; + } else { + tracing::info!("No backfill needed, starting from chain head"); + } + + let state = AppState::new(pool.clone(), config); + + let subscriber_handle = { + let ws_url = state.config.rpc_ws_url.clone(); + let contract_address = state.config.contract_address; + let pool = pool.clone(); + let shutdown_rx = shutdown_rx.clone(); + + tokio::spawn(async move { + subscriber::subscribe_with_reconnect(ws_url, contract_address, pool, shutdown_rx).await; + }) + }; + + let addr = SocketAddr::from(([0, 0, 0, 0], state.config.server_port)); + let listener = tokio::net::TcpListener::bind(addr).await.map_err(|e| { + error::IndexerError::Config(format!("Failed to bind to {}: {}", addr, e)) + })?; + + tracing::info!("API server listening on {}", addr); + + let router = api::create_router(state); + + let server_handle = tokio::spawn(async move { + axum::serve(listener, router) + .with_graceful_shutdown(shutdown_signal(shutdown_tx)) + .await + .ok(); + }); + + tokio::select! { + _ = subscriber_handle => { + tracing::info!("Subscriber task finished"); + } + _ = server_handle => { + tracing::info!("Server task finished"); + } + } + + tracing::info!("Shutdown complete"); + Ok(()) +} + +async fn shutdown_signal(shutdown_tx: watch::Sender) { + let ctrl_c = async { + tokio::signal::ctrl_c() + .await + .expect("Failed to install Ctrl+C handler"); + }; + + #[cfg(unix)] + let terminate = async { + tokio::signal::unix::signal(tokio::signal::unix::SignalKind::terminate()) + .expect("Failed to install SIGTERM handler") + .recv() + .await; + }; + + #[cfg(not(unix))] + let terminate = std::future::pending::<()>(); + + tokio::select! { + _ = ctrl_c => { + tracing::info!("Received Ctrl+C, shutting down..."); + } + _ = terminate => { + tracing::info!("Received SIGTERM, shutting down..."); + } + } + + let _ = shutdown_tx.send(true); +} From 10209857406869d81db0743454bca16aacbb5942 Mon Sep 17 00:00:00 2001 From: Marco Esposito Date: Thu, 5 Feb 2026 10:25:22 +0100 Subject: [PATCH 32/51] stop tracking indexer-log --- apps/verbeth-indexer/README.md | 2 +- apps/verbeth-indexer/indexer.log | 8913 ------------------------------ 2 files changed, 1 insertion(+), 8914 deletions(-) delete mode 100644 apps/verbeth-indexer/indexer.log diff --git a/apps/verbeth-indexer/README.md b/apps/verbeth-indexer/README.md index 8c958d5..8d8061b 100644 --- a/apps/verbeth-indexer/README.md +++ b/apps/verbeth-indexer/README.md @@ -30,7 +30,7 @@ cargo run | `CONTRACT_ADDRESS` | No | Verbeth proxy | Contract to index | | `CREATION_BLOCK` | No | 37097547 | Block to start backfill from | | `DATABASE_PATH` | No | ./data/indexer.db | SQLite file location | -| `SERVER_PORT` | No | 3000 | HTTP server port | +| `SERVER_PORT` | No | 3002 | HTTP server port | | `BACKFILL_DAYS` | No | 7 | Days to backfill on empty DB | | `RUST_LOG` | No | info | Log level | diff --git a/apps/verbeth-indexer/indexer.log b/apps/verbeth-indexer/indexer.log deleted file mode 100644 index ff11519..0000000 --- a/apps/verbeth-indexer/indexer.log +++ /dev/null @@ -1,8913 +0,0 @@ - Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.51s - Running `target/debug/verbeth-indexer` -2026-02-04T18:52:38.494620Z  INFO verbeth_indexer: Starting Verbeth Indexer v0.1.0 -2026-02-04T18:52:38.494856Z  INFO verbeth_indexer: Contract: 0x82C9c5475D63e4C9e959280e9066aBb24973a663 -2026-02-04T18:52:38.495084Z  INFO verbeth_indexer: Database: ./data/indexer.db -2026-02-04T18:52:38.495172Z  INFO verbeth_indexer: RPC chunk size: 10 blocks -2026-02-04T18:52:38.502462Z  INFO verbeth_indexer::db::schema: Database initialized schema_version=1 -2026-02-04T18:52:38.719450Z  INFO verbeth_indexer: Chain head: 37231435 -2026-02-04T18:52:38.719597Z  INFO verbeth_indexer: Running backfill from block 37097547 to 37231435 -2026-02-04T18:52:38.719771Z  INFO verbeth_indexer::indexer::backfill: Starting backfill from block 37097547 to 37231435 -2026-02-04T18:52:39.054284Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10/133889 blocks (0.0%), 0 events -2026-02-04T18:52:39.087314Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20/133889 blocks (0.0%), 0 events -2026-02-04T18:52:39.131361Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30/133889 blocks (0.0%), 0 events -2026-02-04T18:52:39.168315Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40/133889 blocks (0.0%), 0 events -2026-02-04T18:52:39.204444Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50/133889 blocks (0.0%), 0 events -2026-02-04T18:52:39.246517Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60/133889 blocks (0.0%), 0 events -2026-02-04T18:52:39.488322Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70/133889 blocks (0.1%), 0 events -2026-02-04T18:52:39.644941Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80/133889 blocks (0.1%), 0 events -2026-02-04T18:52:39.784651Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 90/133889 blocks (0.1%), 0 events -2026-02-04T18:52:40.023135Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 100/133889 blocks (0.1%), 0 events -2026-02-04T18:52:40.168610Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 110/133889 blocks (0.1%), 0 events -2026-02-04T18:52:40.503949Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 120/133889 blocks (0.1%), 0 events -2026-02-04T18:52:40.619123Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 130/133889 blocks (0.1%), 0 events -2026-02-04T18:52:40.822565Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 140/133889 blocks (0.1%), 0 events -2026-02-04T18:52:41.063307Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 150/133889 blocks (0.1%), 0 events -2026-02-04T18:52:41.254385Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 160/133889 blocks (0.1%), 0 events -2026-02-04T18:52:41.406927Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 170/133889 blocks (0.1%), 0 events -2026-02-04T18:52:41.646892Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 180/133889 blocks (0.1%), 0 events -2026-02-04T18:52:41.785200Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 190/133889 blocks (0.1%), 0 events -2026-02-04T18:52:42.076797Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 200/133889 blocks (0.1%), 0 events -2026-02-04T18:52:42.239479Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 210/133889 blocks (0.2%), 0 events -2026-02-04T18:52:42.420883Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 220/133889 blocks (0.2%), 0 events -2026-02-04T18:52:42.635744Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 230/133889 blocks (0.2%), 0 events -2026-02-04T18:52:42.830690Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 240/133889 blocks (0.2%), 0 events -2026-02-04T18:52:43.124144Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 250/133889 blocks (0.2%), 0 events -2026-02-04T18:52:43.161223Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 260/133889 blocks (0.2%), 0 events -2026-02-04T18:52:43.461322Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 270/133889 blocks (0.2%), 0 events -2026-02-04T18:52:43.682448Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 280/133889 blocks (0.2%), 0 events -2026-02-04T18:52:43.837930Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 290/133889 blocks (0.2%), 0 events -2026-02-04T18:52:44.038073Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 300/133889 blocks (0.2%), 0 events -2026-02-04T18:52:44.206240Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 310/133889 blocks (0.2%), 0 events -2026-02-04T18:52:44.389362Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 320/133889 blocks (0.2%), 0 events -2026-02-04T18:52:44.588226Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 330/133889 blocks (0.2%), 0 events -2026-02-04T18:52:44.824309Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 340/133889 blocks (0.3%), 0 events -2026-02-04T18:52:45.004511Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 350/133889 blocks (0.3%), 0 events -2026-02-04T18:52:45.253963Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 360/133889 blocks (0.3%), 0 events -2026-02-04T18:52:45.430725Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 370/133889 blocks (0.3%), 0 events -2026-02-04T18:52:45.609726Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 380/133889 blocks (0.3%), 0 events -2026-02-04T18:52:45.806604Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 390/133889 blocks (0.3%), 0 events -2026-02-04T18:52:45.998085Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 400/133889 blocks (0.3%), 0 events -2026-02-04T18:52:46.306013Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 410/133889 blocks (0.3%), 0 events -2026-02-04T18:52:46.441328Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 420/133889 blocks (0.3%), 0 events -2026-02-04T18:52:46.665448Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 430/133889 blocks (0.3%), 0 events -2026-02-04T18:52:46.829507Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 440/133889 blocks (0.3%), 0 events -2026-02-04T18:52:47.030167Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 450/133889 blocks (0.3%), 0 events -2026-02-04T18:52:47.318407Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 460/133889 blocks (0.3%), 0 events -2026-02-04T18:52:47.365813Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 470/133889 blocks (0.4%), 0 events -2026-02-04T18:52:47.640943Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 480/133889 blocks (0.4%), 0 events -2026-02-04T18:52:47.877701Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 490/133889 blocks (0.4%), 0 events -2026-02-04T18:52:48.004951Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 500/133889 blocks (0.4%), 0 events -2026-02-04T18:52:48.179122Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 510/133889 blocks (0.4%), 0 events -2026-02-04T18:52:48.404445Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 520/133889 blocks (0.4%), 0 events -2026-02-04T18:52:48.614726Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 530/133889 blocks (0.4%), 0 events -2026-02-04T18:52:48.892021Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 540/133889 blocks (0.4%), 0 events -2026-02-04T18:52:48.981123Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 550/133889 blocks (0.4%), 0 events -2026-02-04T18:52:49.197623Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 560/133889 blocks (0.4%), 0 events -2026-02-04T18:52:49.452059Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 570/133889 blocks (0.4%), 0 events -2026-02-04T18:52:49.658403Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 580/133889 blocks (0.4%), 0 events -2026-02-04T18:52:49.831494Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 590/133889 blocks (0.4%), 0 events -2026-02-04T18:52:50.049561Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 600/133889 blocks (0.4%), 0 events -2026-02-04T18:52:50.175958Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 610/133889 blocks (0.5%), 0 events -2026-02-04T18:52:50.467497Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 620/133889 blocks (0.5%), 0 events -2026-02-04T18:52:50.603203Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 630/133889 blocks (0.5%), 0 events -2026-02-04T18:52:50.805706Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 640/133889 blocks (0.5%), 0 events -2026-02-04T18:52:51.044774Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 650/133889 blocks (0.5%), 0 events -2026-02-04T18:52:51.173995Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 660/133889 blocks (0.5%), 0 events -2026-02-04T18:52:51.555857Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 670/133889 blocks (0.5%), 0 events -2026-02-04T18:52:51.603404Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 680/133889 blocks (0.5%), 0 events -2026-02-04T18:52:52.063305Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 690/133889 blocks (0.5%), 0 events -2026-02-04T18:52:52.101310Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 700/133889 blocks (0.5%), 0 events -2026-02-04T18:52:52.217515Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 710/133889 blocks (0.5%), 0 events -2026-02-04T18:52:52.416191Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 720/133889 blocks (0.5%), 0 events -2026-02-04T18:52:52.659263Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 730/133889 blocks (0.5%), 0 events -2026-02-04T18:52:52.859538Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 740/133889 blocks (0.6%), 0 events -2026-02-04T18:52:52.987370Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 750/133889 blocks (0.6%), 0 events -2026-02-04T18:52:53.202767Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 760/133889 blocks (0.6%), 0 events -2026-02-04T18:52:53.440239Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 770/133889 blocks (0.6%), 0 events -2026-02-04T18:52:53.646816Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 780/133889 blocks (0.6%), 0 events -2026-02-04T18:52:53.860619Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 790/133889 blocks (0.6%), 0 events -2026-02-04T18:52:54.002684Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 800/133889 blocks (0.6%), 0 events -2026-02-04T18:52:54.232065Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 810/133889 blocks (0.6%), 0 events -2026-02-04T18:52:54.443239Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 820/133889 blocks (0.6%), 0 events -2026-02-04T18:52:54.563914Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 830/133889 blocks (0.6%), 0 events -2026-02-04T18:52:54.833722Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 840/133889 blocks (0.6%), 0 events -2026-02-04T18:52:54.986852Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 850/133889 blocks (0.6%), 0 events -2026-02-04T18:52:55.223132Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 860/133889 blocks (0.6%), 0 events -2026-02-04T18:52:55.376580Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 870/133889 blocks (0.6%), 0 events -2026-02-04T18:52:55.592883Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 880/133889 blocks (0.7%), 0 events -2026-02-04T18:52:55.834398Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 890/133889 blocks (0.7%), 0 events -2026-02-04T18:52:55.976505Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 900/133889 blocks (0.7%), 0 events -2026-02-04T18:52:56.267905Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 910/133889 blocks (0.7%), 0 events -2026-02-04T18:52:56.461471Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 920/133889 blocks (0.7%), 0 events -2026-02-04T18:52:56.618550Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 930/133889 blocks (0.7%), 0 events -2026-02-04T18:52:56.794627Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 940/133889 blocks (0.7%), 0 events -2026-02-04T18:52:57.001156Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 950/133889 blocks (0.7%), 0 events -2026-02-04T18:52:57.311914Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 960/133889 blocks (0.7%), 0 events -2026-02-04T18:52:57.366278Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 970/133889 blocks (0.7%), 0 events -2026-02-04T18:52:57.622584Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 980/133889 blocks (0.7%), 0 events -2026-02-04T18:52:57.834678Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 990/133889 blocks (0.7%), 0 events -2026-02-04T18:52:57.993174Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1000/133889 blocks (0.7%), 0 events -2026-02-04T18:52:58.329607Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1010/133889 blocks (0.8%), 0 events -2026-02-04T18:52:58.367058Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1020/133889 blocks (0.8%), 0 events -2026-02-04T18:52:58.603991Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1030/133889 blocks (0.8%), 0 events -2026-02-04T18:52:58.887833Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1040/133889 blocks (0.8%), 0 events -2026-02-04T18:52:59.017829Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1050/133889 blocks (0.8%), 0 events -2026-02-04T18:52:59.256848Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1060/133889 blocks (0.8%), 0 events -2026-02-04T18:52:59.419868Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1070/133889 blocks (0.8%), 0 events -2026-02-04T18:52:59.586656Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1080/133889 blocks (0.8%), 0 events -2026-02-04T18:52:59.936797Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1090/133889 blocks (0.8%), 0 events -2026-02-04T18:52:59.978415Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1100/133889 blocks (0.8%), 0 events -2026-02-04T18:53:00.186088Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1110/133889 blocks (0.8%), 0 events -2026-02-04T18:53:00.461412Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1120/133889 blocks (0.8%), 0 events -2026-02-04T18:53:00.641531Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1130/133889 blocks (0.8%), 0 events -2026-02-04T18:53:00.779170Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1140/133889 blocks (0.9%), 0 events -2026-02-04T18:53:00.988576Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1150/133889 blocks (0.9%), 0 events -2026-02-04T18:53:01.253064Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1160/133889 blocks (0.9%), 0 events -2026-02-04T18:53:01.511461Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1170/133889 blocks (0.9%), 0 events -2026-02-04T18:53:01.590636Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1180/133889 blocks (0.9%), 0 events -2026-02-04T18:53:01.842590Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1190/133889 blocks (0.9%), 0 events -2026-02-04T18:53:02.245706Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1200/133889 blocks (0.9%), 0 events -2026-02-04T18:53:02.281232Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1210/133889 blocks (0.9%), 0 events -2026-02-04T18:53:02.524808Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1220/133889 blocks (0.9%), 0 events -2026-02-04T18:53:02.570713Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1230/133889 blocks (0.9%), 0 events -2026-02-04T18:53:02.820051Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1240/133889 blocks (0.9%), 0 events -2026-02-04T18:53:03.086574Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1250/133889 blocks (0.9%), 0 events -2026-02-04T18:53:03.246479Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1260/133889 blocks (0.9%), 0 events -2026-02-04T18:53:03.421777Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1270/133889 blocks (0.9%), 0 events -2026-02-04T18:53:03.645001Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1280/133889 blocks (1.0%), 0 events -2026-02-04T18:53:03.864911Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1290/133889 blocks (1.0%), 0 events -2026-02-04T18:53:04.097501Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1300/133889 blocks (1.0%), 0 events -2026-02-04T18:53:04.194317Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1310/133889 blocks (1.0%), 0 events -2026-02-04T18:53:04.457447Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1320/133889 blocks (1.0%), 0 events -2026-02-04T18:53:04.654563Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1330/133889 blocks (1.0%), 0 events -2026-02-04T18:53:04.836350Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1340/133889 blocks (1.0%), 0 events -2026-02-04T18:53:04.982072Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1350/133889 blocks (1.0%), 0 events -2026-02-04T18:53:05.208969Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1360/133889 blocks (1.0%), 0 events -2026-02-04T18:53:05.432316Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1370/133889 blocks (1.0%), 0 events -2026-02-04T18:53:05.700063Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1380/133889 blocks (1.0%), 0 events -2026-02-04T18:53:05.778023Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1390/133889 blocks (1.0%), 0 events -2026-02-04T18:53:06.012395Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1400/133889 blocks (1.0%), 0 events -2026-02-04T18:53:06.224673Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1410/133889 blocks (1.1%), 0 events -2026-02-04T18:53:06.464617Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1420/133889 blocks (1.1%), 0 events -2026-02-04T18:53:06.619303Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1430/133889 blocks (1.1%), 0 events -2026-02-04T18:53:06.792763Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1440/133889 blocks (1.1%), 0 events -2026-02-04T18:53:06.989679Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1450/133889 blocks (1.1%), 0 events -2026-02-04T18:53:07.283099Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1460/133889 blocks (1.1%), 0 events -2026-02-04T18:53:07.404276Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1470/133889 blocks (1.1%), 0 events -2026-02-04T18:53:07.619882Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1480/133889 blocks (1.1%), 0 events -2026-02-04T18:53:07.826134Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1490/133889 blocks (1.1%), 0 events -2026-02-04T18:53:08.043188Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1500/133889 blocks (1.1%), 0 events -2026-02-04T18:53:08.292477Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1510/133889 blocks (1.1%), 0 events -2026-02-04T18:53:08.398051Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1520/133889 blocks (1.1%), 0 events -2026-02-04T18:53:08.619177Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1530/133889 blocks (1.1%), 0 events -2026-02-04T18:53:08.850678Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1540/133889 blocks (1.1%), 0 events -2026-02-04T18:53:08.970665Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1550/133889 blocks (1.2%), 0 events -2026-02-04T18:53:09.243551Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1560/133889 blocks (1.2%), 0 events -2026-02-04T18:53:09.379191Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1570/133889 blocks (1.2%), 0 events -2026-02-04T18:53:09.627083Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1580/133889 blocks (1.2%), 0 events -2026-02-04T18:53:09.905482Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1590/133889 blocks (1.2%), 0 events -2026-02-04T18:53:10.054956Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1600/133889 blocks (1.2%), 0 events -2026-02-04T18:53:10.223432Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1610/133889 blocks (1.2%), 0 events -2026-02-04T18:53:10.418543Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1620/133889 blocks (1.2%), 0 events -2026-02-04T18:53:10.613487Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1630/133889 blocks (1.2%), 0 events -2026-02-04T18:53:10.945153Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1640/133889 blocks (1.2%), 0 events -2026-02-04T18:53:10.987052Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1650/133889 blocks (1.2%), 0 events -2026-02-04T18:53:11.241083Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1660/133889 blocks (1.2%), 0 events -2026-02-04T18:53:11.468529Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1670/133889 blocks (1.2%), 0 events -2026-02-04T18:53:11.606387Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1680/133889 blocks (1.3%), 0 events -2026-02-04T18:53:11.958729Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1690/133889 blocks (1.3%), 0 events -2026-02-04T18:53:11.994371Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1700/133889 blocks (1.3%), 0 events -2026-02-04T18:53:12.233484Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1710/133889 blocks (1.3%), 0 events -2026-02-04T18:53:12.385947Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1720/133889 blocks (1.3%), 0 events -2026-02-04T18:53:12.600202Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1730/133889 blocks (1.3%), 0 events -2026-02-04T18:53:12.798854Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1740/133889 blocks (1.3%), 0 events -2026-02-04T18:53:13.055165Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1750/133889 blocks (1.3%), 0 events -2026-02-04T18:53:13.190572Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1760/133889 blocks (1.3%), 0 events -2026-02-04T18:53:13.382594Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1770/133889 blocks (1.3%), 0 events -2026-02-04T18:53:13.613317Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1780/133889 blocks (1.3%), 0 events -2026-02-04T18:53:13.841637Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1790/133889 blocks (1.3%), 0 events -2026-02-04T18:53:14.057344Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1800/133889 blocks (1.3%), 0 events -2026-02-04T18:53:14.225781Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1810/133889 blocks (1.4%), 0 events -2026-02-04T18:53:14.390552Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1820/133889 blocks (1.4%), 0 events -2026-02-04T18:53:14.642769Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1830/133889 blocks (1.4%), 0 events -2026-02-04T18:53:14.827598Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1840/133889 blocks (1.4%), 0 events -2026-02-04T18:53:15.105147Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1850/133889 blocks (1.4%), 0 events -2026-02-04T18:53:15.180765Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1860/133889 blocks (1.4%), 0 events -2026-02-04T18:53:15.450652Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1870/133889 blocks (1.4%), 0 events -2026-02-04T18:53:15.668528Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1880/133889 blocks (1.4%), 0 events -2026-02-04T18:53:15.831030Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1890/133889 blocks (1.4%), 0 events -2026-02-04T18:53:16.014936Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1900/133889 blocks (1.4%), 0 events -2026-02-04T18:53:16.196942Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1910/133889 blocks (1.4%), 0 events -2026-02-04T18:53:16.378310Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1920/133889 blocks (1.4%), 0 events -2026-02-04T18:53:16.709662Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1930/133889 blocks (1.4%), 0 events -2026-02-04T18:53:16.793281Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1940/133889 blocks (1.4%), 0 events -2026-02-04T18:53:17.031304Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1950/133889 blocks (1.5%), 0 events -2026-02-04T18:53:17.234783Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1960/133889 blocks (1.5%), 0 events -2026-02-04T18:53:17.411886Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1970/133889 blocks (1.5%), 0 events -2026-02-04T18:53:17.625847Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1980/133889 blocks (1.5%), 0 events -2026-02-04T18:53:17.825852Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 1990/133889 blocks (1.5%), 0 events -2026-02-04T18:53:17.986246Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2000/133889 blocks (1.5%), 0 events -2026-02-04T18:53:18.252303Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2010/133889 blocks (1.5%), 0 events -2026-02-04T18:53:18.426571Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2020/133889 blocks (1.5%), 0 events -2026-02-04T18:53:18.651551Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2030/133889 blocks (1.5%), 0 events -2026-02-04T18:53:18.842021Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2040/133889 blocks (1.5%), 0 events -2026-02-04T18:53:19.051604Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2050/133889 blocks (1.5%), 0 events -2026-02-04T18:53:19.199550Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2060/133889 blocks (1.5%), 0 events -2026-02-04T18:53:19.361725Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2070/133889 blocks (1.5%), 0 events -2026-02-04T18:53:19.599162Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2080/133889 blocks (1.6%), 0 events -2026-02-04T18:53:19.859318Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2090/133889 blocks (1.6%), 0 events -2026-02-04T18:53:20.057567Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2100/133889 blocks (1.6%), 0 events -2026-02-04T18:53:20.198978Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2110/133889 blocks (1.6%), 0 events -2026-02-04T18:53:20.428595Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2120/133889 blocks (1.6%), 0 events -2026-02-04T18:53:20.670568Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2130/133889 blocks (1.6%), 0 events -2026-02-04T18:53:20.903026Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2140/133889 blocks (1.6%), 0 events -2026-02-04T18:53:20.992191Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2150/133889 blocks (1.6%), 0 events -2026-02-04T18:53:21.179994Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2160/133889 blocks (1.6%), 0 events -2026-02-04T18:53:21.434889Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2170/133889 blocks (1.6%), 0 events -2026-02-04T18:53:21.616983Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2180/133889 blocks (1.6%), 0 events -2026-02-04T18:53:21.786710Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2190/133889 blocks (1.6%), 0 events -2026-02-04T18:53:22.029276Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2200/133889 blocks (1.6%), 0 events -2026-02-04T18:53:22.190847Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2210/133889 blocks (1.6%), 0 events -2026-02-04T18:53:22.444537Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2220/133889 blocks (1.7%), 0 events -2026-02-04T18:53:22.622999Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2230/133889 blocks (1.7%), 0 events -2026-02-04T18:53:22.849126Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2240/133889 blocks (1.7%), 0 events -2026-02-04T18:53:23.049312Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2250/133889 blocks (1.7%), 0 events -2026-02-04T18:53:23.257720Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2260/133889 blocks (1.7%), 0 events -2026-02-04T18:53:23.492181Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2270/133889 blocks (1.7%), 0 events -2026-02-04T18:53:23.658724Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2280/133889 blocks (1.7%), 0 events -2026-02-04T18:53:23.782160Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2290/133889 blocks (1.7%), 0 events -2026-02-04T18:53:24.054859Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2300/133889 blocks (1.7%), 0 events -2026-02-04T18:53:24.239975Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2310/133889 blocks (1.7%), 0 events -2026-02-04T18:53:24.430625Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2320/133889 blocks (1.7%), 0 events -2026-02-04T18:53:24.664503Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2330/133889 blocks (1.7%), 0 events -2026-02-04T18:53:24.840477Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2340/133889 blocks (1.7%), 0 events -2026-02-04T18:53:25.098686Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2350/133889 blocks (1.8%), 0 events -2026-02-04T18:53:25.224026Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2360/133889 blocks (1.8%), 0 events -2026-02-04T18:53:25.375654Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2370/133889 blocks (1.8%), 0 events -2026-02-04T18:53:25.624997Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2380/133889 blocks (1.8%), 0 events -2026-02-04T18:53:25.831336Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2390/133889 blocks (1.8%), 0 events -2026-02-04T18:53:25.999486Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2400/133889 blocks (1.8%), 0 events -2026-02-04T18:53:26.246152Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2410/133889 blocks (1.8%), 0 events -2026-02-04T18:53:26.447172Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2420/133889 blocks (1.8%), 0 events -2026-02-04T18:53:26.670862Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2430/133889 blocks (1.8%), 0 events -2026-02-04T18:53:26.866823Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2440/133889 blocks (1.8%), 0 events -2026-02-04T18:53:27.057005Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2450/133889 blocks (1.8%), 0 events -2026-02-04T18:53:27.225034Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2460/133889 blocks (1.8%), 0 events -2026-02-04T18:53:27.462127Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2470/133889 blocks (1.8%), 0 events -2026-02-04T18:53:27.733644Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2480/133889 blocks (1.9%), 0 events -2026-02-04T18:53:27.776561Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2490/133889 blocks (1.9%), 0 events -2026-02-04T18:53:27.980154Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2500/133889 blocks (1.9%), 0 events -2026-02-04T18:53:28.246779Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2510/133889 blocks (1.9%), 0 events -2026-02-04T18:53:28.414551Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2520/133889 blocks (1.9%), 0 events -2026-02-04T18:53:28.596686Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2530/133889 blocks (1.9%), 0 events -2026-02-04T18:53:28.779946Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2540/133889 blocks (1.9%), 0 events -2026-02-04T18:53:28.985737Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2550/133889 blocks (1.9%), 0 events -2026-02-04T18:53:29.261712Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2560/133889 blocks (1.9%), 0 events -2026-02-04T18:53:29.446534Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2570/133889 blocks (1.9%), 0 events -2026-02-04T18:53:29.593928Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2580/133889 blocks (1.9%), 0 events -2026-02-04T18:53:29.821545Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2590/133889 blocks (1.9%), 0 events -2026-02-04T18:53:30.009048Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2600/133889 blocks (1.9%), 0 events -2026-02-04T18:53:30.213169Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2610/133889 blocks (1.9%), 0 events -2026-02-04T18:53:30.462799Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2620/133889 blocks (2.0%), 0 events -2026-02-04T18:53:30.572113Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2630/133889 blocks (2.0%), 0 events -2026-02-04T18:53:30.868704Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2640/133889 blocks (2.0%), 0 events -2026-02-04T18:53:30.996920Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2650/133889 blocks (2.0%), 0 events -2026-02-04T18:53:31.245386Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2660/133889 blocks (2.0%), 0 events -2026-02-04T18:53:31.405591Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2670/133889 blocks (2.0%), 0 events -2026-02-04T18:53:31.649347Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2680/133889 blocks (2.0%), 0 events -2026-02-04T18:53:31.913307Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2690/133889 blocks (2.0%), 0 events -2026-02-04T18:53:32.005135Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2700/133889 blocks (2.0%), 0 events -2026-02-04T18:53:32.172928Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2710/133889 blocks (2.0%), 0 events -2026-02-04T18:53:32.441782Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2720/133889 blocks (2.0%), 0 events -2026-02-04T18:53:32.613095Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2730/133889 blocks (2.0%), 0 events -2026-02-04T18:53:32.815366Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2740/133889 blocks (2.0%), 0 events -2026-02-04T18:53:32.967023Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2750/133889 blocks (2.1%), 0 events -2026-02-04T18:53:33.181735Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2760/133889 blocks (2.1%), 0 events -2026-02-04T18:53:33.497044Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2770/133889 blocks (2.1%), 0 events -2026-02-04T18:53:33.653833Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2780/133889 blocks (2.1%), 0 events -2026-02-04T18:53:33.831415Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2790/133889 blocks (2.1%), 0 events -2026-02-04T18:53:34.011882Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2800/133889 blocks (2.1%), 0 events -2026-02-04T18:53:34.268444Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2810/133889 blocks (2.1%), 0 events -2026-02-04T18:53:34.373102Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2820/133889 blocks (2.1%), 0 events -2026-02-04T18:53:34.616342Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2830/133889 blocks (2.1%), 0 events -2026-02-04T18:53:34.850455Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2840/133889 blocks (2.1%), 0 events -2026-02-04T18:53:35.061068Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2850/133889 blocks (2.1%), 0 events -2026-02-04T18:53:35.265199Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2860/133889 blocks (2.1%), 0 events -2026-02-04T18:53:35.381250Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2870/133889 blocks (2.1%), 0 events -2026-02-04T18:53:35.626876Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2880/133889 blocks (2.2%), 0 events -2026-02-04T18:53:35.767398Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2890/133889 blocks (2.2%), 0 events -2026-02-04T18:53:36.076777Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2900/133889 blocks (2.2%), 0 events -2026-02-04T18:53:36.168086Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2910/133889 blocks (2.2%), 0 events -2026-02-04T18:53:36.427151Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2920/133889 blocks (2.2%), 0 events -2026-02-04T18:53:36.631871Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2930/133889 blocks (2.2%), 0 events -2026-02-04T18:53:36.828404Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2940/133889 blocks (2.2%), 0 events -2026-02-04T18:53:37.002113Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2950/133889 blocks (2.2%), 0 events -2026-02-04T18:53:37.184940Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2960/133889 blocks (2.2%), 0 events -2026-02-04T18:53:37.430162Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2970/133889 blocks (2.2%), 0 events -2026-02-04T18:53:37.694451Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2980/133889 blocks (2.2%), 0 events -2026-02-04T18:53:37.785621Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 2990/133889 blocks (2.2%), 0 events -2026-02-04T18:53:38.018706Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3000/133889 blocks (2.2%), 0 events -2026-02-04T18:53:38.205594Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3010/133889 blocks (2.2%), 0 events -2026-02-04T18:53:38.389720Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3020/133889 blocks (2.3%), 0 events -2026-02-04T18:53:38.569352Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3030/133889 blocks (2.3%), 0 events -2026-02-04T18:53:38.783047Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3040/133889 blocks (2.3%), 0 events -2026-02-04T18:53:39.038754Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3050/133889 blocks (2.3%), 0 events -2026-02-04T18:53:39.259525Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3060/133889 blocks (2.3%), 0 events -2026-02-04T18:53:39.397158Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3070/133889 blocks (2.3%), 0 events -2026-02-04T18:53:39.587498Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3080/133889 blocks (2.3%), 0 events -2026-02-04T18:53:39.824777Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3090/133889 blocks (2.3%), 0 events -2026-02-04T18:53:40.039345Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3100/133889 blocks (2.3%), 0 events -2026-02-04T18:53:40.304562Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3110/133889 blocks (2.3%), 0 events -2026-02-04T18:53:40.439210Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3120/133889 blocks (2.3%), 0 events -2026-02-04T18:53:40.584194Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3130/133889 blocks (2.3%), 0 events -2026-02-04T18:53:40.838632Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3140/133889 blocks (2.3%), 0 events -2026-02-04T18:53:41.033928Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3150/133889 blocks (2.4%), 0 events -2026-02-04T18:53:41.320452Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3160/133889 blocks (2.4%), 0 events -2026-02-04T18:53:41.363959Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3170/133889 blocks (2.4%), 0 events -2026-02-04T18:53:41.628338Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3180/133889 blocks (2.4%), 0 events -2026-02-04T18:53:41.844486Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3190/133889 blocks (2.4%), 0 events -2026-02-04T18:53:42.048641Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3200/133889 blocks (2.4%), 0 events -2026-02-04T18:53:42.223289Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3210/133889 blocks (2.4%), 0 events -2026-02-04T18:53:42.398957Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3220/133889 blocks (2.4%), 0 events -2026-02-04T18:53:42.637639Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3230/133889 blocks (2.4%), 0 events -2026-02-04T18:53:42.922967Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3240/133889 blocks (2.4%), 0 events -2026-02-04T18:53:42.964463Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3250/133889 blocks (2.4%), 0 events -2026-02-04T18:53:43.227972Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3260/133889 blocks (2.4%), 0 events -2026-02-04T18:53:43.449748Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3270/133889 blocks (2.4%), 0 events -2026-02-04T18:53:43.636585Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3280/133889 blocks (2.4%), 0 events -2026-02-04T18:53:43.835747Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3290/133889 blocks (2.5%), 0 events -2026-02-04T18:53:44.001531Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3300/133889 blocks (2.5%), 0 events -2026-02-04T18:53:44.231232Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3310/133889 blocks (2.5%), 0 events -2026-02-04T18:53:44.464826Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3320/133889 blocks (2.5%), 0 events -2026-02-04T18:53:44.616744Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3330/133889 blocks (2.5%), 0 events -2026-02-04T18:53:44.801811Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3340/133889 blocks (2.5%), 0 events -2026-02-04T18:53:45.021102Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3350/133889 blocks (2.5%), 0 events -2026-02-04T18:53:45.252763Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3360/133889 blocks (2.5%), 0 events -2026-02-04T18:53:45.387813Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3370/133889 blocks (2.5%), 0 events -2026-02-04T18:53:45.606489Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3380/133889 blocks (2.5%), 0 events -2026-02-04T18:53:45.854906Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3390/133889 blocks (2.5%), 0 events -2026-02-04T18:53:46.070527Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3400/133889 blocks (2.5%), 0 events -2026-02-04T18:53:46.208862Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3410/133889 blocks (2.5%), 0 events -2026-02-04T18:53:46.461894Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3420/133889 blocks (2.6%), 0 events -2026-02-04T18:53:46.633571Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3430/133889 blocks (2.6%), 0 events -2026-02-04T18:53:46.769265Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3440/133889 blocks (2.6%), 0 events -2026-02-04T18:53:46.965277Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3450/133889 blocks (2.6%), 0 events -2026-02-04T18:53:47.218824Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3460/133889 blocks (2.6%), 0 events -2026-02-04T18:53:47.400228Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3470/133889 blocks (2.6%), 0 events -2026-02-04T18:53:47.648153Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3480/133889 blocks (2.6%), 0 events -2026-02-04T18:53:47.832556Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3490/133889 blocks (2.6%), 0 events -2026-02-04T18:53:48.017580Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3500/133889 blocks (2.6%), 0 events -2026-02-04T18:53:48.209588Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3510/133889 blocks (2.6%), 0 events -2026-02-04T18:53:48.382798Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3520/133889 blocks (2.6%), 0 events -2026-02-04T18:53:48.659606Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3530/133889 blocks (2.6%), 0 events -2026-02-04T18:53:48.847799Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3540/133889 blocks (2.6%), 0 events -2026-02-04T18:53:49.054288Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3550/133889 blocks (2.7%), 0 events -2026-02-04T18:53:49.219440Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3560/133889 blocks (2.7%), 0 events -2026-02-04T18:53:49.374592Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3570/133889 blocks (2.7%), 0 events -2026-02-04T18:53:49.741902Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3580/133889 blocks (2.7%), 0 events -2026-02-04T18:53:49.785979Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3590/133889 blocks (2.7%), 0 events -2026-02-04T18:53:50.028943Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3600/133889 blocks (2.7%), 0 events -2026-02-04T18:53:50.263481Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3610/133889 blocks (2.7%), 0 events -2026-02-04T18:53:50.449201Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3620/133889 blocks (2.7%), 0 events -2026-02-04T18:53:50.614270Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3630/133889 blocks (2.7%), 0 events -2026-02-04T18:53:50.847673Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3640/133889 blocks (2.7%), 0 events -2026-02-04T18:53:51.014348Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3650/133889 blocks (2.7%), 0 events -2026-02-04T18:53:51.172425Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3660/133889 blocks (2.7%), 0 events -2026-02-04T18:53:51.408954Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3670/133889 blocks (2.7%), 0 events -2026-02-04T18:53:51.617268Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3680/133889 blocks (2.7%), 0 events -2026-02-04T18:53:51.866186Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3690/133889 blocks (2.8%), 0 events -2026-02-04T18:53:52.012420Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3700/133889 blocks (2.8%), 0 events -2026-02-04T18:53:52.205125Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3710/133889 blocks (2.8%), 0 events -2026-02-04T18:53:52.406498Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3720/133889 blocks (2.8%), 0 events -2026-02-04T18:53:52.633767Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3730/133889 blocks (2.8%), 0 events -2026-02-04T18:53:52.852869Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3740/133889 blocks (2.8%), 0 events -2026-02-04T18:53:52.966923Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3750/133889 blocks (2.8%), 0 events -2026-02-04T18:53:53.198585Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3760/133889 blocks (2.8%), 0 events -2026-02-04T18:53:53.454847Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3770/133889 blocks (2.8%), 0 events -2026-02-04T18:53:53.566110Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3780/133889 blocks (2.8%), 0 events -2026-02-04T18:53:53.935437Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3790/133889 blocks (2.8%), 0 events -2026-02-04T18:53:53.981320Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3800/133889 blocks (2.8%), 0 events -2026-02-04T18:53:54.164797Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3810/133889 blocks (2.8%), 0 events -2026-02-04T18:53:54.457182Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3820/133889 blocks (2.9%), 0 events -2026-02-04T18:53:54.642697Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3830/133889 blocks (2.9%), 0 events -2026-02-04T18:53:54.802267Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3840/133889 blocks (2.9%), 0 events -2026-02-04T18:53:55.033736Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3850/133889 blocks (2.9%), 0 events -2026-02-04T18:53:55.229080Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3860/133889 blocks (2.9%), 0 events -2026-02-04T18:53:55.472727Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3870/133889 blocks (2.9%), 0 events -2026-02-04T18:53:55.602329Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3880/133889 blocks (2.9%), 0 events -2026-02-04T18:53:55.822377Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3890/133889 blocks (2.9%), 0 events -2026-02-04T18:53:56.028597Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3900/133889 blocks (2.9%), 0 events -2026-02-04T18:53:56.358460Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3910/133889 blocks (2.9%), 0 events -2026-02-04T18:53:56.404139Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3920/133889 blocks (2.9%), 0 events -2026-02-04T18:53:56.567259Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3930/133889 blocks (2.9%), 0 events -2026-02-04T18:53:56.843028Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3940/133889 blocks (2.9%), 0 events -2026-02-04T18:53:57.080217Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3950/133889 blocks (2.9%), 0 events -2026-02-04T18:53:57.166143Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3960/133889 blocks (3.0%), 0 events -2026-02-04T18:53:57.413401Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3970/133889 blocks (3.0%), 0 events -2026-02-04T18:53:57.610047Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3980/133889 blocks (3.0%), 0 events -2026-02-04T18:53:57.781403Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 3990/133889 blocks (3.0%), 0 events -2026-02-04T18:53:58.125555Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4000/133889 blocks (3.0%), 0 events -2026-02-04T18:53:58.164389Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4010/133889 blocks (3.0%), 0 events -2026-02-04T18:53:58.450057Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4020/133889 blocks (3.0%), 0 events -2026-02-04T18:53:58.653563Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4030/133889 blocks (3.0%), 0 events -2026-02-04T18:53:58.826066Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4040/133889 blocks (3.0%), 0 events -2026-02-04T18:53:59.036387Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4050/133889 blocks (3.0%), 0 events -2026-02-04T18:53:59.182346Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4060/133889 blocks (3.0%), 0 events -2026-02-04T18:53:59.371328Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4070/133889 blocks (3.0%), 0 events -2026-02-04T18:53:59.697422Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4080/133889 blocks (3.0%), 0 events -2026-02-04T18:53:59.781288Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4090/133889 blocks (3.1%), 0 events -2026-02-04T18:53:59.981690Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4100/133889 blocks (3.1%), 0 events -2026-02-04T18:54:00.239960Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4110/133889 blocks (3.1%), 0 events -2026-02-04T18:54:00.418442Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4120/133889 blocks (3.1%), 0 events -2026-02-04T18:54:00.718469Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4130/133889 blocks (3.1%), 0 events -2026-02-04T18:54:00.829725Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4140/133889 blocks (3.1%), 0 events -2026-02-04T18:54:01.009563Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4150/133889 blocks (3.1%), 0 events -2026-02-04T18:54:01.240395Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4160/133889 blocks (3.1%), 0 events -2026-02-04T18:54:01.447874Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4170/133889 blocks (3.1%), 0 events -2026-02-04T18:54:01.606102Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4180/133889 blocks (3.1%), 0 events -2026-02-04T18:54:01.848258Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4190/133889 blocks (3.1%), 0 events -2026-02-04T18:54:01.969607Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4200/133889 blocks (3.1%), 0 events -2026-02-04T18:54:02.323458Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4210/133889 blocks (3.1%), 0 events -2026-02-04T18:54:02.359514Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4220/133889 blocks (3.2%), 0 events -2026-02-04T18:54:02.573563Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4230/133889 blocks (3.2%), 0 events -2026-02-04T18:54:02.852071Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4240/133889 blocks (3.2%), 0 events -2026-02-04T18:54:03.012972Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4250/133889 blocks (3.2%), 0 events -2026-02-04T18:54:03.235449Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4260/133889 blocks (3.2%), 0 events -2026-02-04T18:54:03.411045Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4270/133889 blocks (3.2%), 0 events -2026-02-04T18:54:03.608774Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4280/133889 blocks (3.2%), 0 events -2026-02-04T18:54:03.903468Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4290/133889 blocks (3.2%), 0 events -2026-02-04T18:54:04.016194Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4300/133889 blocks (3.2%), 0 events -2026-02-04T18:54:04.258396Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4310/133889 blocks (3.2%), 0 events -2026-02-04T18:54:04.451709Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4320/133889 blocks (3.2%), 0 events -2026-02-04T18:54:04.615193Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4330/133889 blocks (3.2%), 0 events -2026-02-04T18:54:04.810127Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4340/133889 blocks (3.2%), 0 events -2026-02-04T18:54:04.980929Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4350/133889 blocks (3.2%), 0 events -2026-02-04T18:54:05.179168Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4360/133889 blocks (3.3%), 0 events -2026-02-04T18:54:05.470645Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4370/133889 blocks (3.3%), 0 events -2026-02-04T18:54:05.661531Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4380/133889 blocks (3.3%), 0 events -2026-02-04T18:54:05.828654Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4390/133889 blocks (3.3%), 0 events -2026-02-04T18:54:06.106794Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4400/133889 blocks (3.3%), 0 events -2026-02-04T18:54:06.230241Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4410/133889 blocks (3.3%), 0 events -2026-02-04T18:54:06.386827Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4420/133889 blocks (3.3%), 0 events -2026-02-04T18:54:06.616380Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4430/133889 blocks (3.3%), 0 events -2026-02-04T18:54:06.797564Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4440/133889 blocks (3.3%), 0 events -2026-02-04T18:54:07.043502Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4450/133889 blocks (3.3%), 0 events -2026-02-04T18:54:07.186641Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4460/133889 blocks (3.3%), 0 events -2026-02-04T18:54:07.418974Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4470/133889 blocks (3.3%), 0 events -2026-02-04T18:54:07.641548Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4480/133889 blocks (3.3%), 0 events -2026-02-04T18:54:07.813109Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4490/133889 blocks (3.4%), 0 events -2026-02-04T18:54:08.091778Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4500/133889 blocks (3.4%), 0 events -2026-02-04T18:54:08.190512Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4510/133889 blocks (3.4%), 0 events -2026-02-04T18:54:08.453088Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4520/133889 blocks (3.4%), 0 events -2026-02-04T18:54:08.658909Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4530/133889 blocks (3.4%), 0 events -2026-02-04T18:54:08.858563Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4540/133889 blocks (3.4%), 0 events -2026-02-04T18:54:09.104418Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4550/133889 blocks (3.4%), 0 events -2026-02-04T18:54:09.201653Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4560/133889 blocks (3.4%), 0 events -2026-02-04T18:54:09.393608Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4570/133889 blocks (3.4%), 0 events -2026-02-04T18:54:09.663702Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4580/133889 blocks (3.4%), 0 events -2026-02-04T18:54:09.830526Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4590/133889 blocks (3.4%), 0 events -2026-02-04T18:54:09.997797Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4600/133889 blocks (3.4%), 0 events -2026-02-04T18:54:10.237755Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4610/133889 blocks (3.4%), 0 events -2026-02-04T18:54:10.359104Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4620/133889 blocks (3.4%), 0 events -2026-02-04T18:54:10.715525Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4630/133889 blocks (3.5%), 0 events -2026-02-04T18:54:10.798758Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4640/133889 blocks (3.5%), 0 events -2026-02-04T18:54:11.033174Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4650/133889 blocks (3.5%), 0 events -2026-02-04T18:54:11.262169Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4660/133889 blocks (3.5%), 0 events -2026-02-04T18:54:11.417392Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4670/133889 blocks (3.5%), 0 events -2026-02-04T18:54:11.578135Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4680/133889 blocks (3.5%), 0 events -2026-02-04T18:54:11.849155Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4690/133889 blocks (3.5%), 0 events -2026-02-04T18:54:12.005150Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4700/133889 blocks (3.5%), 0 events -2026-02-04T18:54:12.251412Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4710/133889 blocks (3.5%), 0 events -2026-02-04T18:54:12.454227Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4720/133889 blocks (3.5%), 0 events -2026-02-04T18:54:12.646812Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4730/133889 blocks (3.5%), 0 events -2026-02-04T18:54:12.811630Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4740/133889 blocks (3.5%), 0 events -2026-02-04T18:54:13.045286Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4750/133889 blocks (3.5%), 0 events -2026-02-04T18:54:13.299791Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4760/133889 blocks (3.6%), 0 events -2026-02-04T18:54:13.380155Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4770/133889 blocks (3.6%), 0 events -2026-02-04T18:54:13.659085Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4780/133889 blocks (3.6%), 0 events -2026-02-04T18:54:13.854295Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4790/133889 blocks (3.6%), 0 events -2026-02-04T18:54:14.010742Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4800/133889 blocks (3.6%), 0 events -2026-02-04T18:54:14.255339Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4810/133889 blocks (3.6%), 0 events -2026-02-04T18:54:14.424028Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4820/133889 blocks (3.6%), 0 events -2026-02-04T18:54:14.635621Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4830/133889 blocks (3.6%), 0 events -2026-02-04T18:54:14.905812Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4840/133889 blocks (3.6%), 0 events -2026-02-04T18:54:14.969304Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4850/133889 blocks (3.6%), 0 events -2026-02-04T18:54:15.210388Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4860/133889 blocks (3.6%), 0 events -2026-02-04T18:54:15.432419Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4870/133889 blocks (3.6%), 0 events -2026-02-04T18:54:15.598886Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4880/133889 blocks (3.6%), 0 events -2026-02-04T18:54:15.780778Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4890/133889 blocks (3.7%), 0 events -2026-02-04T18:54:15.970573Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4900/133889 blocks (3.7%), 0 events -2026-02-04T18:54:16.258225Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4910/133889 blocks (3.7%), 0 events -2026-02-04T18:54:16.446881Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4920/133889 blocks (3.7%), 0 events -2026-02-04T18:54:16.652923Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4930/133889 blocks (3.7%), 0 events -2026-02-04T18:54:16.829421Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4940/133889 blocks (3.7%), 0 events -2026-02-04T18:54:17.040173Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4950/133889 blocks (3.7%), 0 events -2026-02-04T18:54:17.248548Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4960/133889 blocks (3.7%), 0 events -2026-02-04T18:54:17.373671Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4970/133889 blocks (3.7%), 0 events -2026-02-04T18:54:17.574805Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4980/133889 blocks (3.7%), 0 events -2026-02-04T18:54:17.880763Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 4990/133889 blocks (3.7%), 0 events -2026-02-04T18:54:18.067991Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5000/133889 blocks (3.7%), 0 events -2026-02-04T18:54:18.240765Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5010/133889 blocks (3.7%), 0 events -2026-02-04T18:54:18.543846Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5020/133889 blocks (3.7%), 0 events -2026-02-04T18:54:18.583024Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5030/133889 blocks (3.8%), 0 events -2026-02-04T18:54:18.787487Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5040/133889 blocks (3.8%), 0 events -2026-02-04T18:54:19.068283Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5050/133889 blocks (3.8%), 0 events -2026-02-04T18:54:19.193270Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5060/133889 blocks (3.8%), 0 events -2026-02-04T18:54:19.397891Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5070/133889 blocks (3.8%), 0 events -2026-02-04T18:54:19.656749Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5080/133889 blocks (3.8%), 0 events -2026-02-04T18:54:19.843563Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5090/133889 blocks (3.8%), 0 events -2026-02-04T18:54:20.114027Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5100/133889 blocks (3.8%), 0 events -2026-02-04T18:54:20.196851Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5110/133889 blocks (3.8%), 0 events -2026-02-04T18:54:20.431529Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5120/133889 blocks (3.8%), 0 events -2026-02-04T18:54:20.671175Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5130/133889 blocks (3.8%), 0 events -2026-02-04T18:54:20.816646Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5140/133889 blocks (3.8%), 0 events -2026-02-04T18:54:20.991231Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5150/133889 blocks (3.8%), 0 events -2026-02-04T18:54:21.198188Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5160/133889 blocks (3.9%), 0 events -2026-02-04T18:54:21.420752Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5170/133889 blocks (3.9%), 0 events -2026-02-04T18:54:21.719503Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5180/133889 blocks (3.9%), 0 events -2026-02-04T18:54:21.808466Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5190/133889 blocks (3.9%), 0 events -2026-02-04T18:54:22.029090Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5200/133889 blocks (3.9%), 0 events -2026-02-04T18:54:22.244958Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5210/133889 blocks (3.9%), 0 events -2026-02-04T18:54:22.400918Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5220/133889 blocks (3.9%), 0 events -2026-02-04T18:54:22.737038Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5230/133889 blocks (3.9%), 0 events -2026-02-04T18:54:22.774123Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5240/133889 blocks (3.9%), 0 events -2026-02-04T18:54:23.066274Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5250/133889 blocks (3.9%), 0 events -2026-02-04T18:54:23.291976Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5260/133889 blocks (3.9%), 0 events -2026-02-04T18:54:23.363633Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5270/133889 blocks (3.9%), 0 events -2026-02-04T18:54:23.583293Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5280/133889 blocks (3.9%), 0 events -2026-02-04T18:54:23.846719Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5290/133889 blocks (4.0%), 0 events -2026-02-04T18:54:24.008969Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5300/133889 blocks (4.0%), 0 events -2026-02-04T18:54:24.309490Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5310/133889 blocks (4.0%), 0 events -2026-02-04T18:54:24.384347Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5320/133889 blocks (4.0%), 0 events -2026-02-04T18:54:24.644539Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5330/133889 blocks (4.0%), 0 events -2026-02-04T18:54:24.865077Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5340/133889 blocks (4.0%), 0 events -2026-02-04T18:54:24.964605Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5350/133889 blocks (4.0%), 0 events -2026-02-04T18:54:25.210361Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5360/133889 blocks (4.0%), 0 events -2026-02-04T18:54:25.426276Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5370/133889 blocks (4.0%), 0 events -2026-02-04T18:54:25.651076Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5380/133889 blocks (4.0%), 0 events -2026-02-04T18:54:25.918340Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5390/133889 blocks (4.0%), 0 events -2026-02-04T18:54:26.002164Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5400/133889 blocks (4.0%), 0 events -2026-02-04T18:54:26.240462Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5410/133889 blocks (4.0%), 0 events -2026-02-04T18:54:26.445467Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5420/133889 blocks (4.0%), 0 events -2026-02-04T18:54:26.665605Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5430/133889 blocks (4.1%), 0 events -2026-02-04T18:54:26.835975Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5440/133889 blocks (4.1%), 0 events -2026-02-04T18:54:26.997912Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5450/133889 blocks (4.1%), 0 events -2026-02-04T18:54:27.258792Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5460/133889 blocks (4.1%), 0 events -2026-02-04T18:54:27.456114Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5470/133889 blocks (4.1%), 0 events -2026-02-04T18:54:27.644877Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5480/133889 blocks (4.1%), 0 events -2026-02-04T18:54:27.856207Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5490/133889 blocks (4.1%), 0 events -2026-02-04T18:54:28.012253Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5500/133889 blocks (4.1%), 0 events -2026-02-04T18:54:28.207918Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5510/133889 blocks (4.1%), 0 events -2026-02-04T18:54:28.381874Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5520/133889 blocks (4.1%), 0 events -2026-02-04T18:54:28.664797Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5530/133889 blocks (4.1%), 0 events -2026-02-04T18:54:28.825260Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5540/133889 blocks (4.1%), 0 events -2026-02-04T18:54:29.065799Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5550/133889 blocks (4.1%), 0 events -2026-02-04T18:54:29.180159Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5560/133889 blocks (4.2%), 0 events -2026-02-04T18:54:29.377802Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5570/133889 blocks (4.2%), 0 events -2026-02-04T18:54:29.637833Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5580/133889 blocks (4.2%), 0 events -2026-02-04T18:54:29.789378Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5590/133889 blocks (4.2%), 0 events -2026-02-04T18:54:30.110111Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5600/133889 blocks (4.2%), 0 events -2026-02-04T18:54:30.221719Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5610/133889 blocks (4.2%), 0 events -2026-02-04T18:54:30.402560Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5620/133889 blocks (4.2%), 0 events -2026-02-04T18:54:30.635820Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5630/133889 blocks (4.2%), 0 events -2026-02-04T18:54:30.801646Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5640/133889 blocks (4.2%), 0 events -2026-02-04T18:54:30.991537Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5650/133889 blocks (4.2%), 0 events -2026-02-04T18:54:31.226699Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5660/133889 blocks (4.2%), 0 events -2026-02-04T18:54:31.448882Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5670/133889 blocks (4.2%), 0 events -2026-02-04T18:54:31.683677Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5680/133889 blocks (4.2%), 0 events -2026-02-04T18:54:31.803978Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5690/133889 blocks (4.2%), 0 events -2026-02-04T18:54:31.989366Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5700/133889 blocks (4.3%), 0 events -2026-02-04T18:54:32.206437Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5710/133889 blocks (4.3%), 0 events -2026-02-04T18:54:32.379439Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5720/133889 blocks (4.3%), 0 events -2026-02-04T18:54:32.697796Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5730/133889 blocks (4.3%), 0 events -2026-02-04T18:54:32.793134Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5740/133889 blocks (4.3%), 0 events -2026-02-04T18:54:33.014143Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5750/133889 blocks (4.3%), 0 events -2026-02-04T18:54:33.256183Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5760/133889 blocks (4.3%), 0 events -2026-02-04T18:54:33.420644Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5770/133889 blocks (4.3%), 0 events -2026-02-04T18:54:33.585845Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5780/133889 blocks (4.3%), 0 events -2026-02-04T18:54:33.819198Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5790/133889 blocks (4.3%), 0 events -2026-02-04T18:54:33.972703Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5800/133889 blocks (4.3%), 0 events -2026-02-04T18:54:34.302187Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5810/133889 blocks (4.3%), 0 events -2026-02-04T18:54:34.404835Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5820/133889 blocks (4.3%), 0 events -2026-02-04T18:54:34.662742Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5830/133889 blocks (4.4%), 0 events -2026-02-04T18:54:34.828349Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5840/133889 blocks (4.4%), 0 events -2026-02-04T18:54:35.030120Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5850/133889 blocks (4.4%), 0 events -2026-02-04T18:54:35.320158Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5860/133889 blocks (4.4%), 0 events -2026-02-04T18:54:35.359494Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5870/133889 blocks (4.4%), 0 events -2026-02-04T18:54:35.602481Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5880/133889 blocks (4.4%), 0 events -2026-02-04T18:54:35.875040Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5890/133889 blocks (4.4%), 0 events -2026-02-04T18:54:36.001618Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5900/133889 blocks (4.4%), 0 events -2026-02-04T18:54:36.223533Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5910/133889 blocks (4.4%), 0 events -2026-02-04T18:54:36.398036Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5920/133889 blocks (4.4%), 0 events -2026-02-04T18:54:36.618349Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5930/133889 blocks (4.4%), 0 events -2026-02-04T18:54:36.891987Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5940/133889 blocks (4.4%), 0 events -2026-02-04T18:54:37.035605Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5950/133889 blocks (4.4%), 0 events -2026-02-04T18:54:37.233892Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5960/133889 blocks (4.5%), 0 events -2026-02-04T18:54:37.462232Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5970/133889 blocks (4.5%), 0 events -2026-02-04T18:54:37.582184Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5980/133889 blocks (4.5%), 0 events -2026-02-04T18:54:37.940277Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 5990/133889 blocks (4.5%), 0 events -2026-02-04T18:54:37.981980Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6000/133889 blocks (4.5%), 0 events -2026-02-04T18:54:38.252988Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6010/133889 blocks (4.5%), 0 events -2026-02-04T18:54:38.464942Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6020/133889 blocks (4.5%), 0 events -2026-02-04T18:54:38.633905Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6030/133889 blocks (4.5%), 0 events -2026-02-04T18:54:38.829534Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6040/133889 blocks (4.5%), 0 events -2026-02-04T18:54:39.057092Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6050/133889 blocks (4.5%), 0 events -2026-02-04T18:54:39.178700Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6060/133889 blocks (4.5%), 0 events -2026-02-04T18:54:39.407083Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6070/133889 blocks (4.5%), 0 events -2026-02-04T18:54:39.631526Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6080/133889 blocks (4.5%), 0 events -2026-02-04T18:54:39.785866Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6090/133889 blocks (4.5%), 0 events -2026-02-04T18:54:40.072112Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6100/133889 blocks (4.6%), 0 events -2026-02-04T18:54:40.254725Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6110/133889 blocks (4.6%), 0 events -2026-02-04T18:54:40.444287Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6120/133889 blocks (4.6%), 0 events -2026-02-04T18:54:40.605758Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6130/133889 blocks (4.6%), 0 events -2026-02-04T18:54:40.837540Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6140/133889 blocks (4.6%), 0 events -2026-02-04T18:54:41.083720Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6150/133889 blocks (4.6%), 0 events -2026-02-04T18:54:41.229011Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6160/133889 blocks (4.6%), 0 events -2026-02-04T18:54:41.418451Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6170/133889 blocks (4.6%), 0 events -2026-02-04T18:54:41.656404Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6180/133889 blocks (4.6%), 0 events -2026-02-04T18:54:41.811542Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6190/133889 blocks (4.6%), 0 events -2026-02-04T18:54:42.027747Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6200/133889 blocks (4.6%), 0 events -2026-02-04T18:54:42.193303Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6210/133889 blocks (4.6%), 0 events -2026-02-04T18:54:42.375586Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6220/133889 blocks (4.6%), 0 events -2026-02-04T18:54:42.658437Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6230/133889 blocks (4.7%), 0 events -2026-02-04T18:54:42.862230Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6240/133889 blocks (4.7%), 0 events -2026-02-04T18:54:42.989930Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6250/133889 blocks (4.7%), 0 events -2026-02-04T18:54:43.219659Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6260/133889 blocks (4.7%), 0 events -2026-02-04T18:54:43.468004Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6270/133889 blocks (4.7%), 0 events -2026-02-04T18:54:43.617027Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6280/133889 blocks (4.7%), 0 events -2026-02-04T18:54:43.772674Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6290/133889 blocks (4.7%), 0 events -2026-02-04T18:54:44.041709Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6300/133889 blocks (4.7%), 0 events -2026-02-04T18:54:44.262822Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6310/133889 blocks (4.7%), 0 events -2026-02-04T18:54:44.422958Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6320/133889 blocks (4.7%), 0 events -2026-02-04T18:54:44.754264Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6330/133889 blocks (4.7%), 0 events -2026-02-04T18:54:44.788868Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6340/133889 blocks (4.7%), 0 events -2026-02-04T18:54:45.010654Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6350/133889 blocks (4.7%), 0 events -2026-02-04T18:54:45.314652Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6360/133889 blocks (4.7%), 0 events -2026-02-04T18:54:45.392842Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6370/133889 blocks (4.8%), 0 events -2026-02-04T18:54:45.660019Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6380/133889 blocks (4.8%), 0 events -2026-02-04T18:54:45.835765Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6390/133889 blocks (4.8%), 0 events -2026-02-04T18:54:45.969679Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6400/133889 blocks (4.8%), 0 events -2026-02-04T18:54:46.233517Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6410/133889 blocks (4.8%), 0 events -2026-02-04T18:54:46.414740Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6420/133889 blocks (4.8%), 0 events -2026-02-04T18:54:46.571843Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6430/133889 blocks (4.8%), 0 events -2026-02-04T18:54:46.885104Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6440/133889 blocks (4.8%), 0 events -2026-02-04T18:54:47.030187Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6450/133889 blocks (4.8%), 0 events -2026-02-04T18:54:47.236244Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6460/133889 blocks (4.8%), 0 events -2026-02-04T18:54:47.438667Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6470/133889 blocks (4.8%), 0 events -2026-02-04T18:54:47.649966Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6480/133889 blocks (4.8%), 0 events -2026-02-04T18:54:47.776690Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6490/133889 blocks (4.8%), 0 events -2026-02-04T18:54:48.003373Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6500/133889 blocks (4.9%), 0 events -2026-02-04T18:54:48.261530Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6510/133889 blocks (4.9%), 0 events -2026-02-04T18:54:48.460912Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6520/133889 blocks (4.9%), 0 events -2026-02-04T18:54:48.645874Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6530/133889 blocks (4.9%), 0 events -2026-02-04T18:54:48.775302Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6540/133889 blocks (4.9%), 0 events -2026-02-04T18:54:49.034130Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6550/133889 blocks (4.9%), 0 events -2026-02-04T18:54:49.192195Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6560/133889 blocks (4.9%), 0 events -2026-02-04T18:54:49.510767Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6570/133889 blocks (4.9%), 0 events -2026-02-04T18:54:49.637751Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6580/133889 blocks (4.9%), 0 events -2026-02-04T18:54:49.843656Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6590/133889 blocks (4.9%), 0 events -2026-02-04T18:54:50.069327Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6600/133889 blocks (4.9%), 0 events -2026-02-04T18:54:50.247195Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6610/133889 blocks (4.9%), 0 events -2026-02-04T18:54:50.420627Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6620/133889 blocks (4.9%), 0 events -2026-02-04T18:54:50.636102Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6630/133889 blocks (5.0%), 0 events -2026-02-04T18:54:50.807632Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6640/133889 blocks (5.0%), 0 events -2026-02-04T18:54:51.078968Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6650/133889 blocks (5.0%), 0 events -2026-02-04T18:54:51.184959Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6660/133889 blocks (5.0%), 0 events -2026-02-04T18:54:51.414100Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6670/133889 blocks (5.0%), 0 events -2026-02-04T18:54:51.603031Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6680/133889 blocks (5.0%), 0 events -2026-02-04T18:54:51.801972Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6690/133889 blocks (5.0%), 0 events -2026-02-04T18:54:51.986295Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6700/133889 blocks (5.0%), 0 events -2026-02-04T18:54:52.248383Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6710/133889 blocks (5.0%), 0 events -2026-02-04T18:54:52.457695Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6720/133889 blocks (5.0%), 0 events -2026-02-04T18:54:52.653994Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6730/133889 blocks (5.0%), 0 events -2026-02-04T18:54:52.827793Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6740/133889 blocks (5.0%), 0 events -2026-02-04T18:54:53.030710Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6750/133889 blocks (5.0%), 0 events -2026-02-04T18:54:53.184530Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6760/133889 blocks (5.0%), 0 events -2026-02-04T18:54:53.454415Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6770/133889 blocks (5.1%), 0 events -2026-02-04T18:54:53.714680Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6780/133889 blocks (5.1%), 0 events -2026-02-04T18:54:53.849030Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6790/133889 blocks (5.1%), 0 events -2026-02-04T18:54:54.022547Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6800/133889 blocks (5.1%), 0 events -2026-02-04T18:54:54.266019Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6810/133889 blocks (5.1%), 0 events -2026-02-04T18:54:54.437016Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6820/133889 blocks (5.1%), 0 events -2026-02-04T18:54:54.609423Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6830/133889 blocks (5.1%), 0 events -2026-02-04T18:54:54.781194Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6840/133889 blocks (5.1%), 0 events -2026-02-04T18:54:54.983711Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6850/133889 blocks (5.1%), 0 events -2026-02-04T18:54:55.277858Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6860/133889 blocks (5.1%), 0 events -2026-02-04T18:54:55.428168Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6870/133889 blocks (5.1%), 0 events -2026-02-04T18:54:55.633373Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6880/133889 blocks (5.1%), 0 events -2026-02-04T18:54:55.796165Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6890/133889 blocks (5.1%), 0 events -2026-02-04T18:54:56.003797Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6900/133889 blocks (5.2%), 0 events -2026-02-04T18:54:56.289229Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6910/133889 blocks (5.2%), 0 events -2026-02-04T18:54:56.375241Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6920/133889 blocks (5.2%), 0 events -2026-02-04T18:54:56.655447Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6930/133889 blocks (5.2%), 0 events -2026-02-04T18:54:56.843805Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6940/133889 blocks (5.2%), 0 events -2026-02-04T18:54:57.043755Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6950/133889 blocks (5.2%), 0 events -2026-02-04T18:54:57.200451Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6960/133889 blocks (5.2%), 0 events -2026-02-04T18:54:57.390518Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6970/133889 blocks (5.2%), 0 events -2026-02-04T18:54:57.562317Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6980/133889 blocks (5.2%), 0 events -2026-02-04T18:54:57.861710Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 6990/133889 blocks (5.2%), 0 events -2026-02-04T18:54:58.008734Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7000/133889 blocks (5.2%), 0 events -2026-02-04T18:54:58.213053Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7010/133889 blocks (5.2%), 0 events -2026-02-04T18:54:58.417186Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7020/133889 blocks (5.2%), 0 events -2026-02-04T18:54:58.582283Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7030/133889 blocks (5.2%), 0 events -2026-02-04T18:54:58.781428Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7040/133889 blocks (5.3%), 0 events -2026-02-04T18:54:59.052802Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7050/133889 blocks (5.3%), 0 events -2026-02-04T18:54:59.168676Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7060/133889 blocks (5.3%), 0 events -2026-02-04T18:54:59.471422Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7070/133889 blocks (5.3%), 0 events -2026-02-04T18:54:59.636074Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7080/133889 blocks (5.3%), 0 events -2026-02-04T18:54:59.808468Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7090/133889 blocks (5.3%), 0 events -2026-02-04T18:55:00.056800Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7100/133889 blocks (5.3%), 0 events -2026-02-04T18:55:00.264787Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7110/133889 blocks (5.3%), 0 events -2026-02-04T18:55:00.483790Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7120/133889 blocks (5.3%), 0 events -2026-02-04T18:55:00.620949Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7130/133889 blocks (5.3%), 0 events -2026-02-04T18:55:00.850210Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7140/133889 blocks (5.3%), 0 events -2026-02-04T18:55:01.044154Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7150/133889 blocks (5.3%), 0 events -2026-02-04T18:55:01.245978Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7160/133889 blocks (5.3%), 0 events -2026-02-04T18:55:01.413650Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7170/133889 blocks (5.4%), 0 events -2026-02-04T18:55:01.659595Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7180/133889 blocks (5.4%), 0 events -2026-02-04T18:55:01.808508Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7190/133889 blocks (5.4%), 0 events -2026-02-04T18:55:02.053418Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7200/133889 blocks (5.4%), 0 events -2026-02-04T18:55:02.269236Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7210/133889 blocks (5.4%), 0 events -2026-02-04T18:55:02.409902Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7220/133889 blocks (5.4%), 0 events -2026-02-04T18:55:02.621288Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7230/133889 blocks (5.4%), 0 events -2026-02-04T18:55:02.865826Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7240/133889 blocks (5.4%), 0 events -2026-02-04T18:55:02.982794Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7250/133889 blocks (5.4%), 0 events -2026-02-04T18:55:03.176014Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7260/133889 blocks (5.4%), 0 events -2026-02-04T18:55:03.460443Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7270/133889 blocks (5.4%), 0 events -2026-02-04T18:55:03.662086Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7280/133889 blocks (5.4%), 0 events -2026-02-04T18:55:03.806955Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7290/133889 blocks (5.4%), 0 events -2026-02-04T18:55:03.998762Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7300/133889 blocks (5.5%), 0 events -2026-02-04T18:55:04.237840Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7310/133889 blocks (5.5%), 0 events -2026-02-04T18:55:04.431684Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7320/133889 blocks (5.5%), 0 events -2026-02-04T18:55:04.719701Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7330/133889 blocks (5.5%), 0 events -2026-02-04T18:55:04.771101Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7340/133889 blocks (5.5%), 0 events -2026-02-04T18:55:04.983831Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7350/133889 blocks (5.5%), 0 events -2026-02-04T18:55:05.239740Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7360/133889 blocks (5.5%), 0 events -2026-02-04T18:55:05.391120Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7370/133889 blocks (5.5%), 0 events -2026-02-04T18:55:05.627140Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7380/133889 blocks (5.5%), 0 events -2026-02-04T18:55:05.843619Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7390/133889 blocks (5.5%), 0 events -2026-02-04T18:55:06.022731Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7400/133889 blocks (5.5%), 0 events -2026-02-04T18:55:06.286078Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7410/133889 blocks (5.5%), 0 events -2026-02-04T18:55:06.424932Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7420/133889 blocks (5.5%), 0 events -2026-02-04T18:55:06.592690Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7430/133889 blocks (5.5%), 0 events -2026-02-04T18:55:06.805382Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7440/133889 blocks (5.6%), 0 events -2026-02-04T18:55:07.041655Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7450/133889 blocks (5.6%), 0 events -2026-02-04T18:55:07.166679Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7460/133889 blocks (5.6%), 0 events -2026-02-04T18:55:07.432840Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7470/133889 blocks (5.6%), 0 events -2026-02-04T18:55:07.658962Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7480/133889 blocks (5.6%), 0 events -2026-02-04T18:55:07.862391Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7490/133889 blocks (5.6%), 0 events -2026-02-04T18:55:07.969030Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7500/133889 blocks (5.6%), 0 events -2026-02-04T18:55:08.197652Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7510/133889 blocks (5.6%), 0 events -2026-02-04T18:55:08.387563Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7520/133889 blocks (5.6%), 0 events -2026-02-04T18:55:08.576004Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7530/133889 blocks (5.6%), 0 events -2026-02-04T18:55:08.905680Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7540/133889 blocks (5.6%), 0 events -2026-02-04T18:55:08.999736Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7550/133889 blocks (5.6%), 0 events -2026-02-04T18:55:09.199598Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7560/133889 blocks (5.6%), 0 events -2026-02-04T18:55:09.454230Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7570/133889 blocks (5.7%), 0 events -2026-02-04T18:55:09.583367Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7580/133889 blocks (5.7%), 0 events -2026-02-04T18:55:09.789631Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7590/133889 blocks (5.7%), 0 events -2026-02-04T18:55:10.002228Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7600/133889 blocks (5.7%), 0 events -2026-02-04T18:55:10.243801Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7610/133889 blocks (5.7%), 0 events -2026-02-04T18:55:10.484430Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7620/133889 blocks (5.7%), 0 events -2026-02-04T18:55:10.603134Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7630/133889 blocks (5.7%), 0 events -2026-02-04T18:55:10.813445Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7640/133889 blocks (5.7%), 0 events -2026-02-04T18:55:11.004029Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7650/133889 blocks (5.7%), 0 events -2026-02-04T18:55:11.247792Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7660/133889 blocks (5.7%), 0 events -2026-02-04T18:55:11.367818Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7670/133889 blocks (5.7%), 0 events -2026-02-04T18:55:11.582486Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7680/133889 blocks (5.7%), 0 events -2026-02-04T18:55:11.784209Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7690/133889 blocks (5.7%), 0 events -2026-02-04T18:55:12.045916Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7700/133889 blocks (5.8%), 0 events -2026-02-04T18:55:12.198062Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7710/133889 blocks (5.8%), 0 events -2026-02-04T18:55:12.399367Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7720/133889 blocks (5.8%), 0 events -2026-02-04T18:55:12.574521Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7730/133889 blocks (5.8%), 0 events -2026-02-04T18:55:12.869340Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7740/133889 blocks (5.8%), 0 events -2026-02-04T18:55:13.066612Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7750/133889 blocks (5.8%), 0 events -2026-02-04T18:55:13.184257Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7760/133889 blocks (5.8%), 0 events -2026-02-04T18:55:13.440403Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7770/133889 blocks (5.8%), 0 events -2026-02-04T18:55:13.626565Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7780/133889 blocks (5.8%), 0 events -2026-02-04T18:55:13.796541Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7790/133889 blocks (5.8%), 0 events -2026-02-04T18:55:13.973190Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7800/133889 blocks (5.8%), 0 events -2026-02-04T18:55:14.206053Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7810/133889 blocks (5.8%), 0 events -2026-02-04T18:55:14.449421Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7820/133889 blocks (5.8%), 0 events -2026-02-04T18:55:14.671550Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7830/133889 blocks (5.8%), 0 events -2026-02-04T18:55:14.823017Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7840/133889 blocks (5.9%), 0 events -2026-02-04T18:55:15.044009Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7850/133889 blocks (5.9%), 0 events -2026-02-04T18:55:15.253757Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7860/133889 blocks (5.9%), 0 events -2026-02-04T18:55:15.375457Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7870/133889 blocks (5.9%), 0 events -2026-02-04T18:55:15.581216Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7880/133889 blocks (5.9%), 0 events -2026-02-04T18:55:15.777748Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7890/133889 blocks (5.9%), 0 events -2026-02-04T18:55:16.052636Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7900/133889 blocks (5.9%), 0 events -2026-02-04T18:55:16.244726Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7910/133889 blocks (5.9%), 0 events -2026-02-04T18:55:16.389551Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7920/133889 blocks (5.9%), 0 events -2026-02-04T18:55:16.592365Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7930/133889 blocks (5.9%), 0 events -2026-02-04T18:55:16.860117Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7940/133889 blocks (5.9%), 0 events -2026-02-04T18:55:16.996172Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7950/133889 blocks (5.9%), 0 events -2026-02-04T18:55:17.292109Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7960/133889 blocks (5.9%), 0 events -2026-02-04T18:55:17.423389Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7970/133889 blocks (6.0%), 0 events -2026-02-04T18:55:17.606675Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7980/133889 blocks (6.0%), 0 events -2026-02-04T18:55:17.859706Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 7990/133889 blocks (6.0%), 0 events -2026-02-04T18:55:17.974066Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8000/133889 blocks (6.0%), 0 events -2026-02-04T18:55:18.310073Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8010/133889 blocks (6.0%), 0 events -2026-02-04T18:55:18.406140Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8020/133889 blocks (6.0%), 0 events -2026-02-04T18:55:18.658384Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8030/133889 blocks (6.0%), 0 events -2026-02-04T18:55:18.869839Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8040/133889 blocks (6.0%), 0 events -2026-02-04T18:55:18.968930Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8050/133889 blocks (6.0%), 0 events -2026-02-04T18:55:19.181092Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8060/133889 blocks (6.0%), 0 events -2026-02-04T18:55:19.444118Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8070/133889 blocks (6.0%), 0 events -2026-02-04T18:55:19.636422Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8080/133889 blocks (6.0%), 0 events -2026-02-04T18:55:19.881079Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8090/133889 blocks (6.0%), 0 events -2026-02-04T18:55:20.041429Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8100/133889 blocks (6.0%), 0 events -2026-02-04T18:55:20.251624Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8110/133889 blocks (6.1%), 0 events -2026-02-04T18:55:20.452947Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8120/133889 blocks (6.1%), 0 events -2026-02-04T18:55:20.641737Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8130/133889 blocks (6.1%), 0 events -2026-02-04T18:55:20.813213Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8140/133889 blocks (6.1%), 0 events -2026-02-04T18:55:21.031423Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8150/133889 blocks (6.1%), 0 events -2026-02-04T18:55:21.179883Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8160/133889 blocks (6.1%), 0 events -2026-02-04T18:55:21.453472Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8170/133889 blocks (6.1%), 0 events -2026-02-04T18:55:21.582897Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8180/133889 blocks (6.1%), 0 events -2026-02-04T18:55:21.834923Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8190/133889 blocks (6.1%), 0 events -2026-02-04T18:55:22.030010Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8200/133889 blocks (6.1%), 0 events -2026-02-04T18:55:22.220812Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8210/133889 blocks (6.1%), 0 events -2026-02-04T18:55:22.408505Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8220/133889 blocks (6.1%), 0 events -2026-02-04T18:55:22.605112Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8230/133889 blocks (6.1%), 0 events -2026-02-04T18:55:22.795421Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8240/133889 blocks (6.2%), 0 events -2026-02-04T18:55:23.064907Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8250/133889 blocks (6.2%), 0 events -2026-02-04T18:55:23.213300Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8260/133889 blocks (6.2%), 0 events -2026-02-04T18:55:23.420456Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8270/133889 blocks (6.2%), 0 events -2026-02-04T18:55:23.584561Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8280/133889 blocks (6.2%), 0 events -2026-02-04T18:55:23.796594Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8290/133889 blocks (6.2%), 0 events -2026-02-04T18:55:24.076322Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8300/133889 blocks (6.2%), 0 events -2026-02-04T18:55:24.262889Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8310/133889 blocks (6.2%), 0 events -2026-02-04T18:55:24.454319Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8320/133889 blocks (6.2%), 0 events -2026-02-04T18:55:24.631771Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8330/133889 blocks (6.2%), 0 events -2026-02-04T18:55:24.793627Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8340/133889 blocks (6.2%), 0 events -2026-02-04T18:55:24.980996Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8350/133889 blocks (6.2%), 0 events -2026-02-04T18:55:25.179015Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8360/133889 blocks (6.2%), 0 events -2026-02-04T18:55:25.415645Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8370/133889 blocks (6.3%), 0 events -2026-02-04T18:55:25.685695Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8380/133889 blocks (6.3%), 0 events -2026-02-04T18:55:25.798537Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8390/133889 blocks (6.3%), 0 events -2026-02-04T18:55:26.029809Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8400/133889 blocks (6.3%), 0 events -2026-02-04T18:55:26.211939Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8410/133889 blocks (6.3%), 0 events -2026-02-04T18:55:26.396276Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8420/133889 blocks (6.3%), 0 events -2026-02-04T18:55:26.696437Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8430/133889 blocks (6.3%), 0 events -2026-02-04T18:55:26.771471Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8440/133889 blocks (6.3%), 0 events -2026-02-04T18:55:27.056102Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8450/133889 blocks (6.3%), 0 events -2026-02-04T18:55:27.507441Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8460/133889 blocks (6.3%), 0 events -2026-02-04T18:55:27.555005Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8470/133889 blocks (6.3%), 0 events -2026-02-04T18:55:27.594057Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8480/133889 blocks (6.3%), 0 events -2026-02-04T18:55:27.849572Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8490/133889 blocks (6.3%), 0 events -2026-02-04T18:55:28.007663Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8500/133889 blocks (6.3%), 0 events -2026-02-04T18:55:28.304326Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8510/133889 blocks (6.4%), 0 events -2026-02-04T18:55:28.376849Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8520/133889 blocks (6.4%), 0 events -2026-02-04T18:55:28.648167Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8530/133889 blocks (6.4%), 0 events -2026-02-04T18:55:28.847086Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8540/133889 blocks (6.4%), 0 events -2026-02-04T18:55:29.010418Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8550/133889 blocks (6.4%), 0 events -2026-02-04T18:55:29.317598Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8560/133889 blocks (6.4%), 0 events -2026-02-04T18:55:29.436825Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8570/133889 blocks (6.4%), 0 events -2026-02-04T18:55:29.633624Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8580/133889 blocks (6.4%), 0 events -2026-02-04T18:55:29.876696Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8590/133889 blocks (6.4%), 0 events -2026-02-04T18:55:30.001782Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8600/133889 blocks (6.4%), 0 events -2026-02-04T18:55:30.248037Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8610/133889 blocks (6.4%), 0 events -2026-02-04T18:55:30.405405Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8620/133889 blocks (6.4%), 0 events -2026-02-04T18:55:30.654112Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8630/133889 blocks (6.4%), 0 events -2026-02-04T18:55:30.892697Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8640/133889 blocks (6.5%), 0 events -2026-02-04T18:55:31.022005Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8650/133889 blocks (6.5%), 0 events -2026-02-04T18:55:31.219927Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8660/133889 blocks (6.5%), 0 events -2026-02-04T18:55:31.451012Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8670/133889 blocks (6.5%), 0 events -2026-02-04T18:55:31.581106Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8680/133889 blocks (6.5%), 0 events -2026-02-04T18:55:31.939654Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8690/133889 blocks (6.5%), 0 events -2026-02-04T18:55:31.981328Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8700/133889 blocks (6.5%), 0 events -2026-02-04T18:55:32.270974Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8710/133889 blocks (6.5%), 0 events -2026-02-04T18:55:32.363829Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8720/133889 blocks (6.5%), 0 events -2026-02-04T18:55:32.638128Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8730/133889 blocks (6.5%), 0 events -2026-02-04T18:55:32.833524Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8740/133889 blocks (6.5%), 0 events -2026-02-04T18:55:33.025646Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8750/133889 blocks (6.5%), 0 events -2026-02-04T18:55:33.266013Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8760/133889 blocks (6.5%), 0 events -2026-02-04T18:55:33.391321Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8770/133889 blocks (6.5%), 0 events -2026-02-04T18:55:33.608546Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8780/133889 blocks (6.6%), 0 events -2026-02-04T18:55:33.819369Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8790/133889 blocks (6.6%), 0 events -2026-02-04T18:55:34.090600Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8800/133889 blocks (6.6%), 0 events -2026-02-04T18:55:34.232997Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8810/133889 blocks (6.6%), 0 events -2026-02-04T18:55:34.401360Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8820/133889 blocks (6.6%), 0 events -2026-02-04T18:55:34.608766Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8830/133889 blocks (6.6%), 0 events -2026-02-04T18:55:34.817835Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8840/133889 blocks (6.6%), 0 events -2026-02-04T18:55:35.129546Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8850/133889 blocks (6.6%), 0 events -2026-02-04T18:55:35.168904Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8860/133889 blocks (6.6%), 0 events -2026-02-04T18:55:35.414533Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8870/133889 blocks (6.6%), 0 events -2026-02-04T18:55:35.648416Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8880/133889 blocks (6.6%), 0 events -2026-02-04T18:55:35.818434Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8890/133889 blocks (6.6%), 0 events -2026-02-04T18:55:35.991914Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8900/133889 blocks (6.6%), 0 events -2026-02-04T18:55:36.223156Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8910/133889 blocks (6.7%), 0 events -2026-02-04T18:55:36.447383Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8920/133889 blocks (6.7%), 0 events -2026-02-04T18:55:36.657535Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8930/133889 blocks (6.7%), 0 events -2026-02-04T18:55:36.840957Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8940/133889 blocks (6.7%), 0 events -2026-02-04T18:55:36.972847Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8950/133889 blocks (6.7%), 0 events -2026-02-04T18:55:37.214866Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8960/133889 blocks (6.7%), 0 events -2026-02-04T18:55:37.423836Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8970/133889 blocks (6.7%), 0 events -2026-02-04T18:55:37.747053Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8980/133889 blocks (6.7%), 0 events -2026-02-04T18:55:37.798005Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 8990/133889 blocks (6.7%), 0 events -2026-02-04T18:55:38.045386Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9000/133889 blocks (6.7%), 0 events -2026-02-04T18:55:38.261522Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9010/133889 blocks (6.7%), 0 events -2026-02-04T18:55:38.436508Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9020/133889 blocks (6.7%), 0 events -2026-02-04T18:55:38.574785Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9030/133889 blocks (6.7%), 0 events -2026-02-04T18:55:38.791967Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9040/133889 blocks (6.8%), 0 events -2026-02-04T18:55:39.040920Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9050/133889 blocks (6.8%), 0 events -2026-02-04T18:55:39.316405Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9060/133889 blocks (6.8%), 0 events -2026-02-04T18:55:39.369530Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9070/133889 blocks (6.8%), 0 events -2026-02-04T18:55:39.615144Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9080/133889 blocks (6.8%), 0 events -2026-02-04T18:55:39.837972Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9090/133889 blocks (6.8%), 0 events -2026-02-04T18:55:40.032427Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9100/133889 blocks (6.8%), 0 events -2026-02-04T18:55:40.190859Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9110/133889 blocks (6.8%), 0 events -2026-02-04T18:55:40.457829Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9120/133889 blocks (6.8%), 0 events -2026-02-04T18:55:40.573566Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9130/133889 blocks (6.8%), 0 events -2026-02-04T18:55:40.852070Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9140/133889 blocks (6.8%), 0 events -2026-02-04T18:55:40.983392Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9150/133889 blocks (6.8%), 0 events -2026-02-04T18:55:41.265675Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9160/133889 blocks (6.8%), 0 events -2026-02-04T18:55:41.443591Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9170/133889 blocks (6.8%), 0 events -2026-02-04T18:55:41.605919Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9180/133889 blocks (6.9%), 0 events -2026-02-04T18:55:41.934272Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9190/133889 blocks (6.9%), 0 events -2026-02-04T18:55:41.978121Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9200/133889 blocks (6.9%), 0 events -2026-02-04T18:55:42.207365Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9210/133889 blocks (6.9%), 0 events -2026-02-04T18:55:42.458739Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9220/133889 blocks (6.9%), 0 events -2026-02-04T18:55:42.621439Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9230/133889 blocks (6.9%), 0 events -2026-02-04T18:55:42.851256Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9240/133889 blocks (6.9%), 0 events -2026-02-04T18:55:43.020469Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9250/133889 blocks (6.9%), 0 events -2026-02-04T18:55:43.198241Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9260/133889 blocks (6.9%), 0 events -2026-02-04T18:55:43.512518Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9270/133889 blocks (6.9%), 0 events -2026-02-04T18:55:43.641543Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9280/133889 blocks (6.9%), 0 events -2026-02-04T18:55:43.782643Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9290/133889 blocks (6.9%), 0 events -2026-02-04T18:55:44.063060Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9300/133889 blocks (6.9%), 0 events -2026-02-04T18:55:44.233230Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9310/133889 blocks (7.0%), 0 events -2026-02-04T18:55:44.520613Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9320/133889 blocks (7.0%), 0 events -2026-02-04T18:55:44.556494Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9330/133889 blocks (7.0%), 0 events -2026-02-04T18:55:44.820699Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9340/133889 blocks (7.0%), 0 events -2026-02-04T18:55:45.079985Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9350/133889 blocks (7.0%), 0 events -2026-02-04T18:55:45.266173Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9360/133889 blocks (7.0%), 0 events -2026-02-04T18:55:45.418765Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9370/133889 blocks (7.0%), 0 events -2026-02-04T18:55:45.624352Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9380/133889 blocks (7.0%), 0 events -2026-02-04T18:55:45.821696Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9390/133889 blocks (7.0%), 0 events -2026-02-04T18:55:46.000247Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9400/133889 blocks (7.0%), 0 events -2026-02-04T18:55:46.250054Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9410/133889 blocks (7.0%), 0 events -2026-02-04T18:55:46.429780Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9420/133889 blocks (7.0%), 0 events -2026-02-04T18:55:46.655094Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9430/133889 blocks (7.0%), 0 events -2026-02-04T18:55:46.809116Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9440/133889 blocks (7.0%), 0 events -2026-02-04T18:55:47.141033Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9450/133889 blocks (7.1%), 0 events -2026-02-04T18:55:47.178815Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9460/133889 blocks (7.1%), 0 events -2026-02-04T18:55:47.393898Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9470/133889 blocks (7.1%), 0 events -2026-02-04T18:55:47.699686Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9480/133889 blocks (7.1%), 0 events -2026-02-04T18:55:47.823045Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9490/133889 blocks (7.1%), 0 events -2026-02-04T18:55:48.027031Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9500/133889 blocks (7.1%), 0 events -2026-02-04T18:55:48.235683Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9510/133889 blocks (7.1%), 0 events -2026-02-04T18:55:48.429995Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9520/133889 blocks (7.1%), 0 events -2026-02-04T18:55:48.714153Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9530/133889 blocks (7.1%), 0 events -2026-02-04T18:55:48.787840Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9540/133889 blocks (7.1%), 0 events -2026-02-04T18:55:48.969578Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9550/133889 blocks (7.1%), 0 events -2026-02-04T18:55:49.274531Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9560/133889 blocks (7.1%), 0 events -2026-02-04T18:55:49.448226Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9570/133889 blocks (7.1%), 0 events -2026-02-04T18:55:49.621027Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9580/133889 blocks (7.2%), 0 events -2026-02-04T18:55:49.808514Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9590/133889 blocks (7.2%), 0 events -2026-02-04T18:55:49.994297Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9600/133889 blocks (7.2%), 0 events -2026-02-04T18:55:50.180561Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9610/133889 blocks (7.2%), 0 events -2026-02-04T18:55:50.430715Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9620/133889 blocks (7.2%), 0 events -2026-02-04T18:55:50.617840Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9630/133889 blocks (7.2%), 0 events -2026-02-04T18:55:50.846112Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9640/133889 blocks (7.2%), 0 events -2026-02-04T18:55:51.037930Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9650/133889 blocks (7.2%), 0 events -2026-02-04T18:55:51.240870Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9660/133889 blocks (7.2%), 0 events -2026-02-04T18:55:51.386275Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9670/133889 blocks (7.2%), 0 events -2026-02-04T18:55:51.574941Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9680/133889 blocks (7.2%), 0 events -2026-02-04T18:55:51.909864Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9690/133889 blocks (7.2%), 0 events -2026-02-04T18:55:52.013452Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9700/133889 blocks (7.2%), 0 events -2026-02-04T18:55:52.193804Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9710/133889 blocks (7.3%), 0 events -2026-02-04T18:55:52.416205Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9720/133889 blocks (7.3%), 0 events -2026-02-04T18:55:52.575145Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9730/133889 blocks (7.3%), 0 events -2026-02-04T18:55:52.798455Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9740/133889 blocks (7.3%), 0 events -2026-02-04T18:55:53.049558Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9750/133889 blocks (7.3%), 0 events -2026-02-04T18:55:53.315675Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9760/133889 blocks (7.3%), 0 events -2026-02-04T18:55:53.464552Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9770/133889 blocks (7.3%), 0 events -2026-02-04T18:55:53.610217Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9780/133889 blocks (7.3%), 0 events -2026-02-04T18:55:53.784541Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9790/133889 blocks (7.3%), 0 events -2026-02-04T18:55:54.017722Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9800/133889 blocks (7.3%), 0 events -2026-02-04T18:55:54.241563Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9810/133889 blocks (7.3%), 0 events -2026-02-04T18:55:54.518032Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9820/133889 blocks (7.3%), 0 events -2026-02-04T18:55:54.625803Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9830/133889 blocks (7.3%), 0 events -2026-02-04T18:55:54.791467Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9840/133889 blocks (7.3%), 0 events -2026-02-04T18:55:55.053066Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9850/133889 blocks (7.4%), 0 events -2026-02-04T18:55:55.168455Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9860/133889 blocks (7.4%), 0 events -2026-02-04T18:55:55.409659Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9870/133889 blocks (7.4%), 0 events -2026-02-04T18:55:55.609531Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9880/133889 blocks (7.4%), 0 events -2026-02-04T18:55:55.798598Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9890/133889 blocks (7.4%), 0 events -2026-02-04T18:55:56.053550Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9900/133889 blocks (7.4%), 0 events -2026-02-04T18:55:56.246722Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9910/133889 blocks (7.4%), 0 events -2026-02-04T18:55:56.410584Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9920/133889 blocks (7.4%), 0 events -2026-02-04T18:55:56.613634Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9930/133889 blocks (7.4%), 0 events -2026-02-04T18:55:56.808401Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9940/133889 blocks (7.4%), 0 events -2026-02-04T18:55:56.989819Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9950/133889 blocks (7.4%), 0 events -2026-02-04T18:55:57.238514Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9960/133889 blocks (7.4%), 0 events -2026-02-04T18:55:57.456595Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9970/133889 blocks (7.4%), 0 events -2026-02-04T18:55:57.664435Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9980/133889 blocks (7.5%), 0 events -2026-02-04T18:55:57.829943Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 9990/133889 blocks (7.5%), 0 events -2026-02-04T18:55:58.054469Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10000/133889 blocks (7.5%), 0 events -2026-02-04T18:55:58.235739Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10010/133889 blocks (7.5%), 0 events -2026-02-04T18:55:58.396711Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10020/133889 blocks (7.5%), 0 events -2026-02-04T18:55:58.585768Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10030/133889 blocks (7.5%), 0 events -2026-02-04T18:55:58.854862Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10040/133889 blocks (7.5%), 0 events -2026-02-04T18:55:58.977718Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10050/133889 blocks (7.5%), 0 events -2026-02-04T18:55:59.255133Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10060/133889 blocks (7.5%), 0 events -2026-02-04T18:55:59.376293Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10070/133889 blocks (7.5%), 0 events -2026-02-04T18:55:59.783581Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10080/133889 blocks (7.5%), 0 events -2026-02-04T18:55:59.822448Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10090/133889 blocks (7.5%), 0 events -2026-02-04T18:55:59.976401Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10100/133889 blocks (7.5%), 0 events -2026-02-04T18:56:00.440954Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10110/133889 blocks (7.6%), 0 events -2026-02-04T18:56:00.480390Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10120/133889 blocks (7.6%), 0 events -2026-02-04T18:56:00.655850Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10130/133889 blocks (7.6%), 0 events -2026-02-04T18:56:00.825190Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10140/133889 blocks (7.6%), 0 events -2026-02-04T18:56:01.048619Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10150/133889 blocks (7.6%), 0 events -2026-02-04T18:56:01.298788Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10160/133889 blocks (7.6%), 0 events -2026-02-04T18:56:01.468660Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10170/133889 blocks (7.6%), 0 events -2026-02-04T18:56:01.577566Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10180/133889 blocks (7.6%), 0 events -2026-02-04T18:56:01.857093Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10190/133889 blocks (7.6%), 0 events -2026-02-04T18:56:02.000958Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10200/133889 blocks (7.6%), 0 events -2026-02-04T18:56:02.229827Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10210/133889 blocks (7.6%), 0 events -2026-02-04T18:56:02.438781Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10220/133889 blocks (7.6%), 0 events -2026-02-04T18:56:02.656099Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10230/133889 blocks (7.6%), 0 events -2026-02-04T18:56:02.905703Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10240/133889 blocks (7.6%), 0 events -2026-02-04T18:56:02.970857Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10250/133889 blocks (7.7%), 0 events -2026-02-04T18:56:03.183025Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10260/133889 blocks (7.7%), 0 events -2026-02-04T18:56:03.432041Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10270/133889 blocks (7.7%), 0 events -2026-02-04T18:56:03.619941Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10280/133889 blocks (7.7%), 0 events -2026-02-04T18:56:03.957596Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10290/133889 blocks (7.7%), 0 events -2026-02-04T18:56:03.998961Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10300/133889 blocks (7.7%), 0 events -2026-02-04T18:56:04.187683Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10310/133889 blocks (7.7%), 0 events -2026-02-04T18:56:04.475791Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10320/133889 blocks (7.7%), 0 events -2026-02-04T18:56:04.588915Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10330/133889 blocks (7.7%), 0 events -2026-02-04T18:56:04.873721Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10340/133889 blocks (7.7%), 0 events -2026-02-04T18:56:05.062220Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10350/133889 blocks (7.7%), 0 events -2026-02-04T18:56:05.268979Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10360/133889 blocks (7.7%), 0 events -2026-02-04T18:56:05.493465Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10370/133889 blocks (7.7%), 0 events -2026-02-04T18:56:05.604982Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10380/133889 blocks (7.8%), 0 events -2026-02-04T18:56:05.792416Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10390/133889 blocks (7.8%), 0 events -2026-02-04T18:56:06.048178Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10400/133889 blocks (7.8%), 0 events -2026-02-04T18:56:06.172010Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10410/133889 blocks (7.8%), 0 events -2026-02-04T18:56:06.393985Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10420/133889 blocks (7.8%), 0 events -2026-02-04T18:56:06.643231Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10430/133889 blocks (7.8%), 0 events -2026-02-04T18:56:06.832741Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10440/133889 blocks (7.8%), 0 events -2026-02-04T18:56:07.064839Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10450/133889 blocks (7.8%), 0 events -2026-02-04T18:56:07.239943Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10460/133889 blocks (7.8%), 0 events -2026-02-04T18:56:07.443157Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10470/133889 blocks (7.8%), 0 events -2026-02-04T18:56:07.621340Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10480/133889 blocks (7.8%), 0 events -2026-02-04T18:56:07.845893Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10490/133889 blocks (7.8%), 0 events -2026-02-04T18:56:08.147571Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10500/133889 blocks (7.8%), 0 events -2026-02-04T18:56:08.196256Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10510/133889 blocks (7.8%), 0 events -2026-02-04T18:56:08.409737Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10520/133889 blocks (7.9%), 0 events -2026-02-04T18:56:08.638116Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10530/133889 blocks (7.9%), 0 events -2026-02-04T18:56:08.843552Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10540/133889 blocks (7.9%), 0 events -2026-02-04T18:56:09.018120Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10550/133889 blocks (7.9%), 0 events -2026-02-04T18:56:09.201577Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10560/133889 blocks (7.9%), 0 events -2026-02-04T18:56:09.424244Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10570/133889 blocks (7.9%), 0 events -2026-02-04T18:56:09.716712Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10580/133889 blocks (7.9%), 0 events -2026-02-04T18:56:09.791495Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10590/133889 blocks (7.9%), 0 events -2026-02-04T18:56:10.065659Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10600/133889 blocks (7.9%), 0 events -2026-02-04T18:56:10.244936Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10610/133889 blocks (7.9%), 0 events -2026-02-04T18:56:10.425196Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10620/133889 blocks (7.9%), 0 events -2026-02-04T18:56:10.577723Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10630/133889 blocks (7.9%), 0 events -2026-02-04T18:56:10.862380Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10640/133889 blocks (7.9%), 0 events -2026-02-04T18:56:10.987608Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10650/133889 blocks (8.0%), 0 events -2026-02-04T18:56:11.169048Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10660/133889 blocks (8.0%), 0 events -2026-02-04T18:56:11.465829Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10670/133889 blocks (8.0%), 0 events -2026-02-04T18:56:11.646938Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10680/133889 blocks (8.0%), 0 events -2026-02-04T18:56:11.829644Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10690/133889 blocks (8.0%), 0 events -2026-02-04T18:56:12.026960Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10700/133889 blocks (8.0%), 0 events -2026-02-04T18:56:12.308291Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10710/133889 blocks (8.0%), 0 events -2026-02-04T18:56:12.398829Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10720/133889 blocks (8.0%), 0 events -2026-02-04T18:56:12.661157Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10730/133889 blocks (8.0%), 0 events -2026-02-04T18:56:12.866825Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10740/133889 blocks (8.0%), 0 events -2026-02-04T18:56:13.022434Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10750/133889 blocks (8.0%), 0 events -2026-02-04T18:56:13.192851Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10760/133889 blocks (8.0%), 0 events -2026-02-04T18:56:13.410165Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10770/133889 blocks (8.0%), 0 events -2026-02-04T18:56:13.670884Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10780/133889 blocks (8.1%), 0 events -2026-02-04T18:56:13.778233Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10790/133889 blocks (8.1%), 0 events -2026-02-04T18:56:14.013961Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10800/133889 blocks (8.1%), 0 events -2026-02-04T18:56:14.208592Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10810/133889 blocks (8.1%), 0 events -2026-02-04T18:56:14.444653Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10820/133889 blocks (8.1%), 0 events -2026-02-04T18:56:14.588226Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10830/133889 blocks (8.1%), 0 events -2026-02-04T18:56:14.769717Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10840/133889 blocks (8.1%), 0 events -2026-02-04T18:56:14.986448Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10850/133889 blocks (8.1%), 0 events -2026-02-04T18:56:15.188616Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10860/133889 blocks (8.1%), 0 events -2026-02-04T18:56:15.498522Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10870/133889 blocks (8.1%), 0 events -2026-02-04T18:56:15.608694Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10880/133889 blocks (8.1%), 0 events -2026-02-04T18:56:15.781301Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10890/133889 blocks (8.1%), 0 events -2026-02-04T18:56:16.017962Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10900/133889 blocks (8.1%), 0 events -2026-02-04T18:56:16.191146Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10910/133889 blocks (8.1%), 0 events -2026-02-04T18:56:16.392304Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10920/133889 blocks (8.2%), 0 events -2026-02-04T18:56:16.651454Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10930/133889 blocks (8.2%), 0 events -2026-02-04T18:56:16.832918Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10940/133889 blocks (8.2%), 0 events -2026-02-04T18:56:17.056651Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10950/133889 blocks (8.2%), 0 events -2026-02-04T18:56:17.241207Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10960/133889 blocks (8.2%), 0 events -2026-02-04T18:56:17.374696Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10970/133889 blocks (8.2%), 0 events -2026-02-04T18:56:17.626223Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10980/133889 blocks (8.2%), 0 events -2026-02-04T18:56:17.817573Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 10990/133889 blocks (8.2%), 0 events -2026-02-04T18:56:18.110323Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11000/133889 blocks (8.2%), 0 events -2026-02-04T18:56:18.182166Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11010/133889 blocks (8.2%), 0 events -2026-02-04T18:56:18.404039Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11020/133889 blocks (8.2%), 0 events -2026-02-04T18:56:18.632844Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11030/133889 blocks (8.2%), 0 events -2026-02-04T18:56:18.815387Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11040/133889 blocks (8.2%), 0 events -2026-02-04T18:56:18.974461Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11050/133889 blocks (8.3%), 0 events -2026-02-04T18:56:19.228042Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11060/133889 blocks (8.3%), 0 events -2026-02-04T18:56:19.375004Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11070/133889 blocks (8.3%), 0 events -2026-02-04T18:56:19.680439Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11080/133889 blocks (8.3%), 0 events -2026-02-04T18:56:19.793503Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11090/133889 blocks (8.3%), 0 events -2026-02-04T18:56:19.971177Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11100/133889 blocks (8.3%), 0 events -2026-02-04T18:56:20.268381Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11110/133889 blocks (8.3%), 0 events -2026-02-04T18:56:20.418163Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11120/133889 blocks (8.3%), 0 events -2026-02-04T18:56:20.566420Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11130/133889 blocks (8.3%), 0 events -2026-02-04T18:56:20.780242Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11140/133889 blocks (8.3%), 0 events -2026-02-04T18:56:21.050739Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11150/133889 blocks (8.3%), 0 events -2026-02-04T18:56:21.256016Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11160/133889 blocks (8.3%), 0 events -2026-02-04T18:56:21.391943Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11170/133889 blocks (8.3%), 0 events -2026-02-04T18:56:21.607922Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11180/133889 blocks (8.3%), 0 events -2026-02-04T18:56:21.818806Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11190/133889 blocks (8.4%), 0 events -2026-02-04T18:56:22.047624Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11200/133889 blocks (8.4%), 0 events -2026-02-04T18:56:22.171662Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11210/133889 blocks (8.4%), 0 events -2026-02-04T18:56:22.418552Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11220/133889 blocks (8.4%), 0 events -2026-02-04T18:56:22.635503Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11230/133889 blocks (8.4%), 0 events -2026-02-04T18:56:22.843132Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11240/133889 blocks (8.4%), 0 events -2026-02-04T18:56:22.966408Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11250/133889 blocks (8.4%), 0 events -2026-02-04T18:56:23.317668Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11260/133889 blocks (8.4%), 0 events -2026-02-04T18:56:23.429328Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11270/133889 blocks (8.4%), 0 events -2026-02-04T18:56:23.660732Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11280/133889 blocks (8.4%), 0 events -2026-02-04T18:56:23.881857Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11290/133889 blocks (8.4%), 0 events -2026-02-04T18:56:24.040917Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11300/133889 blocks (8.4%), 0 events -2026-02-04T18:56:24.262005Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11310/133889 blocks (8.4%), 0 events -2026-02-04T18:56:24.398320Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11320/133889 blocks (8.5%), 0 events -2026-02-04T18:56:24.634691Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11330/133889 blocks (8.5%), 0 events -2026-02-04T18:56:24.921965Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11340/133889 blocks (8.5%), 0 events -2026-02-04T18:56:24.965537Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11350/133889 blocks (8.5%), 0 events -2026-02-04T18:56:25.175032Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11360/133889 blocks (8.5%), 0 events -2026-02-04T18:56:25.444823Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11370/133889 blocks (8.5%), 0 events -2026-02-04T18:56:25.661055Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11380/133889 blocks (8.5%), 0 events -2026-02-04T18:56:25.787086Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11390/133889 blocks (8.5%), 0 events -2026-02-04T18:56:26.036647Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11400/133889 blocks (8.5%), 0 events -2026-02-04T18:56:26.185124Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11410/133889 blocks (8.5%), 0 events -2026-02-04T18:56:26.496552Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11420/133889 blocks (8.5%), 0 events -2026-02-04T18:56:26.589597Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11430/133889 blocks (8.5%), 0 events -2026-02-04T18:56:26.831245Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11440/133889 blocks (8.5%), 0 events -2026-02-04T18:56:27.059354Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11450/133889 blocks (8.6%), 0 events -2026-02-04T18:56:27.209379Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11460/133889 blocks (8.6%), 0 events -2026-02-04T18:56:27.369632Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11470/133889 blocks (8.6%), 0 events -2026-02-04T18:56:27.605481Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11480/133889 blocks (8.6%), 0 events -2026-02-04T18:56:27.857778Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11490/133889 blocks (8.6%), 0 events -2026-02-04T18:56:28.035585Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11500/133889 blocks (8.6%), 0 events -2026-02-04T18:56:28.249047Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11510/133889 blocks (8.6%), 0 events -2026-02-04T18:56:28.431318Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11520/133889 blocks (8.6%), 0 events -2026-02-04T18:56:28.603714Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11530/133889 blocks (8.6%), 0 events -2026-02-04T18:56:28.803021Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11540/133889 blocks (8.6%), 0 events -2026-02-04T18:56:28.980652Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11550/133889 blocks (8.6%), 0 events -2026-02-04T18:56:29.174175Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11560/133889 blocks (8.6%), 0 events -2026-02-04T18:56:29.413276Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11570/133889 blocks (8.6%), 0 events -2026-02-04T18:56:29.644893Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11580/133889 blocks (8.6%), 0 events -2026-02-04T18:56:29.833861Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11590/133889 blocks (8.7%), 0 events -2026-02-04T18:56:30.035770Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11600/133889 blocks (8.7%), 0 events -2026-02-04T18:56:30.256678Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11610/133889 blocks (8.7%), 0 events -2026-02-04T18:56:30.441450Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11620/133889 blocks (8.7%), 0 events -2026-02-04T18:56:30.690751Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11630/133889 blocks (8.7%), 0 events -2026-02-04T18:56:30.797074Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11640/133889 blocks (8.7%), 0 events -2026-02-04T18:56:31.050023Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11650/133889 blocks (8.7%), 0 events -2026-02-04T18:56:31.218462Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11660/133889 blocks (8.7%), 0 events -2026-02-04T18:56:31.456649Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11670/133889 blocks (8.7%), 0 events -2026-02-04T18:56:31.706037Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11680/133889 blocks (8.7%), 0 events -2026-02-04T18:56:31.856993Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11690/133889 blocks (8.7%), 0 events -2026-02-04T18:56:32.035723Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11700/133889 blocks (8.7%), 0 events -2026-02-04T18:56:32.258335Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11710/133889 blocks (8.7%), 0 events -2026-02-04T18:56:32.367122Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11720/133889 blocks (8.8%), 0 events -2026-02-04T18:56:32.566300Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11730/133889 blocks (8.8%), 0 events -2026-02-04T18:56:32.805204Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11740/133889 blocks (8.8%), 0 events -2026-02-04T18:56:33.020982Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11750/133889 blocks (8.8%), 0 events -2026-02-04T18:56:33.277400Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11760/133889 blocks (8.8%), 0 events -2026-02-04T18:56:33.411805Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11770/133889 blocks (8.8%), 0 events -2026-02-04T18:56:33.610086Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11780/133889 blocks (8.8%), 0 events -2026-02-04T18:56:33.837216Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11790/133889 blocks (8.8%), 0 events -2026-02-04T18:56:33.987580Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11800/133889 blocks (8.8%), 0 events -2026-02-04T18:56:34.327066Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11810/133889 blocks (8.8%), 0 events -2026-02-04T18:56:34.369201Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11820/133889 blocks (8.8%), 0 events -2026-02-04T18:56:34.659310Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11830/133889 blocks (8.8%), 0 events -2026-02-04T18:56:34.884249Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11840/133889 blocks (8.8%), 0 events -2026-02-04T18:56:35.036631Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11850/133889 blocks (8.8%), 0 events -2026-02-04T18:56:35.203421Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11860/133889 blocks (8.9%), 0 events -2026-02-04T18:56:35.444544Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11870/133889 blocks (8.9%), 0 events -2026-02-04T18:56:35.599695Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11880/133889 blocks (8.9%), 0 events -2026-02-04T18:56:35.896974Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11890/133889 blocks (8.9%), 0 events -2026-02-04T18:56:36.003655Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11900/133889 blocks (8.9%), 0 events -2026-02-04T18:56:36.241335Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11910/133889 blocks (8.9%), 0 events -2026-02-04T18:56:36.458547Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11920/133889 blocks (8.9%), 0 events -2026-02-04T18:56:36.661500Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11930/133889 blocks (8.9%), 0 events -2026-02-04T18:56:36.789632Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11940/133889 blocks (8.9%), 0 events -2026-02-04T18:56:37.005561Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11950/133889 blocks (8.9%), 0 events -2026-02-04T18:56:37.227631Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11960/133889 blocks (8.9%), 0 events -2026-02-04T18:56:37.506064Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11970/133889 blocks (8.9%), 0 events -2026-02-04T18:56:37.624081Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11980/133889 blocks (8.9%), 0 events -2026-02-04T18:56:37.862330Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 11990/133889 blocks (9.0%), 0 events -2026-02-04T18:56:38.039191Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12000/133889 blocks (9.0%), 0 events -2026-02-04T18:56:38.234139Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12010/133889 blocks (9.0%), 0 events -2026-02-04T18:56:38.402595Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12020/133889 blocks (9.0%), 0 events -2026-02-04T18:56:38.622995Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12030/133889 blocks (9.0%), 0 events -2026-02-04T18:56:38.829554Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12040/133889 blocks (9.0%), 0 events -2026-02-04T18:56:39.083961Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12050/133889 blocks (9.0%), 0 events -2026-02-04T18:56:39.209918Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12060/133889 blocks (9.0%), 0 events -2026-02-04T18:56:39.415183Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12070/133889 blocks (9.0%), 0 events -2026-02-04T18:56:39.602868Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12080/133889 blocks (9.0%), 0 events -2026-02-04T18:56:39.771789Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12090/133889 blocks (9.0%), 0 events -2026-02-04T18:56:39.987732Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12100/133889 blocks (9.0%), 0 events -2026-02-04T18:56:40.239339Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12110/133889 blocks (9.0%), 0 events -2026-02-04T18:56:40.404528Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12120/133889 blocks (9.1%), 0 events -2026-02-04T18:56:40.649741Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12130/133889 blocks (9.1%), 0 events -2026-02-04T18:56:40.831593Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12140/133889 blocks (9.1%), 0 events -2026-02-04T18:56:40.993602Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12150/133889 blocks (9.1%), 0 events -2026-02-04T18:56:41.177697Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12160/133889 blocks (9.1%), 0 events -2026-02-04T18:56:41.419725Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12170/133889 blocks (9.1%), 0 events -2026-02-04T18:56:41.700600Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12180/133889 blocks (9.1%), 0 events -2026-02-04T18:56:41.801291Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12190/133889 blocks (9.1%), 0 events -2026-02-04T18:56:41.967192Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12200/133889 blocks (9.1%), 0 events -2026-02-04T18:56:42.222942Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12210/133889 blocks (9.1%), 0 events -2026-02-04T18:56:42.443486Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12220/133889 blocks (9.1%), 0 events -2026-02-04T18:56:42.712150Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12230/133889 blocks (9.1%), 0 events -2026-02-04T18:56:42.999604Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12240/133889 blocks (9.1%), 0 events -2026-02-04T18:56:43.038589Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12250/133889 blocks (9.1%), 0 events -2026-02-04T18:56:43.269177Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12260/133889 blocks (9.2%), 0 events -2026-02-04T18:56:43.370302Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12270/133889 blocks (9.2%), 0 events -2026-02-04T18:56:43.622687Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12280/133889 blocks (9.2%), 0 events -2026-02-04T18:56:43.857807Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12290/133889 blocks (9.2%), 0 events -2026-02-04T18:56:43.981401Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12300/133889 blocks (9.2%), 0 events -2026-02-04T18:56:44.291285Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12310/133889 blocks (9.2%), 0 events -2026-02-04T18:56:44.369297Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12320/133889 blocks (9.2%), 0 events -2026-02-04T18:56:44.645873Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12330/133889 blocks (9.2%), 0 events -2026-02-04T18:56:44.844169Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12340/133889 blocks (9.2%), 0 events -2026-02-04T18:56:45.048844Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12350/133889 blocks (9.2%), 0 events -2026-02-04T18:56:45.231202Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12360/133889 blocks (9.2%), 0 events -2026-02-04T18:56:45.379104Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12370/133889 blocks (9.2%), 0 events -2026-02-04T18:56:45.634840Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12380/133889 blocks (9.2%), 0 events -2026-02-04T18:56:45.890586Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12390/133889 blocks (9.3%), 0 events -2026-02-04T18:56:45.991749Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12400/133889 blocks (9.3%), 0 events -2026-02-04T18:56:46.241214Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12410/133889 blocks (9.3%), 0 events -2026-02-04T18:56:46.458118Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12420/133889 blocks (9.3%), 0 events -2026-02-04T18:56:46.576672Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12430/133889 blocks (9.3%), 0 events -2026-02-04T18:56:46.798134Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12440/133889 blocks (9.3%), 0 events -2026-02-04T18:56:47.031394Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12450/133889 blocks (9.3%), 0 events -2026-02-04T18:56:47.222358Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12460/133889 blocks (9.3%), 0 events -2026-02-04T18:56:47.465201Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12470/133889 blocks (9.3%), 0 events -2026-02-04T18:56:47.620458Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12480/133889 blocks (9.3%), 0 events -2026-02-04T18:56:47.829018Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12490/133889 blocks (9.3%), 0 events -2026-02-04T18:56:48.048006Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12500/133889 blocks (9.3%), 0 events -2026-02-04T18:56:48.197315Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12510/133889 blocks (9.3%), 0 events -2026-02-04T18:56:48.480379Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12520/133889 blocks (9.4%), 0 events -2026-02-04T18:56:48.624141Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12530/133889 blocks (9.4%), 0 events -2026-02-04T18:56:48.774910Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12540/133889 blocks (9.4%), 0 events -2026-02-04T18:56:49.043332Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12550/133889 blocks (9.4%), 0 events -2026-02-04T18:56:49.207976Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12560/133889 blocks (9.4%), 0 events -2026-02-04T18:56:49.388076Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12570/133889 blocks (9.4%), 0 events -2026-02-04T18:56:49.638038Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12580/133889 blocks (9.4%), 0 events -2026-02-04T18:56:49.845089Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12590/133889 blocks (9.4%), 0 events -2026-02-04T18:56:50.054434Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12600/133889 blocks (9.4%), 0 events -2026-02-04T18:56:50.231669Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12610/133889 blocks (9.4%), 0 events -2026-02-04T18:56:50.484886Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12620/133889 blocks (9.4%), 0 events -2026-02-04T18:56:50.627438Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12630/133889 blocks (9.4%), 0 events -2026-02-04T18:56:50.824313Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12640/133889 blocks (9.4%), 0 events -2026-02-04T18:56:51.140859Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12650/133889 blocks (9.4%), 0 events -2026-02-04T18:56:51.179333Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12660/133889 blocks (9.5%), 0 events -2026-02-04T18:56:51.406195Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12670/133889 blocks (9.5%), 0 events -2026-02-04T18:56:51.626001Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12680/133889 blocks (9.5%), 0 events -2026-02-04T18:56:51.782086Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12690/133889 blocks (9.5%), 0 events -2026-02-04T18:56:52.000722Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12700/133889 blocks (9.5%), 0 events -2026-02-04T18:56:52.184389Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12710/133889 blocks (9.5%), 0 events -2026-02-04T18:56:52.456848Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12720/133889 blocks (9.5%), 0 events -2026-02-04T18:56:52.673207Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12730/133889 blocks (9.5%), 0 events -2026-02-04T18:56:52.831282Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12740/133889 blocks (9.5%), 0 events -2026-02-04T18:56:53.003686Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12750/133889 blocks (9.5%), 0 events -2026-02-04T18:56:53.230514Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12760/133889 blocks (9.5%), 0 events -2026-02-04T18:56:53.377421Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12770/133889 blocks (9.5%), 0 events -2026-02-04T18:56:53.604953Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12780/133889 blocks (9.5%), 0 events -2026-02-04T18:56:53.836618Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12790/133889 blocks (9.6%), 0 events -2026-02-04T18:56:54.001752Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12800/133889 blocks (9.6%), 0 events -2026-02-04T18:56:54.284405Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12810/133889 blocks (9.6%), 0 events -2026-02-04T18:56:54.455697Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12820/133889 blocks (9.6%), 0 events -2026-02-04T18:56:54.638203Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12830/133889 blocks (9.6%), 0 events -2026-02-04T18:56:54.805441Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12840/133889 blocks (9.6%), 0 events -2026-02-04T18:56:55.028081Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12850/133889 blocks (9.6%), 0 events -2026-02-04T18:56:55.329435Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12860/133889 blocks (9.6%), 0 events -2026-02-04T18:56:55.368125Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12870/133889 blocks (9.6%), 0 events -2026-02-04T18:56:55.596664Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12880/133889 blocks (9.6%), 0 events -2026-02-04T18:56:55.819407Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12890/133889 blocks (9.6%), 0 events -2026-02-04T18:56:56.059189Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12900/133889 blocks (9.6%), 0 events -2026-02-04T18:56:56.184787Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12910/133889 blocks (9.6%), 0 events -2026-02-04T18:56:56.382176Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12920/133889 blocks (9.6%), 0 events -2026-02-04T18:56:56.615885Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12930/133889 blocks (9.7%), 0 events -2026-02-04T18:56:56.901124Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12940/133889 blocks (9.7%), 0 events -2026-02-04T18:56:56.993462Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12950/133889 blocks (9.7%), 0 events -2026-02-04T18:56:57.185357Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12960/133889 blocks (9.7%), 0 events -2026-02-04T18:56:57.424577Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12970/133889 blocks (9.7%), 0 events -2026-02-04T18:56:57.588619Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12980/133889 blocks (9.7%), 0 events -2026-02-04T18:56:57.814316Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 12990/133889 blocks (9.7%), 0 events -2026-02-04T18:56:57.992621Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13000/133889 blocks (9.7%), 0 events -2026-02-04T18:56:58.230830Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13010/133889 blocks (9.7%), 0 events -2026-02-04T18:56:58.472552Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13020/133889 blocks (9.7%), 0 events -2026-02-04T18:56:58.608006Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13030/133889 blocks (9.7%), 0 events -2026-02-04T18:56:58.849474Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13040/133889 blocks (9.7%), 0 events -2026-02-04T18:56:59.000753Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13050/133889 blocks (9.7%), 0 events -2026-02-04T18:56:59.234403Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13060/133889 blocks (9.8%), 0 events -2026-02-04T18:56:59.383765Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13070/133889 blocks (9.8%), 0 events -2026-02-04T18:56:59.653411Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13080/133889 blocks (9.8%), 0 events -2026-02-04T18:56:59.830915Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13090/133889 blocks (9.8%), 0 events -2026-02-04T18:57:00.047980Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13100/133889 blocks (9.8%), 0 events -2026-02-04T18:57:00.197276Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13110/133889 blocks (9.8%), 0 events -2026-02-04T18:57:00.430279Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13120/133889 blocks (9.8%), 0 events -2026-02-04T18:57:00.591885Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13130/133889 blocks (9.8%), 0 events -2026-02-04T18:57:00.769551Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13140/133889 blocks (9.8%), 0 events -2026-02-04T18:57:01.115440Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13150/133889 blocks (9.8%), 0 events -2026-02-04T18:57:01.229635Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13160/133889 blocks (9.8%), 0 events -2026-02-04T18:57:01.440722Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13170/133889 blocks (9.8%), 0 events -2026-02-04T18:57:01.631677Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13180/133889 blocks (9.8%), 0 events -2026-02-04T18:57:01.791580Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13190/133889 blocks (9.9%), 0 events -2026-02-04T18:57:02.110013Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13200/133889 blocks (9.9%), 0 events -2026-02-04T18:57:02.233098Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13210/133889 blocks (9.9%), 0 events -2026-02-04T18:57:02.378811Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13220/133889 blocks (9.9%), 0 events -2026-02-04T18:57:02.668053Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13230/133889 blocks (9.9%), 0 events -2026-02-04T18:57:02.780013Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13240/133889 blocks (9.9%), 0 events -2026-02-04T18:57:02.996431Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13250/133889 blocks (9.9%), 0 events -2026-02-04T18:57:03.194174Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13260/133889 blocks (9.9%), 0 events -2026-02-04T18:57:03.405596Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13270/133889 blocks (9.9%), 0 events -2026-02-04T18:57:03.685046Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13280/133889 blocks (9.9%), 0 events -2026-02-04T18:57:03.766813Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13290/133889 blocks (9.9%), 0 events -2026-02-04T18:57:04.001646Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13300/133889 blocks (9.9%), 0 events -2026-02-04T18:57:04.243195Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13310/133889 blocks (9.9%), 0 events -2026-02-04T18:57:04.415948Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13320/133889 blocks (9.9%), 0 events -2026-02-04T18:57:04.614603Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13330/133889 blocks (10.0%), 0 events -2026-02-04T18:57:04.826029Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13340/133889 blocks (10.0%), 0 events -2026-02-04T18:57:05.060274Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13350/133889 blocks (10.0%), 0 events -2026-02-04T18:57:05.293912Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13360/133889 blocks (10.0%), 0 events -2026-02-04T18:57:05.364575Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13370/133889 blocks (10.0%), 0 events -2026-02-04T18:57:05.589810Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13380/133889 blocks (10.0%), 0 events -2026-02-04T18:57:05.832730Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13390/133889 blocks (10.0%), 0 events -2026-02-04T18:57:06.016974Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13400/133889 blocks (10.0%), 0 events -2026-02-04T18:57:06.335693Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13410/133889 blocks (10.0%), 0 events -2026-02-04T18:57:06.379832Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13420/133889 blocks (10.0%), 0 events -2026-02-04T18:57:06.584537Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13430/133889 blocks (10.0%), 0 events -2026-02-04T18:57:06.867920Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13440/133889 blocks (10.0%), 0 events -2026-02-04T18:57:06.998971Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13450/133889 blocks (10.0%), 0 events -2026-02-04T18:57:07.270217Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13460/133889 blocks (10.1%), 0 events -2026-02-04T18:57:07.416836Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13470/133889 blocks (10.1%), 0 events -2026-02-04T18:57:07.578336Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13480/133889 blocks (10.1%), 0 events -2026-02-04T18:57:07.913392Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13490/133889 blocks (10.1%), 0 events -2026-02-04T18:57:08.050337Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13500/133889 blocks (10.1%), 0 events -2026-02-04T18:57:08.196485Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13510/133889 blocks (10.1%), 0 events -2026-02-04T18:57:08.431499Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13520/133889 blocks (10.1%), 0 events -2026-02-04T18:57:08.589000Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13530/133889 blocks (10.1%), 0 events -2026-02-04T18:57:08.816239Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13540/133889 blocks (10.1%), 0 events -2026-02-04T18:57:09.057839Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13550/133889 blocks (10.1%), 0 events -2026-02-04T18:57:09.205345Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13560/133889 blocks (10.1%), 0 events -2026-02-04T18:57:09.451547Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13570/133889 blocks (10.1%), 0 events -2026-02-04T18:57:09.656979Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13580/133889 blocks (10.1%), 0 events -2026-02-04T18:57:09.818237Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13590/133889 blocks (10.1%), 0 events -2026-02-04T18:57:10.030882Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13600/133889 blocks (10.2%), 0 events -2026-02-04T18:57:10.171838Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13610/133889 blocks (10.2%), 0 events -2026-02-04T18:57:10.517249Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13620/133889 blocks (10.2%), 0 events -2026-02-04T18:57:10.658183Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13630/133889 blocks (10.2%), 0 events -2026-02-04T18:57:10.861918Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13640/133889 blocks (10.2%), 0 events -2026-02-04T18:57:11.055718Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13650/133889 blocks (10.2%), 0 events -2026-02-04T18:57:11.172218Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13660/133889 blocks (10.2%), 0 events -2026-02-04T18:57:11.437578Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13670/133889 blocks (10.2%), 0 events -2026-02-04T18:57:11.609741Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13680/133889 blocks (10.2%), 0 events -2026-02-04T18:57:11.839956Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13690/133889 blocks (10.2%), 0 events -2026-02-04T18:57:12.105313Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13700/133889 blocks (10.2%), 0 events -2026-02-04T18:57:12.239588Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13710/133889 blocks (10.2%), 0 events -2026-02-04T18:57:12.413653Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13720/133889 blocks (10.2%), 0 events -2026-02-04T18:57:12.650549Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13730/133889 blocks (10.3%), 0 events -2026-02-04T18:57:12.782062Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13740/133889 blocks (10.3%), 0 events -2026-02-04T18:57:13.028059Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13750/133889 blocks (10.3%), 0 events -2026-02-04T18:57:13.271350Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13760/133889 blocks (10.3%), 0 events -2026-02-04T18:57:13.402089Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13770/133889 blocks (10.3%), 0 events -2026-02-04T18:57:13.645922Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13780/133889 blocks (10.3%), 0 events -2026-02-04T18:57:13.785923Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13790/133889 blocks (10.3%), 0 events -2026-02-04T18:57:13.974683Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13800/133889 blocks (10.3%), 0 events -2026-02-04T18:57:14.232985Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13810/133889 blocks (10.3%), 0 events -2026-02-04T18:57:14.451761Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13820/133889 blocks (10.3%), 0 events -2026-02-04T18:57:14.594504Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13830/133889 blocks (10.3%), 0 events -2026-02-04T18:57:14.834328Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13840/133889 blocks (10.3%), 0 events -2026-02-04T18:57:15.043086Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13850/133889 blocks (10.3%), 0 events -2026-02-04T18:57:15.274035Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13860/133889 blocks (10.4%), 0 events -2026-02-04T18:57:15.459305Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13870/133889 blocks (10.4%), 0 events -2026-02-04T18:57:15.628732Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13880/133889 blocks (10.4%), 0 events -2026-02-04T18:57:15.852955Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13890/133889 blocks (10.4%), 0 events -2026-02-04T18:57:15.996572Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13900/133889 blocks (10.4%), 0 events -2026-02-04T18:57:16.302242Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13910/133889 blocks (10.4%), 0 events -2026-02-04T18:57:16.442230Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13920/133889 blocks (10.4%), 0 events -2026-02-04T18:57:16.592753Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13930/133889 blocks (10.4%), 0 events -2026-02-04T18:57:16.834860Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13940/133889 blocks (10.4%), 0 events -2026-02-04T18:57:17.029286Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13950/133889 blocks (10.4%), 0 events -2026-02-04T18:57:17.197421Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13960/133889 blocks (10.4%), 0 events -2026-02-04T18:57:17.445905Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13970/133889 blocks (10.4%), 0 events -2026-02-04T18:57:17.647077Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13980/133889 blocks (10.4%), 0 events -2026-02-04T18:57:17.871432Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 13990/133889 blocks (10.4%), 0 events -2026-02-04T18:57:17.980665Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14000/133889 blocks (10.5%), 0 events -2026-02-04T18:57:18.181003Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14010/133889 blocks (10.5%), 0 events -2026-02-04T18:57:18.424557Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14020/133889 blocks (10.5%), 0 events -2026-02-04T18:57:18.659156Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14030/133889 blocks (10.5%), 0 events -2026-02-04T18:57:18.772184Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14040/133889 blocks (10.5%), 0 events -2026-02-04T18:57:18.982220Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14050/133889 blocks (10.5%), 0 events -2026-02-04T18:57:19.244143Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14060/133889 blocks (10.5%), 0 events -2026-02-04T18:57:19.452392Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14070/133889 blocks (10.5%), 0 events -2026-02-04T18:57:19.614430Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14080/133889 blocks (10.5%), 0 events -2026-02-04T18:57:19.828874Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14090/133889 blocks (10.5%), 0 events -2026-02-04T18:57:20.006048Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14100/133889 blocks (10.5%), 0 events -2026-02-04T18:57:20.186258Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14110/133889 blocks (10.5%), 0 events -2026-02-04T18:57:20.496442Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14120/133889 blocks (10.5%), 0 events -2026-02-04T18:57:20.597250Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14130/133889 blocks (10.6%), 0 events -2026-02-04T18:57:20.787577Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14140/133889 blocks (10.6%), 0 events -2026-02-04T18:57:21.023148Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14150/133889 blocks (10.6%), 0 events -2026-02-04T18:57:21.254110Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14160/133889 blocks (10.6%), 0 events -2026-02-04T18:57:21.390572Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14170/133889 blocks (10.6%), 0 events -2026-02-04T18:57:21.592128Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14180/133889 blocks (10.6%), 0 events -2026-02-04T18:57:21.810884Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14190/133889 blocks (10.6%), 0 events -2026-02-04T18:57:22.065990Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14200/133889 blocks (10.6%), 0 events -2026-02-04T18:57:22.166476Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14210/133889 blocks (10.6%), 0 events -2026-02-04T18:57:22.462922Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14220/133889 blocks (10.6%), 0 events -2026-02-04T18:57:22.634262Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14230/133889 blocks (10.6%), 0 events -2026-02-04T18:57:22.784377Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14240/133889 blocks (10.6%), 0 events -2026-02-04T18:57:23.112925Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14250/133889 blocks (10.6%), 0 events -2026-02-04T18:57:23.220074Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14260/133889 blocks (10.6%), 0 events -2026-02-04T18:57:23.422910Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14270/133889 blocks (10.7%), 0 events -2026-02-04T18:57:23.644715Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14280/133889 blocks (10.7%), 0 events -2026-02-04T18:57:23.809610Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14290/133889 blocks (10.7%), 0 events -2026-02-04T18:57:24.132556Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14300/133889 blocks (10.7%), 0 events -2026-02-04T18:57:24.173772Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14310/133889 blocks (10.7%), 0 events -2026-02-04T18:57:24.429825Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14320/133889 blocks (10.7%), 0 events -2026-02-04T18:57:24.687594Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14330/133889 blocks (10.7%), 0 events -2026-02-04T18:57:24.801929Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14340/133889 blocks (10.7%), 0 events -2026-02-04T18:57:25.002524Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14350/133889 blocks (10.7%), 0 events -2026-02-04T18:57:25.217960Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14360/133889 blocks (10.7%), 0 events -2026-02-04T18:57:25.430579Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14370/133889 blocks (10.7%), 0 events -2026-02-04T18:57:25.735994Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14380/133889 blocks (10.7%), 0 events -2026-02-04T18:57:25.775783Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14390/133889 blocks (10.7%), 0 events -2026-02-04T18:57:26.056824Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14400/133889 blocks (10.8%), 0 events -2026-02-04T18:57:26.263241Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14410/133889 blocks (10.8%), 0 events -2026-02-04T18:57:26.450914Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14420/133889 blocks (10.8%), 0 events -2026-02-04T18:57:26.624066Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14430/133889 blocks (10.8%), 0 events -2026-02-04T18:57:26.839222Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14440/133889 blocks (10.8%), 0 events -2026-02-04T18:57:27.040872Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14450/133889 blocks (10.8%), 0 events -2026-02-04T18:57:27.317840Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14460/133889 blocks (10.8%), 0 events -2026-02-04T18:57:27.460035Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14470/133889 blocks (10.8%), 0 events -2026-02-04T18:57:27.570090Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14480/133889 blocks (10.8%), 0 events -2026-02-04T18:57:27.844682Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14490/133889 blocks (10.8%), 0 events -2026-02-04T18:57:28.024369Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14500/133889 blocks (10.8%), 0 events -2026-02-04T18:57:28.181655Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14510/133889 blocks (10.8%), 0 events -2026-02-04T18:57:28.428090Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14520/133889 blocks (10.8%), 0 events -2026-02-04T18:57:28.663060Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14530/133889 blocks (10.9%), 0 events -2026-02-04T18:57:28.886787Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14540/133889 blocks (10.9%), 0 events -2026-02-04T18:57:29.059383Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14550/133889 blocks (10.9%), 0 events -2026-02-04T18:57:29.207460Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14560/133889 blocks (10.9%), 0 events -2026-02-04T18:57:29.409948Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14570/133889 blocks (10.9%), 0 events -2026-02-04T18:57:29.582369Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14580/133889 blocks (10.9%), 0 events -2026-02-04T18:57:29.898759Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14590/133889 blocks (10.9%), 0 events -2026-02-04T18:57:30.004680Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14600/133889 blocks (10.9%), 0 events -2026-02-04T18:57:30.247394Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14610/133889 blocks (10.9%), 0 events -2026-02-04T18:57:30.453512Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14620/133889 blocks (10.9%), 0 events -2026-02-04T18:57:30.576610Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14630/133889 blocks (10.9%), 0 events -2026-02-04T18:57:30.805164Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14640/133889 blocks (10.9%), 0 events -2026-02-04T18:57:31.004197Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14650/133889 blocks (10.9%), 0 events -2026-02-04T18:57:31.174624Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14660/133889 blocks (10.9%), 0 events -2026-02-04T18:57:31.516521Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14670/133889 blocks (11.0%), 0 events -2026-02-04T18:57:31.653432Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14680/133889 blocks (11.0%), 0 events -2026-02-04T18:57:31.858730Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14690/133889 blocks (11.0%), 0 events -2026-02-04T18:57:32.042263Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14700/133889 blocks (11.0%), 0 events -2026-02-04T18:57:32.238658Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14710/133889 blocks (11.0%), 0 events -2026-02-04T18:57:32.405705Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14720/133889 blocks (11.0%), 0 events -2026-02-04T18:57:32.656826Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14730/133889 blocks (11.0%), 0 events -2026-02-04T18:57:32.800754Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14740/133889 blocks (11.0%), 0 events -2026-02-04T18:57:33.044466Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14750/133889 blocks (11.0%), 0 events -2026-02-04T18:57:33.202983Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14760/133889 blocks (11.0%), 0 events -2026-02-04T18:57:33.465586Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14770/133889 blocks (11.0%), 0 events -2026-02-04T18:57:33.664779Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14780/133889 blocks (11.0%), 0 events -2026-02-04T18:57:33.823409Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14790/133889 blocks (11.0%), 0 events -2026-02-04T18:57:34.093104Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14800/133889 blocks (11.1%), 0 events -2026-02-04T18:57:34.169162Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14810/133889 blocks (11.1%), 0 events -2026-02-04T18:57:34.381193Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14820/133889 blocks (11.1%), 0 events -2026-02-04T18:57:34.663999Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14830/133889 blocks (11.1%), 0 events -2026-02-04T18:57:34.786014Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14840/133889 blocks (11.1%), 0 events -2026-02-04T18:57:34.974747Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14850/133889 blocks (11.1%), 0 events -2026-02-04T18:57:35.241060Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14860/133889 blocks (11.1%), 0 events -2026-02-04T18:57:35.377783Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14870/133889 blocks (11.1%), 0 events -2026-02-04T18:57:35.666066Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14880/133889 blocks (11.1%), 0 events -2026-02-04T18:57:35.831202Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14890/133889 blocks (11.1%), 0 events -2026-02-04T18:57:35.974404Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14900/133889 blocks (11.1%), 0 events -2026-02-04T18:57:36.237082Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14910/133889 blocks (11.1%), 0 events -2026-02-04T18:57:36.440708Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14920/133889 blocks (11.1%), 0 events -2026-02-04T18:57:36.714555Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14930/133889 blocks (11.2%), 0 events -2026-02-04T18:57:36.802951Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14940/133889 blocks (11.2%), 0 events -2026-02-04T18:57:37.036392Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14950/133889 blocks (11.2%), 0 events -2026-02-04T18:57:37.270936Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14960/133889 blocks (11.2%), 0 events -2026-02-04T18:57:37.447439Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14970/133889 blocks (11.2%), 0 events -2026-02-04T18:57:37.613532Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14980/133889 blocks (11.2%), 0 events -2026-02-04T18:57:37.863159Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 14990/133889 blocks (11.2%), 0 events -2026-02-04T18:57:37.989856Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15000/133889 blocks (11.2%), 0 events -2026-02-04T18:57:38.284580Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15010/133889 blocks (11.2%), 0 events -2026-02-04T18:57:38.419092Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15020/133889 blocks (11.2%), 0 events -2026-02-04T18:57:38.586083Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15030/133889 blocks (11.2%), 0 events -2026-02-04T18:57:38.848713Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15040/133889 blocks (11.2%), 0 events -2026-02-04T18:57:39.004670Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15050/133889 blocks (11.2%), 0 events -2026-02-04T18:57:39.229179Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15060/133889 blocks (11.2%), 0 events -2026-02-04T18:57:39.442046Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15070/133889 blocks (11.3%), 0 events -2026-02-04T18:57:39.612603Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15080/133889 blocks (11.3%), 0 events -2026-02-04T18:57:39.896984Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15090/133889 blocks (11.3%), 0 events -2026-02-04T18:57:40.020107Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15100/133889 blocks (11.3%), 0 events -2026-02-04T18:57:40.252339Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15110/133889 blocks (11.3%), 0 events -2026-02-04T18:57:40.418419Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15120/133889 blocks (11.3%), 0 events -2026-02-04T18:57:40.571959Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15130/133889 blocks (11.3%), 0 events -2026-02-04T18:57:40.785552Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15140/133889 blocks (11.3%), 0 events -2026-02-04T18:57:40.978440Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15150/133889 blocks (11.3%), 0 events -2026-02-04T18:57:41.233778Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15160/133889 blocks (11.3%), 0 events -2026-02-04T18:57:41.471792Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15170/133889 blocks (11.3%), 0 events -2026-02-04T18:57:41.639750Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15180/133889 blocks (11.3%), 0 events -2026-02-04T18:57:41.788580Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15190/133889 blocks (11.3%), 0 events -2026-02-04T18:57:42.032577Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15200/133889 blocks (11.4%), 0 events -2026-02-04T18:57:42.247092Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15210/133889 blocks (11.4%), 0 events -2026-02-04T18:57:42.481419Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15220/133889 blocks (11.4%), 0 events -2026-02-04T18:57:42.561395Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15230/133889 blocks (11.4%), 0 events -2026-02-04T18:57:42.865698Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15240/133889 blocks (11.4%), 0 events -2026-02-04T18:57:43.039315Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15250/133889 blocks (11.4%), 0 events -2026-02-04T18:57:43.218401Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15260/133889 blocks (11.4%), 0 events -2026-02-04T18:57:43.387505Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15270/133889 blocks (11.4%), 0 events -2026-02-04T18:57:43.574062Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15280/133889 blocks (11.4%), 0 events -2026-02-04T18:57:43.807496Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15290/133889 blocks (11.4%), 0 events -2026-02-04T18:57:44.054935Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15300/133889 blocks (11.4%), 0 events -2026-02-04T18:57:44.233973Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15310/133889 blocks (11.4%), 0 events -2026-02-04T18:57:44.439952Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15320/133889 blocks (11.4%), 0 events -2026-02-04T18:57:44.619113Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15330/133889 blocks (11.4%), 0 events -2026-02-04T18:57:44.828530Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15340/133889 blocks (11.5%), 0 events -2026-02-04T18:57:45.131501Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15350/133889 blocks (11.5%), 0 events -2026-02-04T18:57:45.167876Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15360/133889 blocks (11.5%), 0 events -2026-02-04T18:57:45.446370Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15370/133889 blocks (11.5%), 0 events -2026-02-04T18:57:45.658734Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15380/133889 blocks (11.5%), 0 events -2026-02-04T18:57:45.763933Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15390/133889 blocks (11.5%), 0 events -2026-02-04T18:57:46.020119Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15400/133889 blocks (11.5%), 0 events -2026-02-04T18:57:46.243376Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15410/133889 blocks (11.5%), 0 events -2026-02-04T18:57:46.388194Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15420/133889 blocks (11.5%), 0 events -2026-02-04T18:57:46.704068Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15430/133889 blocks (11.5%), 0 events -2026-02-04T18:57:46.785860Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15440/133889 blocks (11.5%), 0 events -2026-02-04T18:57:47.015901Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15450/133889 blocks (11.5%), 0 events -2026-02-04T18:57:47.235774Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15460/133889 blocks (11.5%), 0 events -2026-02-04T18:57:47.412393Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15470/133889 blocks (11.6%), 0 events -2026-02-04T18:57:47.591673Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15480/133889 blocks (11.6%), 0 events -2026-02-04T18:57:47.808443Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15490/133889 blocks (11.6%), 0 events -2026-02-04T18:57:47.998811Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15500/133889 blocks (11.6%), 0 events -2026-02-04T18:57:48.245751Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15510/133889 blocks (11.6%), 0 events -2026-02-04T18:57:48.383439Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15520/133889 blocks (11.6%), 0 events -2026-02-04T18:57:48.583446Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15530/133889 blocks (11.6%), 0 events -2026-02-04T18:57:48.830084Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15540/133889 blocks (11.6%), 0 events -2026-02-04T18:57:48.985570Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15550/133889 blocks (11.6%), 0 events -2026-02-04T18:57:49.332374Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15560/133889 blocks (11.6%), 0 events -2026-02-04T18:57:49.375622Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15570/133889 blocks (11.6%), 0 events -2026-02-04T18:57:49.615919Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15580/133889 blocks (11.6%), 0 events -2026-02-04T18:57:49.866252Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15590/133889 blocks (11.6%), 0 events -2026-02-04T18:57:49.997673Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15600/133889 blocks (11.7%), 0 events -2026-02-04T18:57:50.181004Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15610/133889 blocks (11.7%), 0 events -2026-02-04T18:57:50.447197Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15620/133889 blocks (11.7%), 0 events -2026-02-04T18:57:50.627452Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15630/133889 blocks (11.7%), 0 events -2026-02-04T18:57:50.776750Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15640/133889 blocks (11.7%), 0 events -2026-02-04T18:57:50.977626Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15650/133889 blocks (11.7%), 0 events -2026-02-04T18:57:51.196694Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15660/133889 blocks (11.7%), 0 events -2026-02-04T18:57:51.438564Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15670/133889 blocks (11.7%), 0 events -2026-02-04T18:57:51.608112Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15680/133889 blocks (11.7%), 0 events -2026-02-04T18:57:51.917971Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15690/133889 blocks (11.7%), 0 events -2026-02-04T18:57:52.032127Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15700/133889 blocks (11.7%), 0 events -2026-02-04T18:57:52.242213Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15710/133889 blocks (11.7%), 0 events -2026-02-04T18:57:52.443729Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15720/133889 blocks (11.7%), 0 events -2026-02-04T18:57:52.586743Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15730/133889 blocks (11.7%), 0 events -2026-02-04T18:57:52.837389Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15740/133889 blocks (11.8%), 0 events -2026-02-04T18:57:52.998917Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15750/133889 blocks (11.8%), 0 events -2026-02-04T18:57:53.201086Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15760/133889 blocks (11.8%), 0 events -2026-02-04T18:57:53.382019Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15770/133889 blocks (11.8%), 0 events -2026-02-04T18:57:53.571046Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15780/133889 blocks (11.8%), 0 events -2026-02-04T18:57:53.789848Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15790/133889 blocks (11.8%), 0 events -2026-02-04T18:57:54.046429Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15800/133889 blocks (11.8%), 0 events -2026-02-04T18:57:54.232252Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15810/133889 blocks (11.8%), 0 events -2026-02-04T18:57:54.439379Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15820/133889 blocks (11.8%), 0 events -2026-02-04T18:57:54.628337Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15830/133889 blocks (11.8%), 0 events -2026-02-04T18:57:54.834280Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15840/133889 blocks (11.8%), 0 events -2026-02-04T18:57:55.063072Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15850/133889 blocks (11.8%), 0 events -2026-02-04T18:57:55.242716Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15860/133889 blocks (11.8%), 0 events -2026-02-04T18:57:55.369158Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15870/133889 blocks (11.9%), 0 events -2026-02-04T18:57:55.646076Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15880/133889 blocks (11.9%), 0 events -2026-02-04T18:57:55.811941Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15890/133889 blocks (11.9%), 0 events -2026-02-04T18:57:56.113207Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15900/133889 blocks (11.9%), 0 events -2026-02-04T18:57:56.252860Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15910/133889 blocks (11.9%), 0 events -2026-02-04T18:57:56.442251Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15920/133889 blocks (11.9%), 0 events -2026-02-04T18:57:56.672657Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15930/133889 blocks (11.9%), 0 events -2026-02-04T18:57:56.845539Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15940/133889 blocks (11.9%), 0 events -2026-02-04T18:57:56.966713Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15950/133889 blocks (11.9%), 0 events -2026-02-04T18:57:57.213427Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15960/133889 blocks (11.9%), 0 events -2026-02-04T18:57:57.444261Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15970/133889 blocks (11.9%), 0 events -2026-02-04T18:57:57.685561Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15980/133889 blocks (11.9%), 0 events -2026-02-04T18:57:57.782024Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 15990/133889 blocks (11.9%), 0 events -2026-02-04T18:57:57.981271Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16000/133889 blocks (11.9%), 0 events -2026-02-04T18:57:58.241265Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16010/133889 blocks (12.0%), 0 events -2026-02-04T18:57:58.423018Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16020/133889 blocks (12.0%), 0 events -2026-02-04T18:57:58.733225Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16030/133889 blocks (12.0%), 0 events -2026-02-04T18:57:58.774132Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16040/133889 blocks (12.0%), 0 events -2026-02-04T18:57:59.012162Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16050/133889 blocks (12.0%), 0 events -2026-02-04T18:57:59.299352Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16060/133889 blocks (12.0%), 0 events -2026-02-04T18:57:59.401733Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16070/133889 blocks (12.0%), 0 events -2026-02-04T18:57:59.648398Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16080/133889 blocks (12.0%), 0 events -2026-02-04T18:57:59.844923Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16090/133889 blocks (12.0%), 0 events -2026-02-04T18:57:59.989825Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16100/133889 blocks (12.0%), 0 events -2026-02-04T18:58:00.342046Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16110/133889 blocks (12.0%), 0 events -2026-02-04T18:58:00.384953Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16120/133889 blocks (12.0%), 0 events -2026-02-04T18:58:00.614952Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16130/133889 blocks (12.0%), 0 events -2026-02-04T18:58:00.862139Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16140/133889 blocks (12.1%), 0 events -2026-02-04T18:58:01.000896Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16150/133889 blocks (12.1%), 0 events -2026-02-04T18:58:01.215954Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16160/133889 blocks (12.1%), 0 events -2026-02-04T18:58:01.387056Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16170/133889 blocks (12.1%), 0 events -2026-02-04T18:58:01.666376Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16180/133889 blocks (12.1%), 0 events -2026-02-04T18:58:01.769747Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16190/133889 blocks (12.1%), 0 events -2026-02-04T18:58:01.999570Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16200/133889 blocks (12.1%), 0 events -2026-02-04T18:58:02.211047Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16210/133889 blocks (12.1%), 0 events -2026-02-04T18:58:02.441883Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16220/133889 blocks (12.1%), 0 events -2026-02-04T18:58:02.581124Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16230/133889 blocks (12.1%), 0 events -2026-02-04T18:58:02.803626Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16240/133889 blocks (12.1%), 0 events -2026-02-04T18:58:03.035162Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16250/133889 blocks (12.1%), 0 events -2026-02-04T18:58:03.192955Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16260/133889 blocks (12.1%), 0 events -2026-02-04T18:58:03.490918Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16270/133889 blocks (12.2%), 0 events -2026-02-04T18:58:03.582699Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16280/133889 blocks (12.2%), 0 events -2026-02-04T18:58:03.804000Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16290/133889 blocks (12.2%), 0 events -2026-02-04T18:58:04.063946Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16300/133889 blocks (12.2%), 0 events -2026-02-04T18:58:04.200556Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16310/133889 blocks (12.2%), 0 events -2026-02-04T18:58:04.543472Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16320/133889 blocks (12.2%), 0 events -2026-02-04T18:58:04.598291Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16330/133889 blocks (12.2%), 0 events -2026-02-04T18:58:04.807552Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16340/133889 blocks (12.2%), 0 events -2026-02-04T18:58:05.059849Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16350/133889 blocks (12.2%), 0 events -2026-02-04T18:58:05.225447Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16360/133889 blocks (12.2%), 0 events -2026-02-04T18:58:05.382607Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16370/133889 blocks (12.2%), 0 events -2026-02-04T18:58:05.651763Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16380/133889 blocks (12.2%), 0 events -2026-02-04T18:58:05.814034Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16390/133889 blocks (12.2%), 0 events -2026-02-04T18:58:06.109434Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16400/133889 blocks (12.2%), 0 events -2026-02-04T18:58:06.204257Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16410/133889 blocks (12.3%), 0 events -2026-02-04T18:58:06.387183Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16420/133889 blocks (12.3%), 0 events -2026-02-04T18:58:06.632592Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16430/133889 blocks (12.3%), 0 events -2026-02-04T18:58:06.798972Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16440/133889 blocks (12.3%), 0 events -2026-02-04T18:58:06.996612Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16450/133889 blocks (12.3%), 0 events -2026-02-04T18:58:07.189322Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16460/133889 blocks (12.3%), 0 events -2026-02-04T18:58:07.419172Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16470/133889 blocks (12.3%), 0 events -2026-02-04T18:58:07.682900Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16480/133889 blocks (12.3%), 0 events -2026-02-04T18:58:07.778685Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16490/133889 blocks (12.3%), 0 events -2026-02-04T18:58:07.993244Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16500/133889 blocks (12.3%), 0 events -2026-02-04T18:58:08.218074Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16510/133889 blocks (12.3%), 0 events -2026-02-04T18:58:08.365263Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16520/133889 blocks (12.3%), 0 events -2026-02-04T18:58:08.693792Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16530/133889 blocks (12.3%), 0 events -2026-02-04T18:58:08.820252Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16540/133889 blocks (12.4%), 0 events -2026-02-04T18:58:09.043362Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16550/133889 blocks (12.4%), 0 events -2026-02-04T18:58:09.255338Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16560/133889 blocks (12.4%), 0 events -2026-02-04T18:58:09.428690Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16570/133889 blocks (12.4%), 0 events -2026-02-04T18:58:09.627407Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16580/133889 blocks (12.4%), 0 events -2026-02-04T18:58:09.788219Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16590/133889 blocks (12.4%), 0 events -2026-02-04T18:58:10.066317Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16600/133889 blocks (12.4%), 0 events -2026-02-04T18:58:10.300440Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16610/133889 blocks (12.4%), 0 events -2026-02-04T18:58:10.396647Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16620/133889 blocks (12.4%), 0 events -2026-02-04T18:58:10.564761Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16630/133889 blocks (12.4%), 0 events -2026-02-04T18:58:10.864654Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16640/133889 blocks (12.4%), 0 events -2026-02-04T18:58:11.042650Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16650/133889 blocks (12.4%), 0 events -2026-02-04T18:58:11.314184Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16660/133889 blocks (12.4%), 0 events -2026-02-04T18:58:11.393421Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16670/133889 blocks (12.4%), 0 events -2026-02-04T18:58:11.568969Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16680/133889 blocks (12.5%), 0 events -2026-02-04T18:58:11.877258Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16690/133889 blocks (12.5%), 0 events -2026-02-04T18:58:12.065156Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16700/133889 blocks (12.5%), 0 events -2026-02-04T18:58:12.167401Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16710/133889 blocks (12.5%), 0 events -2026-02-04T18:58:12.402259Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16720/133889 blocks (12.5%), 0 events -2026-02-04T18:58:12.586419Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16730/133889 blocks (12.5%), 0 events -2026-02-04T18:58:12.889119Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16740/133889 blocks (12.5%), 0 events -2026-02-04T18:58:12.997000Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16750/133889 blocks (12.5%), 0 events -2026-02-04T18:58:13.263185Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16760/133889 blocks (12.5%), 0 events -2026-02-04T18:58:13.458658Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16770/133889 blocks (12.5%), 0 events -2026-02-04T18:58:13.595011Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16780/133889 blocks (12.5%), 0 events -2026-02-04T18:58:13.810454Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16790/133889 blocks (12.5%), 0 events -2026-02-04T18:58:14.004482Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16800/133889 blocks (12.5%), 0 events -2026-02-04T18:58:14.238054Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16810/133889 blocks (12.6%), 0 events -2026-02-04T18:58:14.497744Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16820/133889 blocks (12.6%), 0 events -2026-02-04T18:58:14.636575Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16830/133889 blocks (12.6%), 0 events -2026-02-04T18:58:14.851291Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16840/133889 blocks (12.6%), 0 events -2026-02-04T18:58:15.018813Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16850/133889 blocks (12.6%), 0 events -2026-02-04T18:58:15.198347Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16860/133889 blocks (12.6%), 0 events -2026-02-04T18:58:15.396549Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16870/133889 blocks (12.6%), 0 events -2026-02-04T18:58:15.566757Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16880/133889 blocks (12.6%), 0 events -2026-02-04T18:58:15.818998Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16890/133889 blocks (12.6%), 0 events -2026-02-04T18:58:16.032729Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16900/133889 blocks (12.6%), 0 events -2026-02-04T18:58:16.220608Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16910/133889 blocks (12.6%), 0 events -2026-02-04T18:58:16.455529Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16920/133889 blocks (12.6%), 0 events -2026-02-04T18:58:16.590484Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16930/133889 blocks (12.6%), 0 events -2026-02-04T18:58:16.839172Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16940/133889 blocks (12.7%), 0 events -2026-02-04T18:58:16.989618Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16950/133889 blocks (12.7%), 0 events -2026-02-04T18:58:17.189420Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16960/133889 blocks (12.7%), 0 events -2026-02-04T18:58:17.371970Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16970/133889 blocks (12.7%), 0 events -2026-02-04T18:58:17.647523Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16980/133889 blocks (12.7%), 0 events -2026-02-04T18:58:17.773300Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 16990/133889 blocks (12.7%), 0 events -2026-02-04T18:58:18.002311Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17000/133889 blocks (12.7%), 0 events -2026-02-04T18:58:18.212768Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17010/133889 blocks (12.7%), 0 events -2026-02-04T18:58:18.461343Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17020/133889 blocks (12.7%), 0 events -2026-02-04T18:58:18.654724Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17030/133889 blocks (12.7%), 0 events -2026-02-04T18:58:18.801955Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17040/133889 blocks (12.7%), 0 events -2026-02-04T18:58:19.029157Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17050/133889 blocks (12.7%), 0 events -2026-02-04T18:58:19.214141Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17060/133889 blocks (12.7%), 0 events -2026-02-04T18:58:19.444820Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17070/133889 blocks (12.7%), 0 events -2026-02-04T18:58:19.702335Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17080/133889 blocks (12.8%), 0 events -2026-02-04T18:58:19.807472Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17090/133889 blocks (12.8%), 0 events -2026-02-04T18:58:20.016599Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17100/133889 blocks (12.8%), 0 events -2026-02-04T18:58:20.260905Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17110/133889 blocks (12.8%), 0 events -2026-02-04T18:58:20.389204Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17120/133889 blocks (12.8%), 0 events -2026-02-04T18:58:20.643831Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17130/133889 blocks (12.8%), 0 events -2026-02-04T18:58:20.810792Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17140/133889 blocks (12.8%), 0 events -2026-02-04T18:58:20.997278Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17150/133889 blocks (12.8%), 0 events -2026-02-04T18:58:21.275396Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17160/133889 blocks (12.8%), 0 events -2026-02-04T18:58:21.440105Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17170/133889 blocks (12.8%), 0 events -2026-02-04T18:58:21.599806Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17180/133889 blocks (12.8%), 0 events -2026-02-04T18:58:21.832362Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17190/133889 blocks (12.8%), 0 events -2026-02-04T18:58:22.060828Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17200/133889 blocks (12.8%), 0 events -2026-02-04T18:58:22.182825Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17210/133889 blocks (12.9%), 0 events -2026-02-04T18:58:22.399615Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17220/133889 blocks (12.9%), 0 events -2026-02-04T18:58:22.579557Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17230/133889 blocks (12.9%), 0 events -2026-02-04T18:58:22.893046Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17240/133889 blocks (12.9%), 0 events -2026-02-04T18:58:23.066158Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17250/133889 blocks (12.9%), 0 events -2026-02-04T18:58:23.175560Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17260/133889 blocks (12.9%), 0 events -2026-02-04T18:58:23.440513Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17270/133889 blocks (12.9%), 0 events -2026-02-04T18:58:23.586177Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17280/133889 blocks (12.9%), 0 events -2026-02-04T18:58:23.934288Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17290/133889 blocks (12.9%), 0 events -2026-02-04T18:58:23.978097Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17300/133889 blocks (12.9%), 0 events -2026-02-04T18:58:24.226495Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17310/133889 blocks (12.9%), 0 events -2026-02-04T18:58:24.465698Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17320/133889 blocks (12.9%), 0 events -2026-02-04T18:58:24.598243Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17330/133889 blocks (12.9%), 0 events -2026-02-04T18:58:24.831898Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17340/133889 blocks (13.0%), 0 events -2026-02-04T18:58:25.042703Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17350/133889 blocks (13.0%), 0 events -2026-02-04T18:58:25.225031Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17360/133889 blocks (13.0%), 0 events -2026-02-04T18:58:25.507876Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17370/133889 blocks (13.0%), 0 events -2026-02-04T18:58:25.572306Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17380/133889 blocks (13.0%), 0 events -2026-02-04T18:58:25.821686Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17390/133889 blocks (13.0%), 0 events -2026-02-04T18:58:26.030096Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17400/133889 blocks (13.0%), 0 events -2026-02-04T18:58:26.191726Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17410/133889 blocks (13.0%), 0 events -2026-02-04T18:58:26.381721Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17420/133889 blocks (13.0%), 0 events -2026-02-04T18:58:26.634873Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17430/133889 blocks (13.0%), 0 events -2026-02-04T18:58:26.849727Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17440/133889 blocks (13.0%), 0 events -2026-02-04T18:58:27.043366Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17450/133889 blocks (13.0%), 0 events -2026-02-04T18:58:27.209472Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17460/133889 blocks (13.0%), 0 events -2026-02-04T18:58:27.384499Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17470/133889 blocks (13.0%), 0 events -2026-02-04T18:58:27.627663Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17480/133889 blocks (13.1%), 0 events -2026-02-04T18:58:27.826405Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17490/133889 blocks (13.1%), 0 events -2026-02-04T18:58:27.977040Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17500/133889 blocks (13.1%), 0 events -2026-02-04T18:58:28.264821Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17510/133889 blocks (13.1%), 0 events -2026-02-04T18:58:28.446297Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17520/133889 blocks (13.1%), 0 events -2026-02-04T18:58:28.652537Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17530/133889 blocks (13.1%), 0 events -2026-02-04T18:58:28.799631Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17540/133889 blocks (13.1%), 0 events -2026-02-04T18:58:29.047439Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17550/133889 blocks (13.1%), 0 events -2026-02-04T18:58:29.235022Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17560/133889 blocks (13.1%), 0 events -2026-02-04T18:58:29.386317Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17570/133889 blocks (13.1%), 0 events -2026-02-04T18:58:29.699928Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17580/133889 blocks (13.1%), 0 events -2026-02-04T18:58:29.772482Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17590/133889 blocks (13.1%), 0 events -2026-02-04T18:58:30.037929Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17600/133889 blocks (13.1%), 0 events -2026-02-04T18:58:30.224378Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17610/133889 blocks (13.2%), 0 events -2026-02-04T18:58:30.413594Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17620/133889 blocks (13.2%), 0 events -2026-02-04T18:58:30.713489Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17630/133889 blocks (13.2%), 0 events -2026-02-04T18:58:30.798766Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17640/133889 blocks (13.2%), 0 events -2026-02-04T18:58:30.971470Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17650/133889 blocks (13.2%), 0 events -2026-02-04T18:58:31.273775Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17660/133889 blocks (13.2%), 0 events -2026-02-04T18:58:31.382455Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17670/133889 blocks (13.2%), 0 events -2026-02-04T18:58:31.609977Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17680/133889 blocks (13.2%), 0 events -2026-02-04T18:58:31.810998Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17690/133889 blocks (13.2%), 0 events -2026-02-04T18:58:31.975818Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17700/133889 blocks (13.2%), 0 events -2026-02-04T18:58:32.315298Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17710/133889 blocks (13.2%), 0 events -2026-02-04T18:58:32.401727Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17720/133889 blocks (13.2%), 0 events -2026-02-04T18:58:32.578993Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17730/133889 blocks (13.2%), 0 events -2026-02-04T18:58:32.850621Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17740/133889 blocks (13.2%), 0 events -2026-02-04T18:58:33.038360Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17750/133889 blocks (13.3%), 0 events -2026-02-04T18:58:33.198538Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17760/133889 blocks (13.3%), 0 events -2026-02-04T18:58:33.402781Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17770/133889 blocks (13.3%), 0 events -2026-02-04T18:58:33.612237Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17780/133889 blocks (13.3%), 0 events -2026-02-04T18:58:33.894009Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17790/133889 blocks (13.3%), 0 events -2026-02-04T18:58:34.062396Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17800/133889 blocks (13.3%), 0 events -2026-02-04T18:58:34.234066Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17810/133889 blocks (13.3%), 0 events -2026-02-04T18:58:34.416845Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17820/133889 blocks (13.3%), 0 events -2026-02-04T18:58:34.582487Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17830/133889 blocks (13.3%), 0 events -2026-02-04T18:58:34.795555Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17840/133889 blocks (13.3%), 0 events -2026-02-04T18:58:35.045665Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17850/133889 blocks (13.3%), 0 events -2026-02-04T18:58:35.257747Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17860/133889 blocks (13.3%), 0 events -2026-02-04T18:58:35.473462Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17870/133889 blocks (13.3%), 0 events -2026-02-04T18:58:35.633879Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17880/133889 blocks (13.4%), 0 events -2026-02-04T18:58:35.783378Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17890/133889 blocks (13.4%), 0 events -2026-02-04T18:58:36.055843Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17900/133889 blocks (13.4%), 0 events -2026-02-04T18:58:36.169648Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17910/133889 blocks (13.4%), 0 events -2026-02-04T18:58:36.480666Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17920/133889 blocks (13.4%), 0 events -2026-02-04T18:58:36.651207Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17930/133889 blocks (13.4%), 0 events -2026-02-04T18:58:36.827462Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17940/133889 blocks (13.4%), 0 events -2026-02-04T18:58:37.038988Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17950/133889 blocks (13.4%), 0 events -2026-02-04T18:58:37.245605Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17960/133889 blocks (13.4%), 0 events -2026-02-04T18:58:37.382089Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17970/133889 blocks (13.4%), 0 events -2026-02-04T18:58:37.587050Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17980/133889 blocks (13.4%), 0 events -2026-02-04T18:58:37.860432Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 17990/133889 blocks (13.4%), 0 events -2026-02-04T18:58:38.092205Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18000/133889 blocks (13.4%), 0 events -2026-02-04T18:58:38.266580Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18010/133889 blocks (13.5%), 0 events -2026-02-04T18:58:38.436750Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18020/133889 blocks (13.5%), 0 events -2026-02-04T18:58:38.653964Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18030/133889 blocks (13.5%), 0 events -2026-02-04T18:58:38.820020Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18040/133889 blocks (13.5%), 0 events -2026-02-04T18:58:38.981560Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18050/133889 blocks (13.5%), 0 events -2026-02-04T18:58:39.200316Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18060/133889 blocks (13.5%), 0 events -2026-02-04T18:58:39.464160Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18070/133889 blocks (13.5%), 0 events -2026-02-04T18:58:39.661988Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18080/133889 blocks (13.5%), 0 events -2026-02-04T18:58:39.790734Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18090/133889 blocks (13.5%), 0 events -2026-02-04T18:58:40.009609Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18100/133889 blocks (13.5%), 0 events -2026-02-04T18:58:40.239463Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18110/133889 blocks (13.5%), 0 events -2026-02-04T18:58:40.444858Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18120/133889 blocks (13.5%), 0 events -2026-02-04T18:58:40.675568Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18130/133889 blocks (13.5%), 0 events -2026-02-04T18:58:40.847517Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18140/133889 blocks (13.5%), 0 events -2026-02-04T18:58:40.978797Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18150/133889 blocks (13.6%), 0 events -2026-02-04T18:58:41.256474Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18160/133889 blocks (13.6%), 0 events -2026-02-04T18:58:41.456795Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18170/133889 blocks (13.6%), 0 events -2026-02-04T18:58:41.600879Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18180/133889 blocks (13.6%), 0 events -2026-02-04T18:58:41.861850Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18190/133889 blocks (13.6%), 0 events -2026-02-04T18:58:42.030389Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18200/133889 blocks (13.6%), 0 events -2026-02-04T18:58:42.245243Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18210/133889 blocks (13.6%), 0 events -2026-02-04T18:58:42.399217Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18220/133889 blocks (13.6%), 0 events -2026-02-04T18:58:42.595307Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18230/133889 blocks (13.6%), 0 events -2026-02-04T18:58:42.802810Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18240/133889 blocks (13.6%), 0 events -2026-02-04T18:58:43.002823Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18250/133889 blocks (13.6%), 0 events -2026-02-04T18:58:43.175753Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18260/133889 blocks (13.6%), 0 events -2026-02-04T18:58:43.400024Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18270/133889 blocks (13.6%), 0 events -2026-02-04T18:58:43.595714Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18280/133889 blocks (13.7%), 0 events -2026-02-04T18:58:43.860210Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18290/133889 blocks (13.7%), 0 events -2026-02-04T18:58:44.044767Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18300/133889 blocks (13.7%), 0 events -2026-02-04T18:58:44.250901Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18310/133889 blocks (13.7%), 0 events -2026-02-04T18:58:44.378827Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18320/133889 blocks (13.7%), 0 events -2026-02-04T18:58:44.644297Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18330/133889 blocks (13.7%), 0 events -2026-02-04T18:58:44.899695Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18340/133889 blocks (13.7%), 0 events -2026-02-04T18:58:45.008170Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18350/133889 blocks (13.7%), 0 events -2026-02-04T18:58:45.220045Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18360/133889 blocks (13.7%), 0 events -2026-02-04T18:58:45.423132Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18370/133889 blocks (13.7%), 0 events -2026-02-04T18:58:45.586770Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18380/133889 blocks (13.7%), 0 events -2026-02-04T18:58:45.810247Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18390/133889 blocks (13.7%), 0 events -2026-02-04T18:58:45.989928Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18400/133889 blocks (13.7%), 0 events -2026-02-04T18:58:46.224417Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18410/133889 blocks (13.7%), 0 events -2026-02-04T18:58:46.473400Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18420/133889 blocks (13.8%), 0 events -2026-02-04T18:58:46.564479Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18430/133889 blocks (13.8%), 0 events -2026-02-04T18:58:46.807832Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18440/133889 blocks (13.8%), 0 events -2026-02-04T18:58:46.998596Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18450/133889 blocks (13.8%), 0 events -2026-02-04T18:58:47.202390Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18460/133889 blocks (13.8%), 0 events -2026-02-04T18:58:47.531473Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18470/133889 blocks (13.8%), 0 events -2026-02-04T18:58:47.570190Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18480/133889 blocks (13.8%), 0 events -2026-02-04T18:58:47.788809Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18490/133889 blocks (13.8%), 0 events -2026-02-04T18:58:48.053017Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18500/133889 blocks (13.8%), 0 events -2026-02-04T18:58:48.252055Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18510/133889 blocks (13.8%), 0 events -2026-02-04T18:58:48.538690Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18520/133889 blocks (13.8%), 0 events -2026-02-04T18:58:48.577514Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18530/133889 blocks (13.8%), 0 events -2026-02-04T18:58:48.785060Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18540/133889 blocks (13.8%), 0 events -2026-02-04T18:58:49.061990Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18550/133889 blocks (13.9%), 0 events -2026-02-04T18:58:49.208309Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18560/133889 blocks (13.9%), 0 events -2026-02-04T18:58:49.375361Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18570/133889 blocks (13.9%), 0 events -2026-02-04T18:58:49.617217Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18580/133889 blocks (13.9%), 0 events -2026-02-04T18:58:49.841282Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18590/133889 blocks (13.9%), 0 events -2026-02-04T18:58:50.110235Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18600/133889 blocks (13.9%), 0 events -2026-02-04T18:58:50.251306Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18610/133889 blocks (13.9%), 0 events -2026-02-04T18:58:50.461249Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18620/133889 blocks (13.9%), 0 events -2026-02-04T18:58:50.731103Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18630/133889 blocks (13.9%), 0 events -2026-02-04T18:58:50.776713Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18640/133889 blocks (13.9%), 0 events -2026-02-04T18:58:51.060080Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18650/133889 blocks (13.9%), 0 events -2026-02-04T18:58:51.293908Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18660/133889 blocks (13.9%), 0 events -2026-02-04T18:58:51.440932Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18670/133889 blocks (13.9%), 0 events -2026-02-04T18:58:51.607468Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18680/133889 blocks (14.0%), 0 events -2026-02-04T18:58:51.825530Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18690/133889 blocks (14.0%), 0 events -2026-02-04T18:58:52.013178Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18700/133889 blocks (14.0%), 0 events -2026-02-04T18:58:52.303290Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18710/133889 blocks (14.0%), 0 events -2026-02-04T18:58:52.415814Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18720/133889 blocks (14.0%), 0 events -2026-02-04T18:58:52.664466Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18730/133889 blocks (14.0%), 0 events -2026-02-04T18:58:52.861314Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18740/133889 blocks (14.0%), 0 events -2026-02-04T18:58:52.987125Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18750/133889 blocks (14.0%), 0 events -2026-02-04T18:58:53.255244Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18760/133889 blocks (14.0%), 0 events -2026-02-04T18:58:53.458109Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18770/133889 blocks (14.0%), 0 events -2026-02-04T18:58:53.616868Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18780/133889 blocks (14.0%), 0 events -2026-02-04T18:58:53.875391Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18790/133889 blocks (14.0%), 0 events -2026-02-04T18:58:53.996560Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18800/133889 blocks (14.0%), 0 events -2026-02-04T18:58:54.170464Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18810/133889 blocks (14.0%), 0 events -2026-02-04T18:58:54.432717Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18820/133889 blocks (14.1%), 0 events -2026-02-04T18:58:54.617366Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18830/133889 blocks (14.1%), 0 events -2026-02-04T18:58:54.791980Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18840/133889 blocks (14.1%), 0 events -2026-02-04T18:58:54.972048Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18850/133889 blocks (14.1%), 0 events -2026-02-04T18:58:55.232254Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18860/133889 blocks (14.1%), 0 events -2026-02-04T18:58:55.449081Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18870/133889 blocks (14.1%), 0 events -2026-02-04T18:58:55.581945Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18880/133889 blocks (14.1%), 0 events -2026-02-04T18:58:55.832237Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18890/133889 blocks (14.1%), 0 events -2026-02-04T18:58:56.018422Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18900/133889 blocks (14.1%), 0 events -2026-02-04T18:58:56.213733Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18910/133889 blocks (14.1%), 0 events -2026-02-04T18:58:56.397141Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18920/133889 blocks (14.1%), 0 events -2026-02-04T18:58:56.665415Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18930/133889 blocks (14.1%), 0 events -2026-02-04T18:58:56.797549Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18940/133889 blocks (14.1%), 0 events -2026-02-04T18:58:57.055334Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18950/133889 blocks (14.2%), 0 events -2026-02-04T18:58:57.218835Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18960/133889 blocks (14.2%), 0 events -2026-02-04T18:58:57.420291Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18970/133889 blocks (14.2%), 0 events -2026-02-04T18:58:57.594355Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18980/133889 blocks (14.2%), 0 events -2026-02-04T18:58:57.822078Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 18990/133889 blocks (14.2%), 0 events -2026-02-04T18:58:58.070201Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19000/133889 blocks (14.2%), 0 events -2026-02-04T18:58:58.173188Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19010/133889 blocks (14.2%), 0 events -2026-02-04T18:58:58.403995Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19020/133889 blocks (14.2%), 0 events -2026-02-04T18:58:58.626838Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19030/133889 blocks (14.2%), 0 events -2026-02-04T18:58:58.840441Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19040/133889 blocks (14.2%), 0 events -2026-02-04T18:58:59.120020Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19050/133889 blocks (14.2%), 0 events -2026-02-04T18:58:59.166702Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19060/133889 blocks (14.2%), 0 events -2026-02-04T18:58:59.392572Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19070/133889 blocks (14.2%), 0 events -2026-02-04T18:58:59.678898Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19080/133889 blocks (14.2%), 0 events -2026-02-04T18:58:59.808772Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19090/133889 blocks (14.3%), 0 events -2026-02-04T18:59:00.051960Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19100/133889 blocks (14.3%), 0 events -2026-02-04T18:59:00.208158Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19110/133889 blocks (14.3%), 0 events -2026-02-04T18:59:00.373131Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19120/133889 blocks (14.3%), 0 events -2026-02-04T18:59:00.724606Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19130/133889 blocks (14.3%), 0 events -2026-02-04T18:59:00.772276Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19140/133889 blocks (14.3%), 0 events -2026-02-04T18:59:01.011524Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19150/133889 blocks (14.3%), 0 events -2026-02-04T18:59:01.252453Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19160/133889 blocks (14.3%), 0 events -2026-02-04T18:59:01.462882Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19170/133889 blocks (14.3%), 0 events -2026-02-04T18:59:01.594114Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19180/133889 blocks (14.3%), 0 events -2026-02-04T18:59:01.812802Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19190/133889 blocks (14.3%), 0 events -2026-02-04T18:59:02.068909Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19200/133889 blocks (14.3%), 0 events -2026-02-04T18:59:02.263440Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19210/133889 blocks (14.3%), 0 events -2026-02-04T18:59:02.373164Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19220/133889 blocks (14.4%), 0 events -2026-02-04T18:59:02.595377Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19230/133889 blocks (14.4%), 0 events -2026-02-04T18:59:02.827409Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19240/133889 blocks (14.4%), 0 events -2026-02-04T18:59:03.060679Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19250/133889 blocks (14.4%), 0 events -2026-02-04T18:59:03.313457Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19260/133889 blocks (14.4%), 0 events -2026-02-04T18:59:03.396249Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19270/133889 blocks (14.4%), 0 events -2026-02-04T18:59:03.611572Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19280/133889 blocks (14.4%), 0 events -2026-02-04T18:59:03.838123Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19290/133889 blocks (14.4%), 0 events -2026-02-04T18:59:03.987857Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19300/133889 blocks (14.4%), 0 events -2026-02-04T18:59:04.238889Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19310/133889 blocks (14.4%), 0 events -2026-02-04T18:59:04.418094Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19320/133889 blocks (14.4%), 0 events -2026-02-04T18:59:04.573866Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19330/133889 blocks (14.4%), 0 events -2026-02-04T18:59:04.789702Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19340/133889 blocks (14.4%), 0 events -2026-02-04T18:59:05.063435Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19350/133889 blocks (14.5%), 0 events -2026-02-04T18:59:05.227176Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19360/133889 blocks (14.5%), 0 events -2026-02-04T18:59:05.441766Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19370/133889 blocks (14.5%), 0 events -2026-02-04T18:59:05.614715Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19380/133889 blocks (14.5%), 0 events -2026-02-04T18:59:05.797449Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19390/133889 blocks (14.5%), 0 events -2026-02-04T18:59:06.056285Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19400/133889 blocks (14.5%), 0 events -2026-02-04T18:59:06.232195Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19410/133889 blocks (14.5%), 0 events -2026-02-04T18:59:06.496566Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19420/133889 blocks (14.5%), 0 events -2026-02-04T18:59:06.638484Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19430/133889 blocks (14.5%), 0 events -2026-02-04T18:59:06.855938Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19440/133889 blocks (14.5%), 0 events -2026-02-04T18:59:07.038014Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19450/133889 blocks (14.5%), 0 events -2026-02-04T18:59:07.217499Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19460/133889 blocks (14.5%), 0 events -2026-02-04T18:59:07.365298Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19470/133889 blocks (14.5%), 0 events -2026-02-04T18:59:07.647246Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19480/133889 blocks (14.5%), 0 events -2026-02-04T18:59:07.793763Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19490/133889 blocks (14.6%), 0 events -2026-02-04T18:59:08.070757Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19500/133889 blocks (14.6%), 0 events -2026-02-04T18:59:08.243191Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19510/133889 blocks (14.6%), 0 events -2026-02-04T18:59:08.443238Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19520/133889 blocks (14.6%), 0 events -2026-02-04T18:59:08.610195Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19530/133889 blocks (14.6%), 0 events -2026-02-04T18:59:08.857820Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19540/133889 blocks (14.6%), 0 events -2026-02-04T18:59:08.987638Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19550/133889 blocks (14.6%), 0 events -2026-02-04T18:59:09.199832Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19560/133889 blocks (14.6%), 0 events -2026-02-04T18:59:09.373802Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19570/133889 blocks (14.6%), 0 events -2026-02-04T18:59:09.639055Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19580/133889 blocks (14.6%), 0 events -2026-02-04T18:59:09.790913Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19590/133889 blocks (14.6%), 0 events -2026-02-04T18:59:10.128955Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19600/133889 blocks (14.6%), 0 events -2026-02-04T18:59:10.169135Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19610/133889 blocks (14.6%), 0 events -2026-02-04T18:59:10.373775Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19620/133889 blocks (14.7%), 0 events -2026-02-04T18:59:10.694050Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19630/133889 blocks (14.7%), 0 events -2026-02-04T18:59:10.795661Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19640/133889 blocks (14.7%), 0 events -2026-02-04T18:59:11.004262Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19650/133889 blocks (14.7%), 0 events -2026-02-04T18:59:11.253503Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19660/133889 blocks (14.7%), 0 events -2026-02-04T18:59:11.429430Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19670/133889 blocks (14.7%), 0 events -2026-02-04T18:59:11.701996Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19680/133889 blocks (14.7%), 0 events -2026-02-04T18:59:11.776828Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19690/133889 blocks (14.7%), 0 events -2026-02-04T18:59:11.979356Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19700/133889 blocks (14.7%), 0 events -2026-02-04T18:59:12.255347Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19710/133889 blocks (14.7%), 0 events -2026-02-04T18:59:12.450510Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19720/133889 blocks (14.7%), 0 events -2026-02-04T18:59:12.639114Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19730/133889 blocks (14.7%), 0 events -2026-02-04T18:59:12.790287Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19740/133889 blocks (14.7%), 0 events -2026-02-04T18:59:13.071962Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19750/133889 blocks (14.8%), 0 events -2026-02-04T18:59:13.167972Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19760/133889 blocks (14.8%), 0 events -2026-02-04T18:59:13.458538Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19770/133889 blocks (14.8%), 0 events -2026-02-04T18:59:13.610331Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19780/133889 blocks (14.8%), 0 events -2026-02-04T18:59:13.849368Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19790/133889 blocks (14.8%), 0 events -2026-02-04T18:59:14.044370Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19800/133889 blocks (14.8%), 0 events -2026-02-04T18:59:14.172038Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19810/133889 blocks (14.8%), 0 events -2026-02-04T18:59:14.457064Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19820/133889 blocks (14.8%), 0 events -2026-02-04T18:59:14.638996Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19830/133889 blocks (14.8%), 0 events -2026-02-04T18:59:14.885686Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19840/133889 blocks (14.8%), 0 events -2026-02-04T18:59:15.063485Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19850/133889 blocks (14.8%), 0 events -2026-02-04T18:59:15.240185Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19860/133889 blocks (14.8%), 0 events -2026-02-04T18:59:15.448240Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19870/133889 blocks (14.8%), 0 events -2026-02-04T18:59:15.608529Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19880/133889 blocks (14.8%), 0 events -2026-02-04T18:59:15.896450Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19890/133889 blocks (14.9%), 0 events -2026-02-04T18:59:16.003034Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19900/133889 blocks (14.9%), 0 events -2026-02-04T18:59:16.233804Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19910/133889 blocks (14.9%), 0 events -2026-02-04T18:59:16.473427Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19920/133889 blocks (14.9%), 0 events -2026-02-04T18:59:16.635684Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19930/133889 blocks (14.9%), 0 events -2026-02-04T18:59:16.766593Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19940/133889 blocks (14.9%), 0 events -2026-02-04T18:59:17.050673Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19950/133889 blocks (14.9%), 0 events -2026-02-04T18:59:17.213986Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19960/133889 blocks (14.9%), 0 events -2026-02-04T18:59:17.499012Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19970/133889 blocks (14.9%), 0 events -2026-02-04T18:59:17.667865Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19980/133889 blocks (14.9%), 0 events -2026-02-04T18:59:17.844272Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 19990/133889 blocks (14.9%), 0 events -2026-02-04T18:59:18.030800Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20000/133889 blocks (14.9%), 0 events -2026-02-04T18:59:18.179502Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20010/133889 blocks (14.9%), 0 events -2026-02-04T18:59:18.366234Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20020/133889 blocks (15.0%), 0 events -2026-02-04T18:59:18.637102Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20030/133889 blocks (15.0%), 0 events -2026-02-04T18:59:18.816596Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20040/133889 blocks (15.0%), 0 events -2026-02-04T18:59:19.042261Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20050/133889 blocks (15.0%), 0 events -2026-02-04T18:59:19.239807Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20060/133889 blocks (15.0%), 0 events -2026-02-04T18:59:19.377761Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20070/133889 blocks (15.0%), 0 events -2026-02-04T18:59:19.597091Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20080/133889 blocks (15.0%), 0 events -2026-02-04T18:59:19.796704Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20090/133889 blocks (15.0%), 0 events -2026-02-04T18:59:20.088002Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20100/133889 blocks (15.0%), 0 events -2026-02-04T18:59:20.231562Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20110/133889 blocks (15.0%), 0 events -2026-02-04T18:59:20.460495Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20120/133889 blocks (15.0%), 0 events -2026-02-04T18:59:20.648798Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20130/133889 blocks (15.0%), 0 events -2026-02-04T18:59:20.797049Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20140/133889 blocks (15.0%), 0 events -2026-02-04T18:59:21.044346Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20150/133889 blocks (15.0%), 0 events -2026-02-04T18:59:21.177179Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20160/133889 blocks (15.1%), 0 events -2026-02-04T18:59:21.460531Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20170/133889 blocks (15.1%), 0 events -2026-02-04T18:59:21.699332Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20180/133889 blocks (15.1%), 0 events -2026-02-04T18:59:21.867522Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20190/133889 blocks (15.1%), 0 events -2026-02-04T18:59:22.000255Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20200/133889 blocks (15.1%), 0 events -2026-02-04T18:59:22.262975Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20210/133889 blocks (15.1%), 0 events -2026-02-04T18:59:22.385296Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20220/133889 blocks (15.1%), 0 events -2026-02-04T18:59:22.565014Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20230/133889 blocks (15.1%), 0 events -2026-02-04T18:59:22.830090Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20240/133889 blocks (15.1%), 0 events -2026-02-04T18:59:22.968894Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20250/133889 blocks (15.1%), 0 events -2026-02-04T18:59:23.274706Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20260/133889 blocks (15.1%), 0 events -2026-02-04T18:59:23.460987Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20270/133889 blocks (15.1%), 0 events -2026-02-04T18:59:23.629009Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20280/133889 blocks (15.1%), 0 events -2026-02-04T18:59:23.791867Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20290/133889 blocks (15.2%), 0 events -2026-02-04T18:59:24.007253Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20300/133889 blocks (15.2%), 0 events -2026-02-04T18:59:24.284763Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20310/133889 blocks (15.2%), 0 events -2026-02-04T18:59:24.446222Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20320/133889 blocks (15.2%), 0 events -2026-02-04T18:59:24.633719Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20330/133889 blocks (15.2%), 0 events -2026-02-04T18:59:24.866522Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20340/133889 blocks (15.2%), 0 events -2026-02-04T18:59:24.994263Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20350/133889 blocks (15.2%), 0 events -2026-02-04T18:59:25.332102Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20360/133889 blocks (15.2%), 0 events -2026-02-04T18:59:25.372361Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20370/133889 blocks (15.2%), 0 events -2026-02-04T18:59:25.570392Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20380/133889 blocks (15.2%), 0 events -2026-02-04T18:59:25.856399Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20390/133889 blocks (15.2%), 0 events -2026-02-04T18:59:25.976352Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20400/133889 blocks (15.2%), 0 events -2026-02-04T18:59:26.180631Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20410/133889 blocks (15.2%), 0 events -2026-02-04T18:59:26.458226Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20420/133889 blocks (15.3%), 0 events -2026-02-04T18:59:26.574413Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20430/133889 blocks (15.3%), 0 events -2026-02-04T18:59:26.810825Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20440/133889 blocks (15.3%), 0 events -2026-02-04T18:59:27.019867Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20450/133889 blocks (15.3%), 0 events -2026-02-04T18:59:27.220579Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20460/133889 blocks (15.3%), 0 events -2026-02-04T18:59:27.476287Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20470/133889 blocks (15.3%), 0 events -2026-02-04T18:59:27.634925Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20480/133889 blocks (15.3%), 0 events -2026-02-04T18:59:27.836535Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20490/133889 blocks (15.3%), 0 events -2026-02-04T18:59:28.034825Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20500/133889 blocks (15.3%), 0 events -2026-02-04T18:59:28.263878Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20510/133889 blocks (15.3%), 0 events -2026-02-04T18:59:28.514135Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20520/133889 blocks (15.3%), 0 events -2026-02-04T18:59:28.609110Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20530/133889 blocks (15.3%), 0 events -2026-02-04T18:59:28.841363Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20540/133889 blocks (15.3%), 0 events -2026-02-04T18:59:29.035359Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20550/133889 blocks (15.3%), 0 events -2026-02-04T18:59:29.176497Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20560/133889 blocks (15.4%), 0 events -2026-02-04T18:59:29.415399Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20570/133889 blocks (15.4%), 0 events -2026-02-04T18:59:29.642656Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20580/133889 blocks (15.4%), 0 events -2026-02-04T18:59:29.840577Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20590/133889 blocks (15.4%), 0 events -2026-02-04T18:59:30.086631Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20600/133889 blocks (15.4%), 0 events -2026-02-04T18:59:30.218754Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20610/133889 blocks (15.4%), 0 events -2026-02-04T18:59:30.409878Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20620/133889 blocks (15.4%), 0 events -2026-02-04T18:59:30.609859Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20630/133889 blocks (15.4%), 0 events -2026-02-04T18:59:30.863354Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20640/133889 blocks (15.4%), 0 events -2026-02-04T18:59:31.100673Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20650/133889 blocks (15.4%), 0 events -2026-02-04T18:59:31.246282Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20660/133889 blocks (15.4%), 0 events -2026-02-04T18:59:31.461556Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20670/133889 blocks (15.4%), 0 events -2026-02-04T18:59:31.656622Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20680/133889 blocks (15.4%), 0 events -2026-02-04T18:59:31.800008Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20690/133889 blocks (15.5%), 0 events -2026-02-04T18:59:32.049432Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20700/133889 blocks (15.5%), 0 events -2026-02-04T18:59:32.241158Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20710/133889 blocks (15.5%), 0 events -2026-02-04T18:59:32.432210Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20720/133889 blocks (15.5%), 0 events -2026-02-04T18:59:32.569100Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20730/133889 blocks (15.5%), 0 events -2026-02-04T18:59:32.780177Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20740/133889 blocks (15.5%), 0 events -2026-02-04T18:59:33.005728Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20750/133889 blocks (15.5%), 0 events -2026-02-04T18:59:33.231894Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20760/133889 blocks (15.5%), 0 events -2026-02-04T18:59:33.446867Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20770/133889 blocks (15.5%), 0 events -2026-02-04T18:59:33.578107Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20780/133889 blocks (15.5%), 0 events -2026-02-04T18:59:33.799993Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20790/133889 blocks (15.5%), 0 events -2026-02-04T18:59:34.028010Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20800/133889 blocks (15.5%), 0 events -2026-02-04T18:59:34.277350Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20810/133889 blocks (15.5%), 0 events -2026-02-04T18:59:34.373035Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20820/133889 blocks (15.5%), 0 events -2026-02-04T18:59:34.590650Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20830/133889 blocks (15.6%), 0 events -2026-02-04T18:59:34.799272Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20840/133889 blocks (15.6%), 0 events -2026-02-04T18:59:35.025280Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20850/133889 blocks (15.6%), 0 events -2026-02-04T18:59:35.327817Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20860/133889 blocks (15.6%), 0 events -2026-02-04T18:59:35.366064Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20870/133889 blocks (15.6%), 0 events -2026-02-04T18:59:35.588352Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20880/133889 blocks (15.6%), 0 events -2026-02-04T18:59:35.849466Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20890/133889 blocks (15.6%), 0 events -2026-02-04T18:59:35.994058Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20900/133889 blocks (15.6%), 0 events -2026-02-04T18:59:36.185776Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20910/133889 blocks (15.6%), 0 events -2026-02-04T18:59:36.382675Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20920/133889 blocks (15.6%), 0 events -2026-02-04T18:59:36.633242Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20930/133889 blocks (15.6%), 0 events -2026-02-04T18:59:36.866950Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20940/133889 blocks (15.6%), 0 events -2026-02-04T18:59:37.007785Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20950/133889 blocks (15.6%), 0 events -2026-02-04T18:59:37.217480Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20960/133889 blocks (15.7%), 0 events -2026-02-04T18:59:37.439141Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20970/133889 blocks (15.7%), 0 events -2026-02-04T18:59:37.586664Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20980/133889 blocks (15.7%), 0 events -2026-02-04T18:59:37.768114Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 20990/133889 blocks (15.7%), 0 events -2026-02-04T18:59:37.988038Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21000/133889 blocks (15.7%), 0 events -2026-02-04T18:59:38.232702Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21010/133889 blocks (15.7%), 0 events -2026-02-04T18:59:38.484414Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21020/133889 blocks (15.7%), 0 events -2026-02-04T18:59:38.614701Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21030/133889 blocks (15.7%), 0 events -2026-02-04T18:59:38.771325Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21040/133889 blocks (15.7%), 0 events -2026-02-04T18:59:39.012538Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21050/133889 blocks (15.7%), 0 events -2026-02-04T18:59:39.203847Z  INFO verbeth_indexer::indexer::backfill[2m: Backfill progress: 21060/133889 blocks (15.7%), 0 events -2026-02-04T18:59:39.372601Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21070/133889 blocks (15.7%), 0 events -2026-02-04T18:59:39.622020Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21080/133889 blocks (15.7%), 0 events -2026-02-04T18:59:39.842761Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21090/133889 blocks (15.8%), 0 events -2026-02-04T18:59:40.056296Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21100/133889 blocks (15.8%), 0 events -2026-02-04T18:59:40.242333Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21110/133889 blocks (15.8%), 0 events -2026-02-04T18:59:40.428639Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21120/133889 blocks (15.8%), 0 events -2026-02-04T18:59:40.585301Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21130/133889 blocks (15.8%), 0 events -2026-02-04T18:59:40.805583Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21140/133889 blocks (15.8%), 0 events -2026-02-04T18:59:41.093073Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21150/133889 blocks (15.8%), 0 events -2026-02-04T18:59:41.191158Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21160/133889 blocks (15.8%), 0 events -2026-02-04T18:59:41.465182Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21170/133889 blocks (15.8%), 0 events -2026-02-04T18:59:41.617133Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21180/133889 blocks (15.8%), 0 events -2026-02-04T18:59:41.827035Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21190/133889 blocks (15.8%), 0 events -2026-02-04T18:59:41.982561Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21200/133889 blocks (15.8%), 0 events -2026-02-04T18:59:42.215272Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21210/133889 blocks (15.8%), 0 events -2026-02-04T18:59:42.432499Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21220/133889 blocks (15.8%), 0 events -2026-02-04T18:59:42.667027Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21230/133889 blocks (15.9%), 0 events -2026-02-04T18:59:42.769753Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21240/133889 blocks (15.9%), 0 events -2026-02-04T18:59:43.027513Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21250/133889 blocks (15.9%), 0 events -2026-02-04T18:59:43.198268Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21260/133889 blocks (15.9%), 0 events -2026-02-04T18:59:43.399733Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21270/133889 blocks (15.9%), 0 events -2026-02-04T18:59:43.577736Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21280/133889 blocks (15.9%), 0 events -2026-02-04T18:59:43.778754Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21290/133889 blocks (15.9%), 0 events -2026-02-04T18:59:44.051188Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21300/133889 blocks (15.9%), 0 events -2026-02-04T18:59:44.239189Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21310/133889 blocks (15.9%), 0 events -2026-02-04T18:59:44.373177Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21320/133889 blocks (15.9%), 0 events -2026-02-04T18:59:44.731563Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21330/133889 blocks (15.9%), 0 events -2026-02-04T18:59:44.773048Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21340/133889 blocks (15.9%), 0 events -2026-02-04T18:59:44.974757Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21350/133889 blocks (15.9%), 0 events -2026-02-04T18:59:45.255874Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21360/133889 blocks (16.0%), 0 events -2026-02-04T18:59:45.419668Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21370/133889 blocks (16.0%), 0 events -2026-02-04T18:59:45.601846Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21380/133889 blocks (16.0%), 0 events -2026-02-04T18:59:45.819051Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21390/133889 blocks (16.0%), 0 events -2026-02-04T18:59:46.057107Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21400/133889 blocks (16.0%), 0 events -2026-02-04T18:59:46.303146Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21410/133889 blocks (16.0%), 0 events -2026-02-04T18:59:46.364066Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21420/133889 blocks (16.0%), 0 events -2026-02-04T18:59:46.645426Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21430/133889 blocks (16.0%), 0 events -2026-02-04T18:59:46.860390Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21440/133889 blocks (16.0%), 0 events -2026-02-04T18:59:46.998503Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21450/133889 blocks (16.0%), 0 events -2026-02-04T18:59:47.186723Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21460/133889 blocks (16.0%), 0 events -2026-02-04T18:59:47.392474Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21470/133889 blocks (16.0%), 0 events -2026-02-04T18:59:47.653871Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21480/133889 blocks (16.0%), 0 events -2026-02-04T18:59:47.902779Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21490/133889 blocks (16.0%), 0 events -2026-02-04T18:59:47.993448Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21500/133889 blocks (16.1%), 0 events -2026-02-04T18:59:48.239308Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21510/133889 blocks (16.1%), 0 events -2026-02-04T18:59:48.433647Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21520/133889 blocks (16.1%), 0 events -2026-02-04T18:59:48.588955Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21530/133889 blocks (16.1%), 0 events -2026-02-04T18:59:48.923552Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21540/133889 blocks (16.1%), 0 events -2026-02-04T18:59:48.961099Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21550/133889 blocks (16.1%), 0 events -2026-02-04T18:59:49.238740Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21560/133889 blocks (16.1%), 0 events -2026-02-04T18:59:49.482991Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21570/133889 blocks (16.1%), 0 events -2026-02-04T18:59:49.644255Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21580/133889 blocks (16.1%), 0 events -2026-02-04T18:59:49.818337Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21590/133889 blocks (16.1%), 0 events -2026-02-04T18:59:50.014600Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21600/133889 blocks (16.1%), 0 events -2026-02-04T18:59:50.261315Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21610/133889 blocks (16.1%), 0 events -2026-02-04T18:59:50.395471Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21620/133889 blocks (16.1%), 0 events -2026-02-04T18:59:50.664030Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21630/133889 blocks (16.2%), 0 events -2026-02-04T18:59:50.821760Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21640/133889 blocks (16.2%), 0 events -2026-02-04T18:59:51.058003Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21650/133889 blocks (16.2%), 0 events -2026-02-04T18:59:51.261650Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21660/133889 blocks (16.2%), 0 events -2026-02-04T18:59:51.391541Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21670/133889 blocks (16.2%), 0 events -2026-02-04T18:59:51.648119Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21680/133889 blocks (16.2%), 0 events -2026-02-04T18:59:51.814922Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21690/133889 blocks (16.2%), 0 events -2026-02-04T18:59:51.964844Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21700/133889 blocks (16.2%), 0 events -2026-02-04T18:59:52.244923Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21710/133889 blocks (16.2%), 0 events -2026-02-04T18:59:52.418008Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21720/133889 blocks (16.2%), 0 events -2026-02-04T18:59:52.624552Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21730/133889 blocks (16.2%), 0 events -2026-02-04T18:59:52.844165Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21740/133889 blocks (16.2%), 0 events -2026-02-04T18:59:53.118122Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21750/133889 blocks (16.2%), 0 events -2026-02-04T18:59:53.179752Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21760/133889 blocks (16.3%), 0 events -2026-02-04T18:59:53.446605Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21770/133889 blocks (16.3%), 0 events -2026-02-04T18:59:53.644196Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21780/133889 blocks (16.3%), 0 events -2026-02-04T18:59:53.789344Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21790/133889 blocks (16.3%), 0 events -2026-02-04T18:59:53.994202Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21800/133889 blocks (16.3%), 0 events -2026-02-04T18:59:54.249688Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21810/133889 blocks (16.3%), 0 events -2026-02-04T18:59:54.419876Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21820/133889 blocks (16.3%), 0 events -2026-02-04T18:59:54.564957Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21830/133889 blocks (16.3%), 0 events -2026-02-04T18:59:54.841332Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21840/133889 blocks (16.3%), 0 events -2026-02-04T18:59:54.982658Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21850/133889 blocks (16.3%), 0 events -2026-02-04T18:59:55.251341Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21860/133889 blocks (16.3%), 0 events -2026-02-04T18:59:55.389068Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21870/133889 blocks (16.3%), 0 events -2026-02-04T18:59:55.739879Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21880/133889 blocks (16.3%), 0 events -2026-02-04T18:59:55.781823Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21890/133889 blocks (16.3%), 0 events -2026-02-04T18:59:55.981558Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21900/133889 blocks (16.4%), 0 events -2026-02-04T18:59:56.301121Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21910/133889 blocks (16.4%), 0 events -2026-02-04T18:59:56.434361Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21920/133889 blocks (16.4%), 0 events -2026-02-04T18:59:56.645129Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21930/133889 blocks (16.4%), 0 events -2026-02-04T18:59:56.846983Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21940/133889 blocks (16.4%), 0 events -2026-02-04T18:59:56.985783Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21950/133889 blocks (16.4%), 0 events -2026-02-04T18:59:57.310426Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21960/133889 blocks (16.4%), 0 events -2026-02-04T18:59:57.381479Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21970/133889 blocks (16.4%), 0 events -2026-02-04T18:59:57.610408Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21980/133889 blocks (16.4%), 0 events -2026-02-04T18:59:57.871058Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 21990/133889 blocks (16.4%), 0 events -2026-02-04T18:59:58.053176Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22000/133889 blocks (16.4%), 0 events -2026-02-04T18:59:58.227375Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22010/133889 blocks (16.4%), 0 events -2026-02-04T18:59:58.451280Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22020/133889 blocks (16.4%), 0 events -2026-02-04T18:59:58.590606Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22030/133889 blocks (16.5%), 0 events -2026-02-04T18:59:58.917085Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22040/133889 blocks (16.5%), 0 events -2026-02-04T18:59:58.990249Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22050/133889 blocks (16.5%), 0 events -2026-02-04T18:59:59.192608Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22060/133889 blocks (16.5%), 0 events -2026-02-04T18:59:59.438520Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22070/133889 blocks (16.5%), 0 events -2026-02-04T18:59:59.619692Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22080/133889 blocks (16.5%), 0 events -2026-02-04T18:59:59.798005Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22090/133889 blocks (16.5%), 0 events -2026-02-04T19:00:00.015933Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22100/133889 blocks (16.5%), 0 events -2026-02-04T19:00:00.266432Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22110/133889 blocks (16.5%), 0 events -2026-02-04T19:00:00.459291Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22120/133889 blocks (16.5%), 0 events -2026-02-04T19:00:00.665445Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22130/133889 blocks (16.5%), 0 events -2026-02-04T19:00:00.829338Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22140/133889 blocks (16.5%), 0 events -2026-02-04T19:00:01.032054Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22150/133889 blocks (16.5%), 0 events -2026-02-04T19:00:01.278363Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22160/133889 blocks (16.6%), 0 events -2026-02-04T19:00:01.506343Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22170/133889 blocks (16.6%), 0 events -2026-02-04T19:00:01.592065Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22180/133889 blocks (16.6%), 0 events -2026-02-04T19:00:01.813121Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22190/133889 blocks (16.6%), 0 events -2026-02-04T19:00:02.095760Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22200/133889 blocks (16.6%), 0 events -2026-02-04T19:00:02.191881Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22210/133889 blocks (16.6%), 0 events -2026-02-04T19:00:02.464169Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22220/133889 blocks (16.6%), 0 events -2026-02-04T19:00:02.593788Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22230/133889 blocks (16.6%), 0 events -2026-02-04T19:00:02.771315Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22240/133889 blocks (16.6%), 0 events -2026-02-04T19:00:02.984709Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22250/133889 blocks (16.6%), 0 events -2026-02-04T19:00:03.231537Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22260/133889 blocks (16.6%), 0 events -2026-02-04T19:00:03.366177Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22270/133889 blocks (16.6%), 0 events -2026-02-04T19:00:03.634296Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22280/133889 blocks (16.6%), 0 events -2026-02-04T19:00:03.850411Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22290/133889 blocks (16.6%), 0 events -2026-02-04T19:00:04.132484Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22300/133889 blocks (16.7%), 0 events -2026-02-04T19:00:04.192005Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22310/133889 blocks (16.7%), 0 events -2026-02-04T19:00:04.386665Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22320/133889 blocks (16.7%), 0 events -2026-02-04T19:00:04.697765Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22330/133889 blocks (16.7%), 0 events -2026-02-04T19:00:04.833783Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22340/133889 blocks (16.7%), 0 events -2026-02-04T19:00:05.020761Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22350/133889 blocks (16.7%), 0 events -2026-02-04T19:00:05.210151Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22360/133889 blocks (16.7%), 0 events -2026-02-04T19:00:05.410415Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22370/133889 blocks (16.7%), 0 events -2026-02-04T19:00:05.578179Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22380/133889 blocks (16.7%), 0 events -2026-02-04T19:00:05.805116Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22390/133889 blocks (16.7%), 0 events -2026-02-04T19:00:06.059682Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22400/133889 blocks (16.7%), 0 events -2026-02-04T19:00:06.267307Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22410/133889 blocks (16.7%), 0 events -2026-02-04T19:00:06.420214Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22420/133889 blocks (16.7%), 0 events -2026-02-04T19:00:06.575302Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22430/133889 blocks (16.8%), 0 events -2026-02-04T19:00:06.846269Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22440/133889 blocks (16.8%), 0 events -2026-02-04T19:00:07.016063Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22450/133889 blocks (16.8%), 0 events -2026-02-04T19:00:07.309147Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22460/133889 blocks (16.8%), 0 events -2026-02-04T19:00:07.393073Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22470/133889 blocks (16.8%), 0 events -2026-02-04T19:00:07.632214Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22480/133889 blocks (16.8%), 0 events -2026-02-04T19:00:07.843685Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22490/133889 blocks (16.8%), 0 events -2026-02-04T19:00:08.027817Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22500/133889 blocks (16.8%), 0 events -2026-02-04T19:00:08.321795Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22510/133889 blocks (16.8%), 0 events -2026-02-04T19:00:08.357435Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22520/133889 blocks (16.8%), 0 events -2026-02-04T19:00:08.664356Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22530/133889 blocks (16.8%), 0 events -2026-02-04T19:00:08.846317Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22540/133889 blocks (16.8%), 0 events -2026-02-04T19:00:09.067590Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22550/133889 blocks (16.8%), 0 events -2026-02-04T19:00:09.197593Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22560/133889 blocks (16.8%), 0 events -2026-02-04T19:00:09.470091Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22570/133889 blocks (16.9%), 0 events -2026-02-04T19:00:09.605909Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22580/133889 blocks (16.9%), 0 events -2026-02-04T19:00:09.926796Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22590/133889 blocks (16.9%), 0 events -2026-02-04T19:00:09.965861Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22600/133889 blocks (16.9%), 0 events -2026-02-04T19:00:10.255462Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22610/133889 blocks (16.9%), 0 events -2026-02-04T19:00:10.451938Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22620/133889 blocks (16.9%), 0 events -2026-02-04T19:00:10.649527Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22630/133889 blocks (16.9%), 0 events -2026-02-04T19:00:10.787529Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22640/133889 blocks (16.9%), 0 events -2026-02-04T19:00:11.045890Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22650/133889 blocks (16.9%), 0 events -2026-02-04T19:00:11.251455Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22660/133889 blocks (16.9%), 0 events -2026-02-04T19:00:11.373927Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22670/133889 blocks (16.9%), 0 events -2026-02-04T19:00:11.596454Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22680/133889 blocks (16.9%), 0 events -2026-02-04T19:00:11.802240Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22690/133889 blocks (16.9%), 0 events -2026-02-04T19:00:12.044694Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22700/133889 blocks (17.0%), 0 events -2026-02-04T19:00:12.213827Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22710/133889 blocks (17.0%), 0 events -2026-02-04T19:00:12.515685Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22720/133889 blocks (17.0%), 0 events -2026-02-04T19:00:12.594544Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22730/133889 blocks (17.0%), 0 events -2026-02-04T19:00:12.812933Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22740/133889 blocks (17.0%), 0 events -2026-02-04T19:00:13.040357Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22750/133889 blocks (17.0%), 0 events -2026-02-04T19:00:13.186024Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22760/133889 blocks (17.0%), 0 events -2026-02-04T19:00:13.565389Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22770/133889 blocks (17.0%), 0 events -2026-02-04T19:00:13.607115Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22780/133889 blocks (17.0%), 0 events -2026-02-04T19:00:13.789606Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22790/133889 blocks (17.0%), 0 events -2026-02-04T19:00:13.994762Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22800/133889 blocks (17.0%), 0 events -2026-02-04T19:00:14.229943Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22810/133889 blocks (17.0%), 0 events -2026-02-04T19:00:14.397292Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22820/133889 blocks (17.0%), 0 events -2026-02-04T19:00:14.648756Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22830/133889 blocks (17.1%), 0 events -2026-02-04T19:00:14.793741Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22840/133889 blocks (17.1%), 0 events -2026-02-04T19:00:15.011693Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22850/133889 blocks (17.1%), 0 events -2026-02-04T19:00:15.228834Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22860/133889 blocks (17.1%), 0 events -2026-02-04T19:00:15.426485Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22870/133889 blocks (17.1%), 0 events -2026-02-04T19:00:15.710183Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22880/133889 blocks (17.1%), 0 events -2026-02-04T19:00:15.771881Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22890/133889 blocks (17.1%), 0 events -2026-02-04T19:00:16.041188Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22900/133889 blocks (17.1%), 0 events -2026-02-04T19:00:16.218508Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22910/133889 blocks (17.1%), 0 events -2026-02-04T19:00:16.435440Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22920/133889 blocks (17.1%), 0 events -2026-02-04T19:00:16.612942Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22930/133889 blocks (17.1%), 0 events -2026-02-04T19:00:16.806656Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22940/133889 blocks (17.1%), 0 events -2026-02-04T19:00:17.072985Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22950/133889 blocks (17.1%), 0 events -2026-02-04T19:00:17.270930Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22960/133889 blocks (17.1%), 0 events -2026-02-04T19:00:17.451719Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22970/133889 blocks (17.2%), 0 events -2026-02-04T19:00:17.598758Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22980/133889 blocks (17.2%), 0 events -2026-02-04T19:00:17.838325Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 22990/133889 blocks (17.2%), 0 events -2026-02-04T19:00:17.982993Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23000/133889 blocks (17.2%), 0 events -2026-02-04T19:00:18.187156Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23010/133889 blocks (17.2%), 0 events -2026-02-04T19:00:18.440316Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23020/133889 blocks (17.2%), 0 events -2026-02-04T19:00:18.661054Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23030/133889 blocks (17.2%), 0 events -2026-02-04T19:00:18.842916Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23040/133889 blocks (17.2%), 0 events -2026-02-04T19:00:18.982927Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23050/133889 blocks (17.2%), 0 events -2026-02-04T19:00:19.330118Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23060/133889 blocks (17.2%), 0 events -2026-02-04T19:00:19.373733Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23070/133889 blocks (17.2%), 0 events -2026-02-04T19:00:19.620456Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23080/133889 blocks (17.2%), 0 events -2026-02-04T19:00:19.889304Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23090/133889 blocks (17.2%), 0 events -2026-02-04T19:00:19.978681Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23100/133889 blocks (17.3%), 0 events -2026-02-04T19:00:20.190654Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23110/133889 blocks (17.3%), 0 events -2026-02-04T19:00:20.462557Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23120/133889 blocks (17.3%), 0 events -2026-02-04T19:00:20.602486Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23130/133889 blocks (17.3%), 0 events -2026-02-04T19:00:20.783927Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23140/133889 blocks (17.3%), 0 events -2026-02-04T19:00:20.978367Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23150/133889 blocks (17.3%), 0 events -2026-02-04T19:00:21.191797Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23160/133889 blocks (17.3%), 0 events -2026-02-04T19:00:21.466176Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23170/133889 blocks (17.3%), 0 events -2026-02-04T19:00:21.620223Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23180/133889 blocks (17.3%), 0 events -2026-02-04T19:00:21.953043Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23190/133889 blocks (17.3%), 0 events -2026-02-04T19:00:22.029286Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23200/133889 blocks (17.3%), 0 events -2026-02-04T19:00:22.237005Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23210/133889 blocks (17.3%), 0 events -2026-02-04T19:00:22.376222Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23220/133889 blocks (17.3%), 0 events -2026-02-04T19:00:22.639356Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23230/133889 blocks (17.3%), 0 events -2026-02-04T19:00:22.851607Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23240/133889 blocks (17.4%), 0 events -2026-02-04T19:00:23.042166Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23250/133889 blocks (17.4%), 0 events -2026-02-04T19:00:23.204344Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23260/133889 blocks (17.4%), 0 events -2026-02-04T19:00:23.526134Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23270/133889 blocks (17.4%), 0 events -2026-02-04T19:00:23.589898Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23280/133889 blocks (17.4%), 0 events -2026-02-04T19:00:23.819699Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23290/133889 blocks (17.4%), 0 events -2026-02-04T19:00:24.083788Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23300/133889 blocks (17.4%), 0 events -2026-02-04T19:00:24.200038Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23310/133889 blocks (17.4%), 0 events -2026-02-04T19:00:24.439312Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23320/133889 blocks (17.4%), 0 events -2026-02-04T19:00:24.608688Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23330/133889 blocks (17.4%), 0 events -2026-02-04T19:00:24.795209Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23340/133889 blocks (17.4%), 0 events -2026-02-04T19:00:25.131239Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23350/133889 blocks (17.4%), 0 events -2026-02-04T19:00:25.171933Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23360/133889 blocks (17.4%), 0 events -2026-02-04T19:00:25.372092Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23370/133889 blocks (17.5%), 0 events -2026-02-04T19:00:25.653292Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23380/133889 blocks (17.5%), 0 events -2026-02-04T19:00:25.847099Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23390/133889 blocks (17.5%), 0 events -2026-02-04T19:00:26.147176Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23400/133889 blocks (17.5%), 0 events -2026-02-04T19:00:26.184063Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23410/133889 blocks (17.5%), 0 events -2026-02-04T19:00:26.365702Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23420/133889 blocks (17.5%), 0 events -2026-02-04T19:00:26.573828Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23430/133889 blocks (17.5%), 0 events -2026-02-04T19:00:26.808406Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23440/133889 blocks (17.5%), 0 events -2026-02-04T19:00:26.988285Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23450/133889 blocks (17.5%), 0 events -2026-02-04T19:00:27.263299Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23460/133889 blocks (17.5%), 0 events -2026-02-04T19:00:27.386215Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23470/133889 blocks (17.5%), 0 events -2026-02-04T19:00:27.574313Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23480/133889 blocks (17.5%), 0 events -2026-02-04T19:00:27.774614Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23490/133889 blocks (17.5%), 0 events -2026-02-04T19:00:27.967059Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23500/133889 blocks (17.6%), 0 events -2026-02-04T19:00:28.277245Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23510/133889 blocks (17.6%), 0 events -2026-02-04T19:00:28.402160Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23520/133889 blocks (17.6%), 0 events -2026-02-04T19:00:28.629963Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23530/133889 blocks (17.6%), 0 events -2026-02-04T19:00:28.870544Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23540/133889 blocks (17.6%), 0 events -2026-02-04T19:00:29.015678Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23550/133889 blocks (17.6%), 0 events -2026-02-04T19:00:29.189881Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23560/133889 blocks (17.6%), 0 events -2026-02-04T19:00:29.379739Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23570/133889 blocks (17.6%), 0 events -2026-02-04T19:00:29.577809Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23580/133889 blocks (17.6%), 0 events -2026-02-04T19:00:29.848657Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23590/133889 blocks (17.6%), 0 events -2026-02-04T19:00:29.972600Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23600/133889 blocks (17.6%), 0 events -2026-02-04T19:00:30.242801Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23610/133889 blocks (17.6%), 0 events -2026-02-04T19:00:30.403960Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23620/133889 blocks (17.6%), 0 events -2026-02-04T19:00:30.613856Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23630/133889 blocks (17.6%), 0 events -2026-02-04T19:00:30.865527Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23640/133889 blocks (17.7%), 0 events -2026-02-04T19:00:30.974724Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23650/133889 blocks (17.7%), 0 events -2026-02-04T19:00:31.266725Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23660/133889 blocks (17.7%), 0 events -2026-02-04T19:00:31.423749Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23670/133889 blocks (17.7%), 0 events -2026-02-04T19:00:31.634514Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23680/133889 blocks (17.7%), 0 events -2026-02-04T19:00:31.915514Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23690/133889 blocks (17.7%), 0 events -2026-02-04T19:00:31.973085Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23700/133889 blocks (17.7%), 0 events -2026-02-04T19:00:32.190831Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23710/133889 blocks (17.7%), 0 events -2026-02-04T19:00:32.473411Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23720/133889 blocks (17.7%), 0 events -2026-02-04T19:00:32.580780Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23730/133889 blocks (17.7%), 0 events -2026-02-04T19:00:32.794507Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23740/133889 blocks (17.7%), 0 events -2026-02-04T19:00:33.034665Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23750/133889 blocks (17.7%), 0 events -2026-02-04T19:00:33.206768Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23760/133889 blocks (17.7%), 0 events -2026-02-04T19:00:33.487120Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23770/133889 blocks (17.8%), 0 events -2026-02-04T19:00:33.582504Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23780/133889 blocks (17.8%), 0 events -2026-02-04T19:00:33.796052Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23790/133889 blocks (17.8%), 0 events -2026-02-04T19:00:34.052494Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23800/133889 blocks (17.8%), 0 events -2026-02-04T19:00:34.176765Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23810/133889 blocks (17.8%), 0 events -2026-02-04T19:00:34.419769Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23820/133889 blocks (17.8%), 0 events -2026-02-04T19:00:34.639073Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23830/133889 blocks (17.8%), 0 events -2026-02-04T19:00:34.776305Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23840/133889 blocks (17.8%), 0 events -2026-02-04T19:00:35.099007Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23850/133889 blocks (17.8%), 0 events -2026-02-04T19:00:35.261141Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23860/133889 blocks (17.8%), 0 events -2026-02-04T19:00:35.397939Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23870/133889 blocks (17.8%), 0 events -2026-02-04T19:00:35.667056Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23880/133889 blocks (17.8%), 0 events -2026-02-04T19:00:35.828892Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23890/133889 blocks (17.8%), 0 events -2026-02-04T19:00:35.981044Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23900/133889 blocks (17.8%), 0 events -2026-02-04T19:00:36.179357Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23910/133889 blocks (17.9%), 0 events -2026-02-04T19:00:36.421857Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23920/133889 blocks (17.9%), 0 events -2026-02-04T19:00:36.665827Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23930/133889 blocks (17.9%), 0 events -2026-02-04T19:00:36.846136Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23940/133889 blocks (17.9%), 0 events -2026-02-04T19:00:37.060225Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23950/133889 blocks (17.9%), 0 events -2026-02-04T19:00:37.207936Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23960/133889 blocks (17.9%), 0 events -2026-02-04T19:00:37.399581Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23970/133889 blocks (17.9%), 0 events -2026-02-04T19:00:37.583051Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23980/133889 blocks (17.9%), 0 events -2026-02-04T19:00:37.785226Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 23990/133889 blocks (17.9%), 0 events -2026-02-04T19:00:38.035225Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24000/133889 blocks (17.9%), 0 events -2026-02-04T19:00:38.235293Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24010/133889 blocks (17.9%), 0 events -2026-02-04T19:00:38.416382Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24020/133889 blocks (17.9%), 0 events -2026-02-04T19:00:38.609284Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24030/133889 blocks (17.9%), 0 events -2026-02-04T19:00:38.791302Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24040/133889 blocks (18.0%), 0 events -2026-02-04T19:00:39.042500Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24050/133889 blocks (18.0%), 0 events -2026-02-04T19:00:39.253509Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24060/133889 blocks (18.0%), 0 events -2026-02-04T19:00:39.373715Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24070/133889 blocks (18.0%), 0 events -2026-02-04T19:00:39.607200Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24080/133889 blocks (18.0%), 0 events -2026-02-04T19:00:39.815932Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24090/133889 blocks (18.0%), 0 events -2026-02-04T19:00:40.030775Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24100/133889 blocks (18.0%), 0 events -2026-02-04T19:00:40.347159Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24110/133889 blocks (18.0%), 0 events -2026-02-04T19:00:40.384150Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24120/133889 blocks (18.0%), 0 events -2026-02-04T19:00:40.641686Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24130/133889 blocks (18.0%), 0 events -2026-02-04T19:00:40.900284Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24140/133889 blocks (18.0%), 0 events -2026-02-04T19:00:41.049832Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24150/133889 blocks (18.0%), 0 events -2026-02-04T19:00:41.240249Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24160/133889 blocks (18.0%), 0 events -2026-02-04T19:00:41.453844Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24170/133889 blocks (18.1%), 0 events -2026-02-04T19:00:41.595027Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24180/133889 blocks (18.1%), 0 events -2026-02-04T19:00:41.874450Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24190/133889 blocks (18.1%), 0 events -2026-02-04T19:00:42.010537Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24200/133889 blocks (18.1%), 0 events -2026-02-04T19:00:42.261926Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24210/133889 blocks (18.1%), 0 events -2026-02-04T19:00:42.427034Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24220/133889 blocks (18.1%), 0 events -2026-02-04T19:00:42.625064Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24230/133889 blocks (18.1%), 0 events -2026-02-04T19:00:42.777817Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24240/133889 blocks (18.1%), 0 events -2026-02-04T19:00:43.020944Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24250/133889 blocks (18.1%), 0 events -2026-02-04T19:00:43.187981Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24260/133889 blocks (18.1%), 0 events -2026-02-04T19:00:43.490985Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24270/133889 blocks (18.1%), 0 events -2026-02-04T19:00:43.608419Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24280/133889 blocks (18.1%), 0 events -2026-02-04T19:00:43.864176Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24290/133889 blocks (18.1%), 0 events -2026-02-04T19:00:44.039694Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24300/133889 blocks (18.1%), 0 events -2026-02-04T19:00:44.267967Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24310/133889 blocks (18.2%), 0 events -2026-02-04T19:00:44.495742Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24320/133889 blocks (18.2%), 0 events -2026-02-04T19:00:44.585059Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24330/133889 blocks (18.2%), 0 events -2026-02-04T19:00:44.779816Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24340/133889 blocks (18.2%), 0 events -2026-02-04T19:00:45.062352Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24350/133889 blocks (18.2%), 0 events -2026-02-04T19:00:45.250323Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24360/133889 blocks (18.2%), 0 events -2026-02-04T19:00:45.381258Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24370/133889 blocks (18.2%), 0 events -2026-02-04T19:00:45.633238Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24380/133889 blocks (18.2%), 0 events -2026-02-04T19:00:45.782796Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24390/133889 blocks (18.2%), 0 events -2026-02-04T19:00:46.099746Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24400/133889 blocks (18.2%), 0 events -2026-02-04T19:00:46.226094Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24410/133889 blocks (18.2%), 0 events -2026-02-04T19:00:46.360745Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24420/133889 blocks (18.2%), 0 events -2026-02-04T19:00:46.661473Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24430/133889 blocks (18.2%), 0 events -2026-02-04T19:00:46.831928Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24440/133889 blocks (18.3%), 0 events -2026-02-04T19:00:47.025689Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24450/133889 blocks (18.3%), 0 events -2026-02-04T19:00:47.191080Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24460/133889 blocks (18.3%), 0 events -2026-02-04T19:00:47.476486Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24470/133889 blocks (18.3%), 0 events -2026-02-04T19:00:47.640287Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24480/133889 blocks (18.3%), 0 events -2026-02-04T19:00:47.872899Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24490/133889 blocks (18.3%), 0 events -2026-02-04T19:00:48.044387Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24500/133889 blocks (18.3%), 0 events -2026-02-04T19:00:48.227006Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24510/133889 blocks (18.3%), 0 events -2026-02-04T19:00:48.429234Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24520/133889 blocks (18.3%), 0 events -2026-02-04T19:00:48.581893Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24530/133889 blocks (18.3%), 0 events -2026-02-04T19:00:48.792090Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24540/133889 blocks (18.3%), 0 events -2026-02-04T19:00:49.015280Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24550/133889 blocks (18.3%), 0 events -2026-02-04T19:00:49.246953Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24560/133889 blocks (18.3%), 0 events -2026-02-04T19:00:49.452346Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24570/133889 blocks (18.4%), 0 events -2026-02-04T19:00:49.634573Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24580/133889 blocks (18.4%), 0 events -2026-02-04T19:00:49.771561Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24590/133889 blocks (18.4%), 0 events -2026-02-04T19:00:50.020874Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24600/133889 blocks (18.4%), 0 events -2026-02-04T19:00:50.296415Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24610/133889 blocks (18.4%), 0 events -2026-02-04T19:00:50.429069Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24620/133889 blocks (18.4%), 0 events -2026-02-04T19:00:50.626578Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24630/133889 blocks (18.4%), 0 events -2026-02-04T19:00:50.857671Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24640/133889 blocks (18.4%), 0 events -2026-02-04T19:00:51.051373Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24650/133889 blocks (18.4%), 0 events -2026-02-04T19:00:51.196831Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24660/133889 blocks (18.4%), 0 events -2026-02-04T19:00:51.404139Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24670/133889 blocks (18.4%), 0 events -2026-02-04T19:00:51.651882Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24680/133889 blocks (18.4%), 0 events -2026-02-04T19:00:51.836647Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24690/133889 blocks (18.4%), 0 events -2026-02-04T19:00:52.039657Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24700/133889 blocks (18.4%), 0 events -2026-02-04T19:00:52.206948Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24710/133889 blocks (18.5%), 0 events -2026-02-04T19:00:52.404487Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24720/133889 blocks (18.5%), 0 events -2026-02-04T19:00:52.621348Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24730/133889 blocks (18.5%), 0 events -2026-02-04T19:00:52.917614Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24740/133889 blocks (18.5%), 0 events -2026-02-04T19:00:52.970361Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24750/133889 blocks (18.5%), 0 events -2026-02-04T19:00:53.262473Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24760/133889 blocks (18.5%), 0 events -2026-02-04T19:00:53.441319Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24770/133889 blocks (18.5%), 0 events -2026-02-04T19:00:53.588349Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24780/133889 blocks (18.5%), 0 events -2026-02-04T19:00:53.771331Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24790/133889 blocks (18.5%), 0 events -2026-02-04T19:00:54.038395Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24800/133889 blocks (18.5%), 0 events -2026-02-04T19:00:54.499899Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24810/133889 blocks (18.5%), 0 events -2026-02-04T19:00:54.537844Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24820/133889 blocks (18.5%), 0 events -2026-02-04T19:00:54.572690Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24830/133889 blocks (18.5%), 0 events -2026-02-04T19:00:54.812043Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24840/133889 blocks (18.6%), 0 events -2026-02-04T19:00:55.019581Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24850/133889 blocks (18.6%), 0 events -2026-02-04T19:00:55.505641Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24860/133889 blocks (18.6%), 0 events -2026-02-04T19:00:55.545373Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24870/133889 blocks (18.6%), 0 events -2026-02-04T19:00:55.582164Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24880/133889 blocks (18.6%), 0 events -2026-02-04T19:00:55.840239Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24890/133889 blocks (18.6%), 0 events -2026-02-04T19:00:56.062397Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24900/133889 blocks (18.6%), 0 events -2026-02-04T19:00:56.214893Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24910/133889 blocks (18.6%), 0 events -2026-02-04T19:00:56.363732Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24920/133889 blocks (18.6%), 0 events -2026-02-04T19:00:56.638560Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24930/133889 blocks (18.6%), 0 events -2026-02-04T19:00:56.845541Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24940/133889 blocks (18.6%), 0 events -2026-02-04T19:00:57.079344Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24950/133889 blocks (18.6%), 0 events -2026-02-04T19:00:57.221786Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24960/133889 blocks (18.6%), 0 events -2026-02-04T19:00:57.373352Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24970/133889 blocks (18.6%), 0 events -2026-02-04T19:00:57.638572Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24980/133889 blocks (18.7%), 0 events -2026-02-04T19:00:57.767874Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 24990/133889 blocks (18.7%), 0 events -2026-02-04T19:00:58.000942Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25000/133889 blocks (18.7%), 0 events -2026-02-04T19:00:58.257843Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25010/133889 blocks (18.7%), 0 events -2026-02-04T19:00:58.462430Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25020/133889 blocks (18.7%), 0 events -2026-02-04T19:00:58.688120Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25030/133889 blocks (18.7%), 0 events -2026-02-04T19:00:58.853122Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25040/133889 blocks (18.7%), 0 events -2026-02-04T19:00:59.003631Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25050/133889 blocks (18.7%), 0 events -2026-02-04T19:00:59.240520Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25060/133889 blocks (18.7%), 0 events -2026-02-04T19:00:59.403241Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25070/133889 blocks (18.7%), 0 events -2026-02-04T19:00:59.588805Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25080/133889 blocks (18.7%), 0 events -2026-02-04T19:00:59.844753Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25090/133889 blocks (18.7%), 0 events -2026-02-04T19:01:00.038937Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25100/133889 blocks (18.7%), 0 events -2026-02-04T19:01:00.256312Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25110/133889 blocks (18.8%), 0 events -2026-02-04T19:01:00.444055Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25120/133889 blocks (18.8%), 0 events -2026-02-04T19:01:00.651550Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25130/133889 blocks (18.8%), 0 events -2026-02-04T19:01:00.849150Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25140/133889 blocks (18.8%), 0 events -2026-02-04T19:01:01.047799Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25150/133889 blocks (18.8%), 0 events -2026-02-04T19:01:01.509972Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25160/133889 blocks (18.8%), 0 events -2026-02-04T19:01:01.556953Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25170/133889 blocks (18.8%), 0 events -2026-02-04T19:01:01.604130Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25180/133889 blocks (18.8%), 0 events -2026-02-04T19:01:02.029542Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25190/133889 blocks (18.8%), 0 events -2026-02-04T19:01:02.087263Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25200/133889 blocks (18.8%), 0 events -2026-02-04T19:01:02.555433Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25210/133889 blocks (18.8%), 0 events -2026-02-04T19:01:02.591602Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25220/133889 blocks (18.8%), 0 events -2026-02-04T19:01:02.647012Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25230/133889 blocks (18.8%), 0 events -2026-02-04T19:01:03.092143Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25240/133889 blocks (18.9%), 0 events -2026-02-04T19:01:03.131702Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25250/133889 blocks (18.9%), 0 events -2026-02-04T19:01:03.570747Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25260/133889 blocks (18.9%), 0 events -2026-02-04T19:01:03.614823Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25270/133889 blocks (18.9%), 0 events -2026-02-04T19:01:03.654157Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25280/133889 blocks (18.9%), 0 events -2026-02-04T19:01:04.125304Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25290/133889 blocks (18.9%), 0 events -2026-02-04T19:01:04.161862Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25300/133889 blocks (18.9%), 0 events -2026-02-04T19:01:04.618801Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25310/133889 blocks (18.9%), 0 events -2026-02-04T19:01:04.656241Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25320/133889 blocks (18.9%), 0 events -2026-02-04T19:01:04.692598Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25330/133889 blocks (18.9%), 0 events -2026-02-04T19:01:05.140761Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25340/133889 blocks (18.9%), 0 events -2026-02-04T19:01:05.177404Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25350/133889 blocks (18.9%), 0 events -2026-02-04T19:01:05.220169Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25360/133889 blocks (18.9%), 0 events -2026-02-04T19:01:05.502321Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25370/133889 blocks (18.9%), 0 events -2026-02-04T19:01:05.565035Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25380/133889 blocks (19.0%), 0 events -2026-02-04T19:01:05.992883Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25390/133889 blocks (19.0%), 0 events -2026-02-04T19:01:06.057608Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25400/133889 blocks (19.0%), 0 events -2026-02-04T19:01:06.205373Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25410/133889 blocks (19.0%), 0 events -2026-02-04T19:01:06.551593Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25420/133889 blocks (19.0%), 0 events -2026-02-04T19:01:06.587003Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25430/133889 blocks (19.0%), 0 events -2026-02-04T19:01:06.846955Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25440/133889 blocks (19.0%), 0 events -2026-02-04T19:01:07.075546Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25450/133889 blocks (19.0%), 0 events -2026-02-04T19:01:07.225530Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25460/133889 blocks (19.0%), 0 events -2026-02-04T19:01:07.440476Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25470/133889 blocks (19.0%), 0 events -2026-02-04T19:01:07.598637Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25480/133889 blocks (19.0%), 0 events -2026-02-04T19:01:07.846724Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25490/133889 blocks (19.0%), 0 events -2026-02-04T19:01:08.091295Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25500/133889 blocks (19.0%), 0 events -2026-02-04T19:01:08.287097Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25510/133889 blocks (19.1%), 0 events -2026-02-04T19:01:08.406995Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25520/133889 blocks (19.1%), 0 events -2026-02-04T19:01:08.651647Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25530/133889 blocks (19.1%), 0 events -2026-02-04T19:01:08.846083Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25540/133889 blocks (19.1%), 0 events -2026-02-04T19:01:09.137546Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25550/133889 blocks (19.1%), 0 events -2026-02-04T19:01:09.181855Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25560/133889 blocks (19.1%), 0 events -2026-02-04T19:01:09.442196Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25570/133889 blocks (19.1%), 0 events -2026-02-04T19:01:09.697562Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25580/133889 blocks (19.1%), 0 events -2026-02-04T19:01:09.863393Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25590/133889 blocks (19.1%), 0 events -2026-02-04T19:01:10.024947Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25600/133889 blocks (19.1%), 0 events -2026-02-04T19:01:10.228879Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25610/133889 blocks (19.1%), 0 events -2026-02-04T19:01:10.462622Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25620/133889 blocks (19.1%), 0 events -2026-02-04T19:01:10.579555Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25630/133889 blocks (19.1%), 0 events -2026-02-04T19:01:10.864931Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25640/133889 blocks (19.1%), 0 events -2026-02-04T19:01:11.043151Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25650/133889 blocks (19.2%), 0 events -2026-02-04T19:01:11.279255Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25660/133889 blocks (19.2%), 0 events -2026-02-04T19:01:11.460120Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25670/133889 blocks (19.2%), 0 events -2026-02-04T19:01:11.614936Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25680/133889 blocks (19.2%), 0 events -2026-02-04T19:01:11.864117Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25690/133889 blocks (19.2%), 0 events -2026-02-04T19:01:11.998132Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25700/133889 blocks (19.2%), 0 events -2026-02-04T19:01:12.313554Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25710/133889 blocks (19.2%), 0 events -2026-02-04T19:01:12.390460Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25720/133889 blocks (19.2%), 0 events -2026-02-04T19:01:12.641060Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25730/133889 blocks (19.2%), 0 events -2026-02-04T19:01:12.846817Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25740/133889 blocks (19.2%), 0 events -2026-02-04T19:01:13.047175Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25750/133889 blocks (19.2%), 0 events -2026-02-04T19:01:13.332717Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25760/133889 blocks (19.2%), 0 events -2026-02-04T19:01:13.376297Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25770/133889 blocks (19.2%), 0 events -2026-02-04T19:01:13.632422Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25780/133889 blocks (19.3%), 0 events -2026-02-04T19:01:13.857690Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25790/133889 blocks (19.3%), 0 events -2026-02-04T19:01:13.981638Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25800/133889 blocks (19.3%), 0 events -2026-02-04T19:01:14.216389Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25810/133889 blocks (19.3%), 0 events -2026-02-04T19:01:14.418216Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25820/133889 blocks (19.3%), 0 events -2026-02-04T19:01:14.668868Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25830/133889 blocks (19.3%), 0 events -2026-02-04T19:01:14.939070Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25840/133889 blocks (19.3%), 0 events -2026-02-04T19:01:14.979082Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25850/133889 blocks (19.3%), 0 events -2026-02-04T19:01:15.200565Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25860/133889 blocks (19.3%), 0 events -2026-02-04T19:01:15.490118Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25870/133889 blocks (19.3%), 0 events -2026-02-04T19:01:15.677297Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25880/133889 blocks (19.3%), 0 events -2026-02-04T19:01:15.999227Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25890/133889 blocks (19.3%), 0 events -2026-02-04T19:01:16.051771Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25900/133889 blocks (19.3%), 0 events -2026-02-04T19:01:16.277511Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25910/133889 blocks (19.4%), 0 events -2026-02-04T19:01:16.512782Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25920/133889 blocks (19.4%), 0 events -2026-02-04T19:01:16.645956Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25930/133889 blocks (19.4%), 0 events -2026-02-04T19:01:16.778053Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25940/133889 blocks (19.4%), 0 events -2026-02-04T19:01:17.040645Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25950/133889 blocks (19.4%), 0 events -2026-02-04T19:01:17.191169Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25960/133889 blocks (19.4%), 0 events -2026-02-04T19:01:17.558131Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25970/133889 blocks (19.4%), 0 events -2026-02-04T19:01:17.598866Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25980/133889 blocks (19.4%), 0 events -2026-02-04T19:01:17.881534Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 25990/133889 blocks (19.4%), 0 events -2026-02-04T19:01:18.089985Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26000/133889 blocks (19.4%), 0 events -2026-02-04T19:01:18.240145Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26010/133889 blocks (19.4%), 0 events -2026-02-04T19:01:18.456923Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26020/133889 blocks (19.4%), 0 events -2026-02-04T19:01:18.611730Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26030/133889 blocks (19.4%), 0 events -2026-02-04T19:01:18.785110Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26040/133889 blocks (19.4%), 0 events -2026-02-04T19:01:19.098253Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26050/133889 blocks (19.5%), 0 events -2026-02-04T19:01:19.268664Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26060/133889 blocks (19.5%), 0 events -2026-02-04T19:01:19.391966Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26070/133889 blocks (19.5%), 0 events -2026-02-04T19:01:19.661550Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26080/133889 blocks (19.5%), 0 events -2026-02-04T19:01:19.824243Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26090/133889 blocks (19.5%), 0 events -2026-02-04T19:01:20.042127Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26100/133889 blocks (19.5%), 0 events -2026-02-04T19:01:20.219689Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26110/133889 blocks (19.5%), 0 events -2026-02-04T19:01:20.420069Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26120/133889 blocks (19.5%), 0 events -2026-02-04T19:01:20.712180Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26130/133889 blocks (19.5%), 0 events -2026-02-04T19:01:20.855814Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26140/133889 blocks (19.5%), 0 events -2026-02-04T19:01:21.035450Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26150/133889 blocks (19.5%), 0 events -2026-02-04T19:01:21.251838Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26160/133889 blocks (19.5%), 0 events -2026-02-04T19:01:21.390195Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26170/133889 blocks (19.5%), 0 events -2026-02-04T19:01:21.618957Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26180/133889 blocks (19.6%), 0 events -2026-02-04T19:01:21.822982Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26190/133889 blocks (19.6%), 0 events -2026-02-04T19:01:22.018722Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26200/133889 blocks (19.6%), 0 events -2026-02-04T19:01:22.279181Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26210/133889 blocks (19.6%), 0 events -2026-02-04T19:01:22.420670Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26220/133889 blocks (19.6%), 0 events -2026-02-04T19:01:22.631094Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26230/133889 blocks (19.6%), 0 events -2026-02-04T19:01:22.833377Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26240/133889 blocks (19.6%), 0 events -2026-02-04T19:01:23.015042Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26250/133889 blocks (19.6%), 0 events -2026-02-04T19:01:23.182213Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26260/133889 blocks (19.6%), 0 events -2026-02-04T19:01:23.447679Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26270/133889 blocks (19.6%), 0 events -2026-02-04T19:01:23.652246Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26280/133889 blocks (19.6%), 0 events -2026-02-04T19:01:23.851683Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26290/133889 blocks (19.6%), 0 events -2026-02-04T19:01:24.040083Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26300/133889 blocks (19.6%), 0 events -2026-02-04T19:01:24.340084Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26310/133889 blocks (19.7%), 0 events -2026-02-04T19:01:24.439020Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26320/133889 blocks (19.7%), 0 events -2026-02-04T19:01:24.904134Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26330/133889 blocks (19.7%), 0 events -2026-02-04T19:01:24.958001Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26340/133889 blocks (19.7%), 0 events -2026-02-04T19:01:24.996056Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26350/133889 blocks (19.7%), 0 events -2026-02-04T19:01:25.434871Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26360/133889 blocks (19.7%), 0 events -2026-02-04T19:01:25.481523Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26370/133889 blocks (19.7%), 0 events -2026-02-04T19:01:25.641512Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26380/133889 blocks (19.7%), 0 events -2026-02-04T19:01:25.972603Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26390/133889 blocks (19.7%), 0 events -2026-02-04T19:01:26.022000Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26400/133889 blocks (19.7%), 0 events -2026-02-04T19:01:26.200592Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26410/133889 blocks (19.7%), 0 events -2026-02-04T19:01:26.473177Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26420/133889 blocks (19.7%), 0 events -2026-02-04T19:01:26.646967Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26430/133889 blocks (19.7%), 0 events -2026-02-04T19:01:26.965344Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26440/133889 blocks (19.7%), 0 events -2026-02-04T19:01:27.029707Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26450/133889 blocks (19.8%), 0 events -2026-02-04T19:01:27.228717Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26460/133889 blocks (19.8%), 0 events -2026-02-04T19:01:27.524470Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26470/133889 blocks (19.8%), 0 events -2026-02-04T19:01:27.582766Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26480/133889 blocks (19.8%), 0 events -2026-02-04T19:01:27.840382Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26490/133889 blocks (19.8%), 0 events -2026-02-04T19:01:28.045612Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26500/133889 blocks (19.8%), 0 events -2026-02-04T19:01:28.192342Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26510/133889 blocks (19.8%), 0 events -2026-02-04T19:01:28.580844Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26520/133889 blocks (19.8%), 0 events -2026-02-04T19:01:28.626386Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26530/133889 blocks (19.8%), 0 events -2026-02-04T19:01:28.836281Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26540/133889 blocks (19.8%), 0 events -2026-02-04T19:01:29.097535Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26550/133889 blocks (19.8%), 0 events -2026-02-04T19:01:29.228503Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26560/133889 blocks (19.8%), 0 events -2026-02-04T19:01:29.618534Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26570/133889 blocks (19.8%), 0 events -2026-02-04T19:01:29.660350Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26580/133889 blocks (19.9%), 0 events -2026-02-04T19:01:29.820914Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26590/133889 blocks (19.9%), 0 events -2026-02-04T19:01:30.153268Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26600/133889 blocks (19.9%), 0 events -2026-02-04T19:01:30.193305Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26610/133889 blocks (19.9%), 0 events -2026-02-04T19:01:30.437646Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26620/133889 blocks (19.9%), 0 events -2026-02-04T19:01:30.663735Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26630/133889 blocks (19.9%), 0 events -2026-02-04T19:01:30.868627Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26640/133889 blocks (19.9%), 0 events -2026-02-04T19:01:31.055963Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26650/133889 blocks (19.9%), 0 events -2026-02-04T19:01:31.192416Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26660/133889 blocks (19.9%), 0 events -2026-02-04T19:01:31.464008Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26670/133889 blocks (19.9%), 0 events -2026-02-04T19:01:31.682835Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26680/133889 blocks (19.9%), 0 events -2026-02-04T19:01:31.808880Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26690/133889 blocks (19.9%), 0 events -2026-02-04T19:01:31.990328Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26700/133889 blocks (19.9%), 0 events -2026-02-04T19:01:32.240283Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26710/133889 blocks (19.9%), 0 events -2026-02-04T19:01:32.402628Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26720/133889 blocks (20.0%), 0 events -2026-02-04T19:01:32.730523Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26730/133889 blocks (20.0%), 0 events -2026-02-04T19:01:32.808923Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26740/133889 blocks (20.0%), 0 events -2026-02-04T19:01:33.036070Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26750/133889 blocks (20.0%), 0 events -2026-02-04T19:01:33.287145Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26760/133889 blocks (20.0%), 0 events -2026-02-04T19:01:33.470517Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26770/133889 blocks (20.0%), 0 events -2026-02-04T19:01:33.667156Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26780/133889 blocks (20.0%), 0 events -2026-02-04T19:01:33.838356Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26790/133889 blocks (20.0%), 0 events -2026-02-04T19:01:34.054620Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26800/133889 blocks (20.0%), 0 events -2026-02-04T19:01:34.303583Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26810/133889 blocks (20.0%), 0 events -2026-02-04T19:01:34.416335Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26820/133889 blocks (20.0%), 0 events -2026-02-04T19:01:34.827366Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26830/133889 blocks (20.0%), 0 events -2026-02-04T19:01:34.864571Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26840/133889 blocks (20.0%), 0 events -2026-02-04T19:01:35.047785Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26850/133889 blocks (20.1%), 0 events -2026-02-04T19:01:35.187209Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26860/133889 blocks (20.1%), 0 events -2026-02-04T19:01:35.398767Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26870/133889 blocks (20.1%), 0 events -2026-02-04T19:01:35.620842Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26880/133889 blocks (20.1%), 0 events -2026-02-04T19:01:35.914735Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26890/133889 blocks (20.1%), 0 events -2026-02-04T19:01:36.028386Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26900/133889 blocks (20.1%), 0 events -2026-02-04T19:01:36.183645Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26910/133889 blocks (20.1%), 0 events -2026-02-04T19:01:36.431725Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26920/133889 blocks (20.1%), 0 events -2026-02-04T19:01:36.720892Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26930/133889 blocks (20.1%), 0 events -2026-02-04T19:01:36.772512Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26940/133889 blocks (20.1%), 0 events -2026-02-04T19:01:36.990759Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26950/133889 blocks (20.1%), 0 events -2026-02-04T19:01:37.204380Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26960/133889 blocks (20.1%), 0 events -2026-02-04T19:01:37.494224Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26970/133889 blocks (20.1%), 0 events -2026-02-04T19:01:37.618336Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26980/133889 blocks (20.2%), 0 events -2026-02-04T19:01:37.766633Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 26990/133889 blocks (20.2%), 0 events -2026-02-04T19:01:38.009787Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27000/133889 blocks (20.2%), 0 events -2026-02-04T19:01:38.250608Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27010/133889 blocks (20.2%), 0 events -2026-02-04T19:01:38.401376Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27020/133889 blocks (20.2%), 0 events -2026-02-04T19:01:38.571083Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27030/133889 blocks (20.2%), 0 events -2026-02-04T19:01:38.831575Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27040/133889 blocks (20.2%), 0 events -2026-02-04T19:01:39.070280Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27050/133889 blocks (20.2%), 0 events -2026-02-04T19:01:39.239116Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27060/133889 blocks (20.2%), 0 events -2026-02-04T19:01:39.454071Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27070/133889 blocks (20.2%), 0 events -2026-02-04T19:01:39.612614Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27080/133889 blocks (20.2%), 0 events -2026-02-04T19:01:39.870100Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27090/133889 blocks (20.2%), 0 events -2026-02-04T19:01:40.071890Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27100/133889 blocks (20.2%), 0 events -2026-02-04T19:01:40.228096Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27110/133889 blocks (20.2%), 0 events -2026-02-04T19:01:40.390570Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27120/133889 blocks (20.3%), 0 events -2026-02-04T19:01:40.649983Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27130/133889 blocks (20.3%), 0 events -2026-02-04T19:01:40.808471Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27140/133889 blocks (20.3%), 0 events -2026-02-04T19:01:40.993894Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27150/133889 blocks (20.3%), 0 events -2026-02-04T19:01:41.257813Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27160/133889 blocks (20.3%), 0 events -2026-02-04T19:01:41.415479Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27170/133889 blocks (20.3%), 0 events -2026-02-04T19:01:41.673420Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27180/133889 blocks (20.3%), 0 events -2026-02-04T19:01:41.815455Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27190/133889 blocks (20.3%), 0 events -2026-02-04T19:01:41.972979Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27200/133889 blocks (20.3%), 0 events -2026-02-04T19:01:42.228039Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27210/133889 blocks (20.3%), 0 events -2026-02-04T19:01:42.409365Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27220/133889 blocks (20.3%), 0 events -2026-02-04T19:01:42.691269Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27230/133889 blocks (20.3%), 0 events -2026-02-04T19:01:42.823752Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27240/133889 blocks (20.3%), 0 events -2026-02-04T19:01:43.055442Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27250/133889 blocks (20.4%), 0 events -2026-02-04T19:01:43.253946Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27260/133889 blocks (20.4%), 0 events -2026-02-04T19:01:43.457617Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27270/133889 blocks (20.4%), 0 events -2026-02-04T19:01:43.608457Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27280/133889 blocks (20.4%), 0 events -2026-02-04T19:01:43.855252Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27290/133889 blocks (20.4%), 0 events -2026-02-04T19:01:44.002669Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27300/133889 blocks (20.4%), 0 events -2026-02-04T19:01:44.264204Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27310/133889 blocks (20.4%), 0 events -2026-02-04T19:01:44.462938Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27320/133889 blocks (20.4%), 0 events -2026-02-04T19:01:44.570568Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27330/133889 blocks (20.4%), 0 events -2026-02-04T19:01:44.860413Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27340/133889 blocks (20.4%), 0 events -2026-02-04T19:01:45.055380Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27350/133889 blocks (20.4%), 0 events -2026-02-04T19:01:45.311368Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27360/133889 blocks (20.4%), 0 events -2026-02-04T19:01:45.403963Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27370/133889 blocks (20.4%), 0 events -2026-02-04T19:01:45.684735Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27380/133889 blocks (20.4%), 0 events -2026-02-04T19:01:45.872341Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27390/133889 blocks (20.5%), 0 events -2026-02-04T19:01:45.999706Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27400/133889 blocks (20.5%), 0 events -2026-02-04T19:01:46.247030Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27410/133889 blocks (20.5%), 0 events -2026-02-04T19:01:46.433260Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27420/133889 blocks (20.5%), 0 events -2026-02-04T19:01:46.616964Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27430/133889 blocks (20.5%), 0 events -2026-02-04T19:01:46.886061Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27440/133889 blocks (20.5%), 0 events -2026-02-04T19:01:47.006016Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27450/133889 blocks (20.5%), 0 events -2026-02-04T19:01:47.243207Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27460/133889 blocks (20.5%), 0 events -2026-02-04T19:01:47.454600Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27470/133889 blocks (20.5%), 0 events -2026-02-04T19:01:47.611049Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27480/133889 blocks (20.5%), 0 events -2026-02-04T19:01:47.822466Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27490/133889 blocks (20.5%), 0 events -2026-02-04T19:01:47.999266Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27500/133889 blocks (20.5%), 0 events -2026-02-04T19:01:48.196137Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27510/133889 blocks (20.5%), 0 events -2026-02-04T19:01:48.364499Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27520/133889 blocks (20.6%), 0 events -2026-02-04T19:01:48.608606Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27530/133889 blocks (20.6%), 0 events -2026-02-04T19:01:48.771478Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27540/133889 blocks (20.6%), 0 events -2026-02-04T19:01:49.241644Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27550/133889 blocks (20.6%), 0 events -2026-02-04T19:01:49.278386Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27560/133889 blocks (20.6%), 0 events -2026-02-04T19:01:49.383836Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27570/133889 blocks (20.6%), 0 events -2026-02-04T19:01:49.644625Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27580/133889 blocks (20.6%), 0 events -2026-02-04T19:01:49.800688Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27590/133889 blocks (20.6%), 0 events -2026-02-04T19:01:50.061682Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27600/133889 blocks (20.6%), 0 events -2026-02-04T19:01:50.197329Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27610/133889 blocks (20.6%), 0 events -2026-02-04T19:01:50.372441Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27620/133889 blocks (20.6%), 0 events -2026-02-04T19:01:50.645709Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27630/133889 blocks (20.6%), 0 events -2026-02-04T19:01:50.792875Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27640/133889 blocks (20.6%), 0 events -2026-02-04T19:01:50.983320Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27650/133889 blocks (20.7%), 0 events -2026-02-04T19:01:51.268878Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27660/133889 blocks (20.7%), 0 events -2026-02-04T19:01:51.403062Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27670/133889 blocks (20.7%), 0 events -2026-02-04T19:01:51.638095Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27680/133889 blocks (20.7%), 0 events -2026-02-04T19:01:51.803778Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27690/133889 blocks (20.7%), 0 events -2026-02-04T19:01:51.997545Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27700/133889 blocks (20.7%), 0 events -2026-02-04T19:01:52.238225Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27710/133889 blocks (20.7%), 0 events -2026-02-04T19:01:52.424355Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27720/133889 blocks (20.7%), 0 events -2026-02-04T19:01:52.684429Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27730/133889 blocks (20.7%), 0 events -2026-02-04T19:01:52.847850Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27740/133889 blocks (20.7%), 0 events -2026-02-04T19:01:53.055644Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27750/133889 blocks (20.7%), 0 events -2026-02-04T19:01:53.211956Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27760/133889 blocks (20.7%), 0 events -2026-02-04T19:01:53.415702Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27770/133889 blocks (20.7%), 0 events -2026-02-04T19:01:53.702382Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27780/133889 blocks (20.7%), 0 events -2026-02-04T19:01:53.792884Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27790/133889 blocks (20.8%), 0 events -2026-02-04T19:01:53.991687Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27800/133889 blocks (20.8%), 0 events -2026-02-04T19:01:54.258235Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27810/133889 blocks (20.8%), 0 events -2026-02-04T19:01:54.362321Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27820/133889 blocks (20.8%), 0 events -2026-02-04T19:01:54.573124Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27830/133889 blocks (20.8%), 0 events -2026-02-04T19:01:54.784204Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27840/133889 blocks (20.8%), 0 events -2026-02-04T19:01:55.055721Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27850/133889 blocks (20.8%), 0 events -2026-02-04T19:01:55.309359Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27860/133889 blocks (20.8%), 0 events -2026-02-04T19:01:55.407131Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27870/133889 blocks (20.8%), 0 events -2026-02-04T19:01:55.598917Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27880/133889 blocks (20.8%), 0 events -2026-02-04T19:01:55.830957Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27890/133889 blocks (20.8%), 0 events -2026-02-04T19:01:56.011814Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27900/133889 blocks (20.8%), 0 events -2026-02-04T19:01:56.322812Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27910/133889 blocks (20.8%), 0 events -2026-02-04T19:01:56.363826Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27920/133889 blocks (20.9%), 0 events -2026-02-04T19:01:56.597350Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27930/133889 blocks (20.9%), 0 events -2026-02-04T19:01:56.878991Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27940/133889 blocks (20.9%), 0 events -2026-02-04T19:01:57.003357Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27950/133889 blocks (20.9%), 0 events -2026-02-04T19:01:57.230780Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27960/133889 blocks (20.9%), 0 events -2026-02-04T19:01:57.453282Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27970/133889 blocks (20.9%), 0 events -2026-02-04T19:01:57.618419Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27980/133889 blocks (20.9%), 0 events -2026-02-04T19:01:57.772119Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 27990/133889 blocks (20.9%), 0 events -2026-02-04T19:01:58.018711Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28000/133889 blocks (20.9%), 0 events -2026-02-04T19:01:58.219417Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28010/133889 blocks (20.9%), 0 events -2026-02-04T19:01:58.466329Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28020/133889 blocks (20.9%), 0 events -2026-02-04T19:01:58.623024Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28030/133889 blocks (20.9%), 0 events -2026-02-04T19:01:58.797938Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28040/133889 blocks (20.9%), 0 events -2026-02-04T19:01:59.055030Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28050/133889 blocks (20.9%), 0 events -2026-02-04T19:01:59.206865Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28060/133889 blocks (21.0%), 0 events -2026-02-04T19:01:59.378204Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28070/133889 blocks (21.0%), 0 events -2026-02-04T19:01:59.661337Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28080/133889 blocks (21.0%), 0 events -2026-02-04T19:01:59.840354Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28090/133889 blocks (21.0%), 0 events -2026-02-04T19:02:00.030388Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28100/133889 blocks (21.0%), 0 events -2026-02-04T19:02:00.205920Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28110/133889 blocks (21.0%), 0 events -2026-02-04T19:02:00.367530Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28120/133889 blocks (21.0%), 0 events -2026-02-04T19:02:00.631839Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28130/133889 blocks (21.0%), 0 events -2026-02-04T19:02:00.801557Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28140/133889 blocks (21.0%), 0 events -2026-02-04T19:02:01.078774Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28150/133889 blocks (21.0%), 0 events -2026-02-04T19:02:01.168311Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28160/133889 blocks (21.0%), 0 events -2026-02-04T19:02:01.436853Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28170/133889 blocks (21.0%), 0 events -2026-02-04T19:02:01.638817Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28180/133889 blocks (21.0%), 0 events -2026-02-04T19:02:01.819031Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28190/133889 blocks (21.1%), 0 events -2026-02-04T19:02:02.089337Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28200/133889 blocks (21.1%), 0 events -2026-02-04T19:02:02.199380Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28210/133889 blocks (21.1%), 0 events -2026-02-04T19:02:02.390205Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28220/133889 blocks (21.1%), 0 events -2026-02-04T19:02:02.643465Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28230/133889 blocks (21.1%), 0 events -2026-02-04T19:02:02.864654Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28240/133889 blocks (21.1%), 0 events -2026-02-04T19:02:02.997372Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28250/133889 blocks (21.1%), 0 events -2026-02-04T19:02:03.170362Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28260/133889 blocks (21.1%), 0 events -2026-02-04T19:02:03.445872Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28270/133889 blocks (21.1%), 0 events -2026-02-04T19:02:03.702513Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28280/133889 blocks (21.1%), 0 events -2026-02-04T19:02:03.866249Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28290/133889 blocks (21.1%), 0 events -2026-02-04T19:02:04.063944Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28300/133889 blocks (21.1%), 0 events -2026-02-04T19:02:04.231709Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28310/133889 blocks (21.1%), 0 events -2026-02-04T19:02:04.378331Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28320/133889 blocks (21.2%), 0 events -2026-02-04T19:02:04.579460Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28330/133889 blocks (21.2%), 0 events -2026-02-04T19:02:04.797606Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28340/133889 blocks (21.2%), 0 events -2026-02-04T19:02:05.059811Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28350/133889 blocks (21.2%), 0 events -2026-02-04T19:02:05.294149Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28360/133889 blocks (21.2%), 0 events -2026-02-04T19:02:05.375796Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28370/133889 blocks (21.2%), 0 events -2026-02-04T19:02:05.613765Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28380/133889 blocks (21.2%), 0 events -2026-02-04T19:02:05.857386Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28390/133889 blocks (21.2%), 0 events -2026-02-04T19:02:05.973859Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28400/133889 blocks (21.2%), 0 events -2026-02-04T19:02:06.314823Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28410/133889 blocks (21.2%), 0 events -2026-02-04T19:02:06.394831Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28420/133889 blocks (21.2%), 0 events -2026-02-04T19:02:06.580033Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28430/133889 blocks (21.2%), 0 events -2026-02-04T19:02:06.844401Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28440/133889 blocks (21.2%), 0 events -2026-02-04T19:02:06.989619Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28450/133889 blocks (21.2%), 0 events -2026-02-04T19:02:07.202434Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28460/133889 blocks (21.3%), 0 events -2026-02-04T19:02:07.393043Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28470/133889 blocks (21.3%), 0 events -2026-02-04T19:02:07.573931Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28480/133889 blocks (21.3%), 0 events -2026-02-04T19:02:07.890863Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28490/133889 blocks (21.3%), 0 events -2026-02-04T19:02:07.986059Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28500/133889 blocks (21.3%), 0 events -2026-02-04T19:02:08.231935Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28510/133889 blocks (21.3%), 0 events -2026-02-04T19:02:08.414710Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28520/133889 blocks (21.3%), 0 events -2026-02-04T19:02:08.642976Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28530/133889 blocks (21.3%), 0 events -2026-02-04T19:02:08.758870Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28540/133889 blocks (21.3%), 0 events -2026-02-04T19:02:09.029417Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28550/133889 blocks (21.3%), 0 events -2026-02-04T19:02:09.218347Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28560/133889 blocks (21.3%), 0 events -2026-02-04T19:02:09.467172Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28570/133889 blocks (21.3%), 0 events -2026-02-04T19:02:09.586031Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28580/133889 blocks (21.3%), 0 events -2026-02-04T19:02:09.822798Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28590/133889 blocks (21.4%), 0 events -2026-02-04T19:02:10.009071Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28600/133889 blocks (21.4%), 0 events -2026-02-04T19:02:10.184175Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28610/133889 blocks (21.4%), 0 events -2026-02-04T19:02:10.510582Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28620/133889 blocks (21.4%), 0 events -2026-02-04T19:02:10.614793Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28630/133889 blocks (21.4%), 0 events -2026-02-04T19:02:10.825796Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28640/133889 blocks (21.4%), 0 events -2026-02-04T19:02:11.040634Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28650/133889 blocks (21.4%), 0 events -2026-02-04T19:02:11.238509Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28660/133889 blocks (21.4%), 0 events -2026-02-04T19:02:11.393827Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28670/133889 blocks (21.4%), 0 events -2026-02-04T19:02:11.612142Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28680/133889 blocks (21.4%), 0 events -2026-02-04T19:02:11.838187Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28690/133889 blocks (21.4%), 0 events -2026-02-04T19:02:12.086614Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28700/133889 blocks (21.4%), 0 events -2026-02-04T19:02:12.265117Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28710/133889 blocks (21.4%), 0 events -2026-02-04T19:02:12.396965Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28720/133889 blocks (21.5%), 0 events -2026-02-04T19:02:12.607599Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28730/133889 blocks (21.5%), 0 events -2026-02-04T19:02:12.799504Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28740/133889 blocks (21.5%), 0 events -2026-02-04T19:02:13.098340Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28750/133889 blocks (21.5%), 0 events -2026-02-04T19:02:13.176399Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28760/133889 blocks (21.5%), 0 events -2026-02-04T19:02:13.417914Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28770/133889 blocks (21.5%), 0 events -2026-02-04T19:02:13.655944Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28780/133889 blocks (21.5%), 0 events -2026-02-04T19:02:13.829936Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28790/133889 blocks (21.5%), 0 events -2026-02-04T19:02:13.978056Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28800/133889 blocks (21.5%), 0 events -2026-02-04T19:02:14.247001Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28810/133889 blocks (21.5%), 0 events -2026-02-04T19:02:14.457378Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28820/133889 blocks (21.5%), 0 events -2026-02-04T19:02:14.705162Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28830/133889 blocks (21.5%), 0 events -2026-02-04T19:02:14.811561Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28840/133889 blocks (21.5%), 0 events -2026-02-04T19:02:15.045240Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28850/133889 blocks (21.5%), 0 events -2026-02-04T19:02:15.234032Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28860/133889 blocks (21.6%), 0 events -2026-02-04T19:02:15.399771Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28870/133889 blocks (21.6%), 0 events -2026-02-04T19:02:15.752214Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28880/133889 blocks (21.6%), 0 events -2026-02-04T19:02:15.790660Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28890/133889 blocks (21.6%), 0 events -2026-02-04T19:02:15.987773Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28900/133889 blocks (21.6%), 0 events -2026-02-04T19:02:16.277932Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28910/133889 blocks (21.6%), 0 events -2026-02-04T19:02:16.406259Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28920/133889 blocks (21.6%), 0 events -2026-02-04T19:02:16.568487Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28930/133889 blocks (21.6%), 0 events -2026-02-04T19:02:16.857713Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28940/133889 blocks (21.6%), 0 events -2026-02-04T19:02:17.002111Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28950/133889 blocks (21.6%), 0 events -2026-02-04T19:02:17.291660Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28960/133889 blocks (21.6%), 0 events -2026-02-04T19:02:17.417597Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28970/133889 blocks (21.6%), 0 events -2026-02-04T19:02:17.630889Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28980/133889 blocks (21.6%), 0 events -2026-02-04T19:02:17.848111Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 28990/133889 blocks (21.7%), 0 events -2026-02-04T19:02:17.980873Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29000/133889 blocks (21.7%), 0 events -2026-02-04T19:02:18.174950Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29010/133889 blocks (21.7%), 0 events -2026-02-04T19:02:18.457301Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29020/133889 blocks (21.7%), 0 events -2026-02-04T19:02:18.638458Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29030/133889 blocks (21.7%), 0 events -2026-02-04T19:02:18.898420Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29040/133889 blocks (21.7%), 0 events -2026-02-04T19:02:19.054136Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29050/133889 blocks (21.7%), 0 events -2026-02-04T19:02:19.217679Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29060/133889 blocks (21.7%), 0 events -2026-02-04T19:02:19.432977Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29070/133889 blocks (21.7%), 0 events -2026-02-04T19:02:19.641619Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29080/133889 blocks (21.7%), 0 events -2026-02-04T19:02:19.914026Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29090/133889 blocks (21.7%), 0 events -2026-02-04T19:02:19.971624Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29100/133889 blocks (21.7%), 0 events -2026-02-04T19:02:20.205132Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29110/133889 blocks (21.7%), 0 events -2026-02-04T19:02:20.481565Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29120/133889 blocks (21.7%), 0 events -2026-02-04T19:02:20.616627Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29130/133889 blocks (21.8%), 0 events -2026-02-04T19:02:20.830442Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29140/133889 blocks (21.8%), 0 events -2026-02-04T19:02:21.032767Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29150/133889 blocks (21.8%), 0 events -2026-02-04T19:02:21.181109Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29160/133889 blocks (21.8%), 0 events -2026-02-04T19:02:21.372996Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29170/133889 blocks (21.8%), 0 events -2026-02-04T19:02:21.646530Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29180/133889 blocks (21.8%), 0 events -2026-02-04T19:02:21.760688Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29190/133889 blocks (21.8%), 0 events -2026-02-04T19:02:22.058932Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29200/133889 blocks (21.8%), 0 events -2026-02-04T19:02:22.229304Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29210/133889 blocks (21.8%), 0 events -2026-02-04T19:02:22.386384Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29220/133889 blocks (21.8%), 0 events -2026-02-04T19:02:22.572011Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29230/133889 blocks (21.8%), 0 events -2026-02-04T19:02:22.770198Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29240/133889 blocks (21.8%), 0 events -2026-02-04T19:02:23.092443Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29250/133889 blocks (21.8%), 0 events -2026-02-04T19:02:23.174963Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29260/133889 blocks (21.9%), 0 events -2026-02-04T19:02:23.371581Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29270/133889 blocks (21.9%), 0 events -2026-02-04T19:02:23.617346Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29280/133889 blocks (21.9%), 0 events -2026-02-04T19:02:23.853115Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29290/133889 blocks (21.9%), 0 events -2026-02-04T19:02:24.108776Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29300/133889 blocks (21.9%), 0 events -2026-02-04T19:02:24.218663Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29310/133889 blocks (21.9%), 0 events -2026-02-04T19:02:24.439458Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29320/133889 blocks (21.9%), 0 events -2026-02-04T19:02:24.665260Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29330/133889 blocks (21.9%), 0 events -2026-02-04T19:02:24.812990Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29340/133889 blocks (21.9%), 0 events -2026-02-04T19:02:25.064772Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29350/133889 blocks (21.9%), 0 events -2026-02-04T19:02:25.228325Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29360/133889 blocks (21.9%), 0 events -2026-02-04T19:02:25.388878Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29370/133889 blocks (21.9%), 0 events -2026-02-04T19:02:25.682165Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29380/133889 blocks (21.9%), 0 events -2026-02-04T19:02:25.831268Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29390/133889 blocks (22.0%), 0 events -2026-02-04T19:02:25.981054Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29400/133889 blocks (22.0%), 0 events -2026-02-04T19:02:26.240603Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29410/133889 blocks (22.0%), 0 events -2026-02-04T19:02:26.370983Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29420/133889 blocks (22.0%), 0 events -2026-02-04T19:02:26.585962Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29430/133889 blocks (22.0%), 0 events -2026-02-04T19:02:26.776010Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29440/133889 blocks (22.0%), 0 events -2026-02-04T19:02:26.999141Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29450/133889 blocks (22.0%), 0 events -2026-02-04T19:02:27.289719Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29460/133889 blocks (22.0%), 0 events -2026-02-04T19:02:27.401940Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29470/133889 blocks (22.0%), 0 events -2026-02-04T19:02:27.629941Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29480/133889 blocks (22.0%), 0 events -2026-02-04T19:02:27.862958Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29490/133889 blocks (22.0%), 0 events -2026-02-04T19:02:28.043243Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29500/133889 blocks (22.0%), 0 events -2026-02-04T19:02:28.176395Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29510/133889 blocks (22.0%), 0 events -2026-02-04T19:02:28.427161Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29520/133889 blocks (22.0%), 0 events -2026-02-04T19:02:28.640400Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29530/133889 blocks (22.1%), 0 events -2026-02-04T19:02:28.861543Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29540/133889 blocks (22.1%), 0 events -2026-02-04T19:02:29.031505Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29550/133889 blocks (22.1%), 0 events -2026-02-04T19:02:29.245022Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29560/133889 blocks (22.1%), 0 events -2026-02-04T19:02:29.465357Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29570/133889 blocks (22.1%), 0 events -2026-02-04T19:02:29.654776Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29580/133889 blocks (22.1%), 0 events -2026-02-04T19:02:29.909396Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29590/133889 blocks (22.1%), 0 events -2026-02-04T19:02:30.056675Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29600/133889 blocks (22.1%), 0 events -2026-02-04T19:02:30.194962Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29610/133889 blocks (22.1%), 0 events -2026-02-04T19:02:30.432129Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29620/133889 blocks (22.1%), 0 events -2026-02-04T19:02:30.648686Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29630/133889 blocks (22.1%), 0 events -2026-02-04T19:02:30.830991Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29640/133889 blocks (22.1%), 0 events -2026-02-04T19:02:31.012320Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29650/133889 blocks (22.1%), 0 events -2026-02-04T19:02:31.254042Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29660/133889 blocks (22.2%), 0 events -2026-02-04T19:02:31.449011Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29670/133889 blocks (22.2%), 0 events -2026-02-04T19:02:31.578678Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29680/133889 blocks (22.2%), 0 events -2026-02-04T19:02:31.844862Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29690/133889 blocks (22.2%), 0 events -2026-02-04T19:02:32.012069Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29700/133889 blocks (22.2%), 0 events -2026-02-04T19:02:32.199945Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29710/133889 blocks (22.2%), 0 events -2026-02-04T19:02:32.531054Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29720/133889 blocks (22.2%), 0 events -2026-02-04T19:02:32.571960Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29730/133889 blocks (22.2%), 0 events -2026-02-04T19:02:32.824055Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29740/133889 blocks (22.2%), 0 events -2026-02-04T19:02:33.057175Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29750/133889 blocks (22.2%), 0 events -2026-02-04T19:02:33.188161Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29760/133889 blocks (22.2%), 0 events -2026-02-04T19:02:33.446679Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29770/133889 blocks (22.2%), 0 events -2026-02-04T19:02:33.627527Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29780/133889 blocks (22.2%), 0 events -2026-02-04T19:02:33.779769Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29790/133889 blocks (22.2%), 0 events -2026-02-04T19:02:34.070865Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29800/133889 blocks (22.3%), 0 events -2026-02-04T19:02:34.173608Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29810/133889 blocks (22.3%), 0 events -2026-02-04T19:02:34.459322Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29820/133889 blocks (22.3%), 0 events -2026-02-04T19:02:34.648212Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29830/133889 blocks (22.3%), 0 events -2026-02-04T19:02:34.827173Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29840/133889 blocks (22.3%), 0 events -2026-02-04T19:02:35.027372Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29850/133889 blocks (22.3%), 0 events -2026-02-04T19:02:35.260283Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29860/133889 blocks (22.3%), 0 events -2026-02-04T19:02:35.411739Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29870/133889 blocks (22.3%), 0 events -2026-02-04T19:02:35.640778Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29880/133889 blocks (22.3%), 0 events -2026-02-04T19:02:35.869245Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29890/133889 blocks (22.3%), 0 events -2026-02-04T19:02:36.041166Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29900/133889 blocks (22.3%), 0 events -2026-02-04T19:02:36.217301Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29910/133889 blocks (22.3%), 0 events -2026-02-04T19:02:36.374752Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29920/133889 blocks (22.3%), 0 events -2026-02-04T19:02:36.690745Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29930/133889 blocks (22.4%), 0 events -2026-02-04T19:02:36.835422Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29940/133889 blocks (22.4%), 0 events -2026-02-04T19:02:37.035571Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29950/133889 blocks (22.4%), 0 events -2026-02-04T19:02:37.248343Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29960/133889 blocks (22.4%), 0 events -2026-02-04T19:02:37.404541Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29970/133889 blocks (22.4%), 0 events -2026-02-04T19:02:37.587981Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29980/133889 blocks (22.4%), 0 events -2026-02-04T19:02:37.778855Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 29990/133889 blocks (22.4%), 0 events -2026-02-04T19:02:37.975379Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30000/133889 blocks (22.4%), 0 events -2026-02-04T19:02:38.306228Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30010/133889 blocks (22.4%), 0 events -2026-02-04T19:02:38.392775Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30020/133889 blocks (22.4%), 0 events -2026-02-04T19:02:38.642053Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30030/133889 blocks (22.4%), 0 events -2026-02-04T19:02:38.820005Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30040/133889 blocks (22.4%), 0 events -2026-02-04T19:02:38.980891Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30050/133889 blocks (22.4%), 0 events -2026-02-04T19:02:39.206807Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30060/133889 blocks (22.5%), 0 events -2026-02-04T19:02:39.406275Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30070/133889 blocks (22.5%), 0 events -2026-02-04T19:02:39.626430Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30080/133889 blocks (22.5%), 0 events -2026-02-04T19:02:39.865819Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30090/133889 blocks (22.5%), 0 events -2026-02-04T19:02:40.064079Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30100/133889 blocks (22.5%), 0 events -2026-02-04T19:02:40.213910Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30110/133889 blocks (22.5%), 0 events -2026-02-04T19:02:40.403720Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30120/133889 blocks (22.5%), 0 events -2026-02-04T19:02:40.630917Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30130/133889 blocks (22.5%), 0 events -2026-02-04T19:02:40.923456Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30140/133889 blocks (22.5%), 0 events -2026-02-04T19:02:40.973513Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30150/133889 blocks (22.5%), 0 events -2026-02-04T19:02:41.213264Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30160/133889 blocks (22.5%), 0 events -2026-02-04T19:02:41.452053Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30170/133889 blocks (22.5%), 0 events -2026-02-04T19:02:41.668915Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30180/133889 blocks (22.5%), 0 events -2026-02-04T19:02:41.840930Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30190/133889 blocks (22.5%), 0 events -2026-02-04T19:02:41.964042Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30200/133889 blocks (22.6%), 0 events -2026-02-04T19:02:42.224291Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30210/133889 blocks (22.6%), 0 events -2026-02-04T19:02:42.489818Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30220/133889 blocks (22.6%), 0 events -2026-02-04T19:02:42.683776Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30230/133889 blocks (22.6%), 0 events -2026-02-04T19:02:42.833217Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30240/133889 blocks (22.6%), 0 events -2026-02-04T19:02:43.059523Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30250/133889 blocks (22.6%), 0 events -2026-02-04T19:02:43.215893Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30260/133889 blocks (22.6%), 0 events -2026-02-04T19:02:43.504412Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30270/133889 blocks (22.6%), 0 events -2026-02-04T19:02:43.566190Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30280/133889 blocks (22.6%), 0 events -2026-02-04T19:02:43.827755Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30290/133889 blocks (22.6%), 0 events -2026-02-04T19:02:44.063774Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30300/133889 blocks (22.6%), 0 events -2026-02-04T19:02:44.166381Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30310/133889 blocks (22.6%), 0 events -2026-02-04T19:02:44.460805Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30320/133889 blocks (22.6%), 0 events -2026-02-04T19:02:44.648532Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30330/133889 blocks (22.7%), 0 events -2026-02-04T19:02:44.813842Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30340/133889 blocks (22.7%), 0 events -2026-02-04T19:02:45.109585Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30350/133889 blocks (22.7%), 0 events -2026-02-04T19:02:45.193450Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30360/133889 blocks (22.7%), 0 events -2026-02-04T19:02:45.420347Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30370/133889 blocks (22.7%), 0 events -2026-02-04T19:02:45.634057Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30380/133889 blocks (22.7%), 0 events -2026-02-04T19:02:45.778246Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30390/133889 blocks (22.7%), 0 events -2026-02-04T19:02:46.126089Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30400/133889 blocks (22.7%), 0 events -2026-02-04T19:02:46.161849Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30410/133889 blocks (22.7%), 0 events -2026-02-04T19:02:46.379909Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30420/133889 blocks (22.7%), 0 events -2026-02-04T19:02:46.650061Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30430/133889 blocks (22.7%), 0 events -2026-02-04T19:02:46.847605Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30440/133889 blocks (22.7%), 0 events -2026-02-04T19:02:46.996496Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30450/133889 blocks (22.7%), 0 events -2026-02-04T19:02:47.204868Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30460/133889 blocks (22.7%), 0 events -2026-02-04T19:02:47.432440Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30470/133889 blocks (22.8%), 0 events -2026-02-04T19:02:47.699253Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30480/133889 blocks (22.8%), 0 events -2026-02-04T19:02:47.926862Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30490/133889 blocks (22.8%), 0 events -2026-02-04T19:02:47.965276Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30500/133889 blocks (22.8%), 0 events -2026-02-04T19:02:48.267074Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30510/133889 blocks (22.8%), 0 events -2026-02-04T19:02:48.458943Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30520/133889 blocks (22.8%), 0 events -2026-02-04T19:02:48.641989Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30530/133889 blocks (22.8%), 0 events -2026-02-04T19:02:48.807160Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30540/133889 blocks (22.8%), 0 events -2026-02-04T19:02:48.982779Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30550/133889 blocks (22.8%), 0 events -2026-02-04T19:02:49.272970Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30560/133889 blocks (22.8%), 0 events -2026-02-04T19:02:49.527732Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30570/133889 blocks (22.8%), 0 events -2026-02-04T19:02:49.579033Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30580/133889 blocks (22.8%), 0 events -2026-02-04T19:02:49.828745Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30590/133889 blocks (22.8%), 0 events -2026-02-04T19:02:50.061447Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30600/133889 blocks (22.9%), 0 events -2026-02-04T19:02:50.217890Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30610/133889 blocks (22.9%), 0 events -2026-02-04T19:02:50.405572Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30620/133889 blocks (22.9%), 0 events -2026-02-04T19:02:50.663472Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30630/133889 blocks (22.9%), 0 events -2026-02-04T19:02:50.883189Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30640/133889 blocks (22.9%), 0 events -2026-02-04T19:02:51.034197Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30650/133889 blocks (22.9%), 0 events -2026-02-04T19:02:51.175407Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30660/133889 blocks (22.9%), 0 events -2026-02-04T19:02:51.400090Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30670/133889 blocks (22.9%), 0 events -2026-02-04T19:02:51.603139Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30680/133889 blocks (22.9%), 0 events -2026-02-04T19:02:51.896121Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30690/133889 blocks (22.9%), 0 events -2026-02-04T19:02:52.027538Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30700/133889 blocks (22.9%), 0 events -2026-02-04T19:02:52.452813Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30710/133889 blocks (22.9%), 0 events -2026-02-04T19:02:52.492335Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30720/133889 blocks (22.9%), 0 events -2026-02-04T19:02:52.588558Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30730/133889 blocks (23.0%), 0 events -2026-02-04T19:02:52.810060Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30740/133889 blocks (23.0%), 0 events -2026-02-04T19:02:52.976198Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30750/133889 blocks (23.0%), 0 events -2026-02-04T19:02:53.232056Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30760/133889 blocks (23.0%), 0 events -2026-02-04T19:02:53.360874Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30770/133889 blocks (23.0%), 0 events -2026-02-04T19:02:53.659538Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30780/133889 blocks (23.0%), 0 events -2026-02-04T19:02:53.780081Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30790/133889 blocks (23.0%), 0 events -2026-02-04T19:02:54.046354Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30800/133889 blocks (23.0%), 0 events -2026-02-04T19:02:54.220123Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30810/133889 blocks (23.0%), 0 events -2026-02-04T19:02:54.518194Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30820/133889 blocks (23.0%), 0 events -2026-02-04T19:02:54.556390Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30830/133889 blocks (23.0%), 0 events -2026-02-04T19:02:54.846538Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30840/133889 blocks (23.0%), 0 events -2026-02-04T19:02:55.078413Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30850/133889 blocks (23.0%), 0 events -2026-02-04T19:02:55.211746Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30860/133889 blocks (23.0%), 0 events -2026-02-04T19:02:55.399451Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30870/133889 blocks (23.1%), 0 events -2026-02-04T19:02:55.651410Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30880/133889 blocks (23.1%), 0 events -2026-02-04T19:02:55.861198Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30890/133889 blocks (23.1%), 0 events -2026-02-04T19:02:56.131132Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30900/133889 blocks (23.1%), 0 events -2026-02-04T19:02:56.172973Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30910/133889 blocks (23.1%), 0 events -2026-02-04T19:02:56.416192Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30920/133889 blocks (23.1%), 0 events -2026-02-04T19:02:56.643761Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30930/133889 blocks (23.1%), 0 events -2026-02-04T19:02:56.867724Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30940/133889 blocks (23.1%), 0 events -2026-02-04T19:02:57.033436Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30950/133889 blocks (23.1%), 0 events -2026-02-04T19:02:57.255881Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30960/133889 blocks (23.1%), 0 events -2026-02-04T19:02:57.442471Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30970/133889 blocks (23.1%), 0 events -2026-02-04T19:02:57.690980Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30980/133889 blocks (23.1%), 0 events -2026-02-04T19:02:57.808679Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 30990/133889 blocks (23.1%), 0 events -2026-02-04T19:02:58.032459Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31000/133889 blocks (23.2%), 0 events -2026-02-04T19:02:58.244478Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31010/133889 blocks (23.2%), 0 events -2026-02-04T19:02:58.445504Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31020/133889 blocks (23.2%), 0 events -2026-02-04T19:02:58.739739Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31030/133889 blocks (23.2%), 0 events -2026-02-04T19:02:58.778296Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31040/133889 blocks (23.2%), 0 events -2026-02-04T19:02:59.061808Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31050/133889 blocks (23.2%), 0 events -2026-02-04T19:02:59.265573Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31060/133889 blocks (23.2%), 0 events -2026-02-04T19:02:59.375674Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31070/133889 blocks (23.2%), 0 events -2026-02-04T19:02:59.574771Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31080/133889 blocks (23.2%), 0 events -2026-02-04T19:02:59.799922Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31090/133889 blocks (23.2%), 0 events -2026-02-04T19:02:59.998485Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31100/133889 blocks (23.2%), 0 events -2026-02-04T19:03:00.188647Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31110/133889 blocks (23.2%), 0 events -2026-02-04T19:03:00.432810Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31120/133889 blocks (23.2%), 0 events -2026-02-04T19:03:00.659764Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31130/133889 blocks (23.3%), 0 events -2026-02-04T19:03:00.866965Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31140/133889 blocks (23.3%), 0 events -2026-02-04T19:03:01.033609Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31150/133889 blocks (23.3%), 0 events -2026-02-04T19:03:01.225553Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31160/133889 blocks (23.3%), 0 events -2026-02-04T19:03:01.419631Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31170/133889 blocks (23.3%), 0 events -2026-02-04T19:03:01.617484Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31180/133889 blocks (23.3%), 0 events -2026-02-04T19:03:01.856095Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31190/133889 blocks (23.3%), 0 events -2026-02-04T19:03:02.000554Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31200/133889 blocks (23.3%), 0 events -2026-02-04T19:03:02.248654Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31210/133889 blocks (23.3%), 0 events -2026-02-04T19:03:02.460991Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31220/133889 blocks (23.3%), 0 events -2026-02-04T19:03:02.629286Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31230/133889 blocks (23.3%), 0 events -2026-02-04T19:03:02.783951Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31240/133889 blocks (23.3%), 0 events -2026-02-04T19:03:03.004252Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31250/133889 blocks (23.3%), 0 events -2026-02-04T19:03:03.192225Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31260/133889 blocks (23.3%), 0 events -2026-02-04T19:03:03.465912Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31270/133889 blocks (23.4%), 0 events -2026-02-04T19:03:03.611571Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31280/133889 blocks (23.4%), 0 events -2026-02-04T19:03:03.860344Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31290/133889 blocks (23.4%), 0 events -2026-02-04T19:03:03.999132Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31300/133889 blocks (23.4%), 0 events -2026-02-04T19:03:04.225338Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31310/133889 blocks (23.4%), 0 events -2026-02-04T19:03:04.476374Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31320/133889 blocks (23.4%), 0 events -2026-02-04T19:03:04.578135Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31330/133889 blocks (23.4%), 0 events -2026-02-04T19:03:04.841668Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31340/133889 blocks (23.4%), 0 events -2026-02-04T19:03:05.034397Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31350/133889 blocks (23.4%), 0 events -2026-02-04T19:03:05.230829Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31360/133889 blocks (23.4%), 0 events -2026-02-04T19:03:05.402916Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31370/133889 blocks (23.4%), 0 events -2026-02-04T19:03:05.807427Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31380/133889 blocks (23.4%), 0 events -2026-02-04T19:03:05.844750Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31390/133889 blocks (23.4%), 0 events -2026-02-04T19:03:06.094285Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31400/133889 blocks (23.5%), 0 events -2026-02-04T19:03:06.186442Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31410/133889 blocks (23.5%), 0 events -2026-02-04T19:03:06.437486Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31420/133889 blocks (23.5%), 0 events -2026-02-04T19:03:06.602779Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31430/133889 blocks (23.5%), 0 events -2026-02-04T19:03:06.773156Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31440/133889 blocks (23.5%), 0 events -2026-02-04T19:03:06.984498Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31450/133889 blocks (23.5%), 0 events -2026-02-04T19:03:07.253159Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31460/133889 blocks (23.5%), 0 events -2026-02-04T19:03:07.412513Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31470/133889 blocks (23.5%), 0 events -2026-02-04T19:03:07.667550Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31480/133889 blocks (23.5%), 0 events -2026-02-04T19:03:07.780128Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31490/133889 blocks (23.5%), 0 events -2026-02-04T19:03:08.038528Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31500/133889 blocks (23.5%), 0 events -2026-02-04T19:03:08.177316Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31510/133889 blocks (23.5%), 0 events -2026-02-04T19:03:08.414584Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31520/133889 blocks (23.5%), 0 events -2026-02-04T19:03:08.574592Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31530/133889 blocks (23.5%), 0 events -2026-02-04T19:03:08.857668Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31540/133889 blocks (23.6%), 0 events -2026-02-04T19:03:09.004694Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31550/133889 blocks (23.6%), 0 events -2026-02-04T19:03:09.263571Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31560/133889 blocks (23.6%), 0 events -2026-02-04T19:03:09.407998Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31570/133889 blocks (23.6%), 0 events -2026-02-04T19:03:09.613948Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31580/133889 blocks (23.6%), 0 events -2026-02-04T19:03:09.813244Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31590/133889 blocks (23.6%), 0 events -2026-02-04T19:03:10.037207Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31600/133889 blocks (23.6%), 0 events -2026-02-04T19:03:10.276618Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31610/133889 blocks (23.6%), 0 events -2026-02-04T19:03:10.433006Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31620/133889 blocks (23.6%), 0 events -2026-02-04T19:03:10.585764Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31630/133889 blocks (23.6%), 0 events -2026-02-04T19:03:10.806760Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31640/133889 blocks (23.6%), 0 events -2026-02-04T19:03:10.992097Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31650/133889 blocks (23.6%), 0 events -2026-02-04T19:03:11.338422Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31660/133889 blocks (23.6%), 0 events -2026-02-04T19:03:11.380964Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31670/133889 blocks (23.7%), 0 events -2026-02-04T19:03:11.587352Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31680/133889 blocks (23.7%), 0 events -2026-02-04T19:03:11.852782Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31690/133889 blocks (23.7%), 0 events -2026-02-04T19:03:11.994240Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31700/133889 blocks (23.7%), 0 events -2026-02-04T19:03:12.217427Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31710/133889 blocks (23.7%), 0 events -2026-02-04T19:03:12.446568Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31720/133889 blocks (23.7%), 0 events -2026-02-04T19:03:12.646929Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31730/133889 blocks (23.7%), 0 events -2026-02-04T19:03:12.899123Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31740/133889 blocks (23.7%), 0 events -2026-02-04T19:03:13.045521Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31750/133889 blocks (23.7%), 0 events -2026-02-04T19:03:13.198948Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31760/133889 blocks (23.7%), 0 events -2026-02-04T19:03:13.418263Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31770/133889 blocks (23.7%), 0 events -2026-02-04T19:03:13.584849Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31780/133889 blocks (23.7%), 0 events -2026-02-04T19:03:13.913075Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31790/133889 blocks (23.7%), 0 events -2026-02-04T19:03:14.043936Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31800/133889 blocks (23.8%), 0 events -2026-02-04T19:03:14.181314Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31810/133889 blocks (23.8%), 0 events -2026-02-04T19:03:14.467493Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31820/133889 blocks (23.8%), 0 events -2026-02-04T19:03:14.605714Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31830/133889 blocks (23.8%), 0 events -2026-02-04T19:03:14.845254Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31840/133889 blocks (23.8%), 0 events -2026-02-04T19:03:15.000710Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31850/133889 blocks (23.8%), 0 events -2026-02-04T19:03:15.274790Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31860/133889 blocks (23.8%), 0 events -2026-02-04T19:03:15.484764Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31870/133889 blocks (23.8%), 0 events -2026-02-04T19:03:15.601617Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31880/133889 blocks (23.8%), 0 events -2026-02-04T19:03:15.868333Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31890/133889 blocks (23.8%), 0 events -2026-02-04T19:03:16.045094Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31900/133889 blocks (23.8%), 0 events -2026-02-04T19:03:16.192770Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31910/133889 blocks (23.8%), 0 events -2026-02-04T19:03:16.440725Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31920/133889 blocks (23.8%), 0 events -2026-02-04T19:03:16.609455Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31930/133889 blocks (23.8%), 0 events -2026-02-04T19:03:16.870360Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31940/133889 blocks (23.9%), 0 events -2026-02-04T19:03:17.094403Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31950/133889 blocks (23.9%), 0 events -2026-02-04T19:03:17.202879Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31960/133889 blocks (23.9%), 0 events -2026-02-04T19:03:17.367912Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31970/133889 blocks (23.9%), 0 events -2026-02-04T19:03:17.654917Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31980/133889 blocks (23.9%), 0 events -2026-02-04T19:03:17.821148Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 31990/133889 blocks (23.9%), 0 events -2026-02-04T19:03:18.137949Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32000/133889 blocks (23.9%), 0 events -2026-02-04T19:03:18.176632Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32010/133889 blocks (23.9%), 0 events -2026-02-04T19:03:18.457435Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32020/133889 blocks (23.9%), 0 events -2026-02-04T19:03:18.662909Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32030/133889 blocks (23.9%), 0 events -2026-02-04T19:03:18.851754Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32040/133889 blocks (23.9%), 0 events -2026-02-04T19:03:19.053762Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32050/133889 blocks (23.9%), 0 events -2026-02-04T19:03:19.232723Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32060/133889 blocks (23.9%), 0 events -2026-02-04T19:03:19.444431Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32070/133889 blocks (24.0%), 0 events -2026-02-04T19:03:19.714120Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32080/133889 blocks (24.0%), 0 events -2026-02-04T19:03:19.836293Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32090/133889 blocks (24.0%), 0 events -2026-02-04T19:03:20.027063Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32100/133889 blocks (24.0%), 0 events -2026-02-04T19:03:20.237967Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32110/133889 blocks (24.0%), 0 events -2026-02-04T19:03:20.434372Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32120/133889 blocks (24.0%), 0 events -2026-02-04T19:03:20.585404Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32130/133889 blocks (24.0%), 0 events -2026-02-04T19:03:20.847526Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32140/133889 blocks (24.0%), 0 events -2026-02-04T19:03:20.993930Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32150/133889 blocks (24.0%), 0 events -2026-02-04T19:03:21.288397Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32160/133889 blocks (24.0%), 0 events -2026-02-04T19:03:21.433260Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32170/133889 blocks (24.0%), 0 events -2026-02-04T19:03:21.645936Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32180/133889 blocks (24.0%), 0 events -2026-02-04T19:03:21.809984Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32190/133889 blocks (24.0%), 0 events -2026-02-04T19:03:21.998041Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32200/133889 blocks (24.0%), 0 events -2026-02-04T19:03:22.193776Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32210/133889 blocks (24.1%), 0 events -2026-02-04T19:03:22.457035Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32220/133889 blocks (24.1%), 0 events -2026-02-04T19:03:22.638231Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32230/133889 blocks (24.1%), 0 events -2026-02-04T19:03:22.860514Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32240/133889 blocks (24.1%), 0 events -2026-02-04T19:03:23.014701Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32250/133889 blocks (24.1%), 0 events -2026-02-04T19:03:23.218089Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32260/133889 blocks (24.1%), 0 events -2026-02-04T19:03:23.446778Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32270/133889 blocks (24.1%), 0 events -2026-02-04T19:03:23.636363Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32280/133889 blocks (24.1%), 0 events -2026-02-04T19:03:23.873838Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32290/133889 blocks (24.1%), 0 events -2026-02-04T19:03:24.028833Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32300/133889 blocks (24.1%), 0 events -2026-02-04T19:03:24.211600Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32310/133889 blocks (24.1%), 0 events -2026-02-04T19:03:24.427785Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32320/133889 blocks (24.1%), 0 events -2026-02-04T19:03:24.635818Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32330/133889 blocks (24.1%), 0 events -2026-02-04T19:03:24.766461Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32340/133889 blocks (24.2%), 0 events -2026-02-04T19:03:25.008951Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32350/133889 blocks (24.2%), 0 events -2026-02-04T19:03:25.168732Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32360/133889 blocks (24.2%), 0 events -2026-02-04T19:03:25.447246Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32370/133889 blocks (24.2%), 0 events -2026-02-04T19:03:25.642792Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32380/133889 blocks (24.2%), 0 events -2026-02-04T19:03:25.809208Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32390/133889 blocks (24.2%), 0 events -2026-02-04T19:03:26.008771Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32400/133889 blocks (24.2%), 0 events -2026-02-04T19:03:26.180565Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32410/133889 blocks (24.2%), 0 events -2026-02-04T19:03:26.495027Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32420/133889 blocks (24.2%), 0 events -2026-02-04T19:03:26.659428Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32430/133889 blocks (24.2%), 0 events -2026-02-04T19:03:26.791271Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32440/133889 blocks (24.2%), 0 events -2026-02-04T19:03:27.051769Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32450/133889 blocks (24.2%), 0 events -2026-02-04T19:03:27.249269Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32460/133889 blocks (24.2%), 0 events -2026-02-04T19:03:27.383064Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32470/133889 blocks (24.3%), 0 events -2026-02-04T19:03:27.629347Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32480/133889 blocks (24.3%), 0 events -2026-02-04T19:03:27.868017Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32490/133889 blocks (24.3%), 0 events -2026-02-04T19:03:27.975203Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32500/133889 blocks (24.3%), 0 events -2026-02-04T19:03:28.197803Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32510/133889 blocks (24.3%), 0 events -2026-02-04T19:03:28.412018Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32520/133889 blocks (24.3%), 0 events -2026-02-04T19:03:28.661718Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32530/133889 blocks (24.3%), 0 events -2026-02-04T19:03:28.845878Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32540/133889 blocks (24.3%), 0 events -2026-02-04T19:03:29.149165Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32550/133889 blocks (24.3%), 0 events -2026-02-04T19:03:29.199266Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32560/133889 blocks (24.3%), 0 events -2026-02-04T19:03:29.450277Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32570/133889 blocks (24.3%), 0 events -2026-02-04T19:03:29.675349Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32580/133889 blocks (24.3%), 0 events -2026-02-04T19:03:29.804436Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32590/133889 blocks (24.3%), 0 events -2026-02-04T19:03:30.009481Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32600/133889 blocks (24.3%), 0 events -2026-02-04T19:03:30.264893Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32610/133889 blocks (24.4%), 0 events -2026-02-04T19:03:30.384595Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32620/133889 blocks (24.4%), 0 events -2026-02-04T19:03:30.597190Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32630/133889 blocks (24.4%), 0 events -2026-02-04T19:03:30.832343Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32640/133889 blocks (24.4%), 0 events -2026-02-04T19:03:31.010430Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32650/133889 blocks (24.4%), 0 events -2026-02-04T19:03:31.255524Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32660/133889 blocks (24.4%), 0 events -2026-02-04T19:03:31.382534Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32670/133889 blocks (24.4%), 0 events -2026-02-04T19:03:31.738622Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32680/133889 blocks (24.4%), 0 events -2026-02-04T19:03:31.778618Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32690/133889 blocks (24.4%), 0 events -2026-02-04T19:03:32.053298Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32700/133889 blocks (24.4%), 0 events -2026-02-04T19:03:32.300807Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32710/133889 blocks (24.4%), 0 events -2026-02-04T19:03:32.433554Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32720/133889 blocks (24.4%), 0 events -2026-02-04T19:03:32.626830Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32730/133889 blocks (24.4%), 0 events -2026-02-04T19:03:32.823151Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32740/133889 blocks (24.5%), 0 events -2026-02-04T19:03:33.017036Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32750/133889 blocks (24.5%), 0 events -2026-02-04T19:03:33.346922Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32760/133889 blocks (24.5%), 0 events -2026-02-04T19:03:33.385665Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32770/133889 blocks (24.5%), 0 events -2026-02-04T19:03:33.636797Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32780/133889 blocks (24.5%), 0 events -2026-02-04T19:03:33.866495Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32790/133889 blocks (24.5%), 0 events -2026-02-04T19:03:33.977536Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32800/133889 blocks (24.5%), 0 events -2026-02-04T19:03:34.197641Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32810/133889 blocks (24.5%), 0 events -2026-02-04T19:03:34.421167Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32820/133889 blocks (24.5%), 0 events -2026-02-04T19:03:34.658718Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32830/133889 blocks (24.5%), 0 events -2026-02-04T19:03:34.884130Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32840/133889 blocks (24.5%), 0 events -2026-02-04T19:03:35.000529Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32850/133889 blocks (24.5%), 0 events -2026-02-04T19:03:35.218482Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32860/133889 blocks (24.5%), 0 events -2026-02-04T19:03:35.450000Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32870/133889 blocks (24.5%), 0 events -2026-02-04T19:03:35.600167Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32880/133889 blocks (24.6%), 0 events -2026-02-04T19:03:35.823045Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32890/133889 blocks (24.6%), 0 events -2026-02-04T19:03:36.058162Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32900/133889 blocks (24.6%), 0 events -2026-02-04T19:03:36.170268Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32910/133889 blocks (24.6%), 0 events -2026-02-04T19:03:36.455833Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32920/133889 blocks (24.6%), 0 events -2026-02-04T19:03:36.563461Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32930/133889 blocks (24.6%), 0 events -2026-02-04T19:03:36.864563Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32940/133889 blocks (24.6%), 0 events -2026-02-04T19:03:37.022530Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32950/133889 blocks (24.6%), 0 events -2026-02-04T19:03:37.211074Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32960/133889 blocks (24.6%), 0 events -2026-02-04T19:03:37.370155Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32970/133889 blocks (24.6%), 0 events -2026-02-04T19:03:37.620737Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32980/133889 blocks (24.6%), 0 events -2026-02-04T19:03:37.824024Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 32990/133889 blocks (24.6%), 0 events -2026-02-04T19:03:38.062409Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33000/133889 blocks (24.6%), 0 events -2026-02-04T19:03:38.253342Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33010/133889 blocks (24.7%), 0 events -2026-02-04T19:03:38.557044Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33020/133889 blocks (24.7%), 0 events -2026-02-04T19:03:38.601244Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33030/133889 blocks (24.7%), 0 events -2026-02-04T19:03:38.833812Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33040/133889 blocks (24.7%), 0 events -2026-02-04T19:03:39.120329Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33050/133889 blocks (24.7%), 0 events -2026-02-04T19:03:39.165830Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33060/133889 blocks (24.7%), 0 events -2026-02-04T19:03:39.404724Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33070/133889 blocks (24.7%), 0 events -2026-02-04T19:03:39.633995Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33080/133889 blocks (24.7%), 0 events -2026-02-04T19:03:39.803211Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33090/133889 blocks (24.7%), 0 events -2026-02-04T19:03:39.967882Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33100/133889 blocks (24.7%), 0 events -2026-02-04T19:03:40.252346Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33110/133889 blocks (24.7%), 0 events -2026-02-04T19:03:40.419574Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33120/133889 blocks (24.7%), 0 events -2026-02-04T19:03:40.650192Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33130/133889 blocks (24.7%), 0 events -2026-02-04T19:03:40.778317Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33140/133889 blocks (24.8%), 0 events -2026-02-04T19:03:40.994771Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33150/133889 blocks (24.8%), 0 events -2026-02-04T19:03:41.249196Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33160/133889 blocks (24.8%), 0 events -2026-02-04T19:03:41.400944Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33170/133889 blocks (24.8%), 0 events -2026-02-04T19:03:41.584816Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33180/133889 blocks (24.8%), 0 events -2026-02-04T19:03:41.849432Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33190/133889 blocks (24.8%), 0 events -2026-02-04T19:03:42.055208Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33200/133889 blocks (24.8%), 0 events -2026-02-04T19:03:42.256260Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33210/133889 blocks (24.8%), 0 events -2026-02-04T19:03:42.442354Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33220/133889 blocks (24.8%), 0 events -2026-02-04T19:03:42.627590Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33230/133889 blocks (24.8%), 0 events -2026-02-04T19:03:42.850783Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33240/133889 blocks (24.8%), 0 events -2026-02-04T19:03:43.012385Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33250/133889 blocks (24.8%), 0 events -2026-02-04T19:03:43.302095Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33260/133889 blocks (24.8%), 0 events -2026-02-04T19:03:43.430522Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33270/133889 blocks (24.8%), 0 events -2026-02-04T19:03:43.660048Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33280/133889 blocks (24.9%), 0 events -2026-02-04T19:03:43.841034Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33290/133889 blocks (24.9%), 0 events -2026-02-04T19:03:44.043378Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33300/133889 blocks (24.9%), 0 events -2026-02-04T19:03:44.323857Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33310/133889 blocks (24.9%), 0 events -2026-02-04T19:03:44.363429Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33320/133889 blocks (24.9%), 0 events -2026-02-04T19:03:44.586146Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33330/133889 blocks (24.9%), 0 events -2026-02-04T19:03:44.878636Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33340/133889 blocks (24.9%), 0 events -2026-02-04T19:03:44.990110Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33350/133889 blocks (24.9%), 0 events -2026-02-04T19:03:45.196912Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33360/133889 blocks (24.9%), 0 events -2026-02-04T19:03:45.406762Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33370/133889 blocks (24.9%), 0 events -2026-02-04T19:03:45.667279Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33380/133889 blocks (24.9%), 0 events -2026-02-04T19:03:45.921171Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33390/133889 blocks (24.9%), 0 events -2026-02-04T19:03:45.959048Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33400/133889 blocks (24.9%), 0 events -2026-02-04T19:03:46.216090Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33410/133889 blocks (25.0%), 0 events -2026-02-04T19:03:46.452991Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33420/133889 blocks (25.0%), 0 events -2026-02-04T19:03:46.637236Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33430/133889 blocks (25.0%), 0 events -2026-02-04T19:03:46.769444Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33440/133889 blocks (25.0%), 0 events -2026-02-04T19:03:46.976937Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33450/133889 blocks (25.0%), 0 events -2026-02-04T19:03:47.204399Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33460/133889 blocks (25.0%), 0 events -2026-02-04T19:03:47.499628Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33470/133889 blocks (25.0%), 0 events -2026-02-04T19:03:47.580729Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33480/133889 blocks (25.0%), 0 events -2026-02-04T19:03:47.771322Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33490/133889 blocks (25.0%), 0 events -2026-02-04T19:03:48.018154Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33500/133889 blocks (25.0%), 0 events -2026-02-04T19:03:48.225002Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33510/133889 blocks (25.0%), 0 events -2026-02-04T19:03:48.382223Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33520/133889 blocks (25.0%), 0 events -2026-02-04T19:03:48.568788Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33530/133889 blocks (25.0%), 0 events -2026-02-04T19:03:48.847523Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33540/133889 blocks (25.1%), 0 events -2026-02-04T19:03:49.077541Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33550/133889 blocks (25.1%), 0 events -2026-02-04T19:03:49.229338Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33560/133889 blocks (25.1%), 0 events -2026-02-04T19:03:49.447235Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33570/133889 blocks (25.1%), 0 events -2026-02-04T19:03:49.596100Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33580/133889 blocks (25.1%), 0 events -2026-02-04T19:03:49.836803Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33590/133889 blocks (25.1%), 0 events -2026-02-04T19:03:50.087220Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33600/133889 blocks (25.1%), 0 events -2026-02-04T19:03:50.234340Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33610/133889 blocks (25.1%), 0 events -2026-02-04T19:03:50.384298Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33620/133889 blocks (25.1%), 0 events -2026-02-04T19:03:50.647595Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33630/133889 blocks (25.1%), 0 events -2026-02-04T19:03:50.858681Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33640/133889 blocks (25.1%), 0 events -2026-02-04T19:03:50.990239Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33650/133889 blocks (25.1%), 0 events -2026-02-04T19:03:51.225833Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33660/133889 blocks (25.1%), 0 events -2026-02-04T19:03:51.392545Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33670/133889 blocks (25.1%), 0 events -2026-02-04T19:03:51.659168Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33680/133889 blocks (25.2%), 0 events -2026-02-04T19:03:51.789307Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33690/133889 blocks (25.2%), 0 events -2026-02-04T19:03:52.069098Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33700/133889 blocks (25.2%), 0 events -2026-02-04T19:03:52.230717Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33710/133889 blocks (25.2%), 0 events -2026-02-04T19:03:52.422989Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33720/133889 blocks (25.2%), 0 events -2026-02-04T19:03:52.710744Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33730/133889 blocks (25.2%), 0 events -2026-02-04T19:03:52.778674Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33740/133889 blocks (25.2%), 0 events -2026-02-04T19:03:53.058078Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33750/133889 blocks (25.2%), 0 events -2026-02-04T19:03:53.232606Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33760/133889 blocks (25.2%), 0 events -2026-02-04T19:03:53.437207Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33770/133889 blocks (25.2%), 0 events -2026-02-04T19:03:53.580585Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33780/133889 blocks (25.2%), 0 events -2026-02-04T19:03:53.836861Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33790/133889 blocks (25.2%), 0 events -2026-02-04T19:03:54.000039Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33800/133889 blocks (25.2%), 0 events -2026-02-04T19:03:54.420897Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33810/133889 blocks (25.3%), 0 events -2026-02-04T19:03:54.457963Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33820/133889 blocks (25.3%), 0 events -2026-02-04T19:03:54.601888Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33830/133889 blocks (25.3%), 0 events -2026-02-04T19:03:54.868785Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33840/133889 blocks (25.3%), 0 events -2026-02-04T19:03:54.994664Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33850/133889 blocks (25.3%), 0 events -2026-02-04T19:03:55.202779Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33860/133889 blocks (25.3%), 0 events -2026-02-04T19:03:55.419163Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33870/133889 blocks (25.3%), 0 events -2026-02-04T19:03:55.573671Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33880/133889 blocks (25.3%), 0 events -2026-02-04T19:03:55.885226Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33890/133889 blocks (25.3%), 0 events -2026-02-04T19:03:56.019584Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33900/133889 blocks (25.3%), 0 events -2026-02-04T19:03:56.201313Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33910/133889 blocks (25.3%), 0 events -2026-02-04T19:03:56.409554Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33920/133889 blocks (25.3%), 0 events -2026-02-04T19:03:56.653389Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33930/133889 blocks (25.3%), 0 events -2026-02-04T19:03:56.901398Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33940/133889 blocks (25.3%), 0 events -2026-02-04T19:03:56.996256Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33950/133889 blocks (25.4%), 0 events -2026-02-04T19:03:57.175711Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33960/133889 blocks (25.4%), 0 events -2026-02-04T19:03:57.456391Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33970/133889 blocks (25.4%), 0 events -2026-02-04T19:03:57.663668Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33980/133889 blocks (25.4%), 0 events -2026-02-04T19:03:57.853679Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 33990/133889 blocks (25.4%), 0 events -2026-02-04T19:03:57.997668Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34000/133889 blocks (25.4%), 0 events -2026-02-04T19:03:58.181825Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34010/133889 blocks (25.4%), 0 events -2026-02-04T19:03:58.474801Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34020/133889 blocks (25.4%), 0 events -2026-02-04T19:03:59.001563Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34030/133889 blocks (25.4%), 0 events -2026-02-04T19:03:59.043036Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34040/133889 blocks (25.4%), 0 events -2026-02-04T19:03:59.088574Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34050/133889 blocks (25.4%), 0 events -2026-02-04T19:03:59.244317Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34060/133889 blocks (25.4%), 0 events -2026-02-04T19:03:59.521973Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34070/133889 blocks (25.4%), 0 events -2026-02-04T19:03:59.563565Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34080/133889 blocks (25.5%), 0 events -2026-02-04T19:03:59.838317Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34090/133889 blocks (25.5%), 0 events -2026-02-04T19:04:00.081821Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34100/133889 blocks (25.5%), 0 events -2026-02-04T19:04:00.240049Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34110/133889 blocks (25.5%), 0 events -2026-02-04T19:04:00.390260Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34120/133889 blocks (25.5%), 0 events -2026-02-04T19:04:00.614694Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34130/133889 blocks (25.5%), 0 events -2026-02-04T19:04:00.846991Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34140/133889 blocks (25.5%), 0 events -2026-02-04T19:04:01.096010Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34150/133889 blocks (25.5%), 0 events -2026-02-04T19:04:01.209385Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34160/133889 blocks (25.5%), 0 events -2026-02-04T19:04:01.443156Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34170/133889 blocks (25.5%), 0 events -2026-02-04T19:04:01.657496Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34180/133889 blocks (25.5%), 0 events -2026-02-04T19:04:01.864463Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34190/133889 blocks (25.5%), 0 events -2026-02-04T19:04:02.031174Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34200/133889 blocks (25.5%), 0 events -2026-02-04T19:04:02.247744Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34210/133889 blocks (25.6%), 0 events -2026-02-04T19:04:02.398965Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34220/133889 blocks (25.6%), 0 events -2026-02-04T19:04:02.706952Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34230/133889 blocks (25.6%), 0 events -2026-02-04T19:04:02.829122Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34240/133889 blocks (25.6%), 0 events -2026-02-04T19:04:02.974589Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34250/133889 blocks (25.6%), 0 events -2026-02-04T19:04:03.273806Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34260/133889 blocks (25.6%), 0 events -2026-02-04T19:04:03.434182Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34270/133889 blocks (25.6%), 0 events -2026-02-04T19:04:03.754873Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34280/133889 blocks (25.6%), 0 events -2026-02-04T19:04:03.808571Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34290/133889 blocks (25.6%), 0 events -2026-02-04T19:04:04.064108Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34300/133889 blocks (25.6%), 0 events -2026-02-04T19:04:04.277972Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34310/133889 blocks (25.6%), 0 events -2026-02-04T19:04:04.375153Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34320/133889 blocks (25.6%), 0 events -2026-02-04T19:04:04.641886Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34330/133889 blocks (25.6%), 0 events -2026-02-04T19:04:04.847786Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34340/133889 blocks (25.6%), 0 events -2026-02-04T19:04:04.991931Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34350/133889 blocks (25.7%), 0 events -2026-02-04T19:04:05.326015Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34360/133889 blocks (25.7%), 0 events -2026-02-04T19:04:05.372640Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34370/133889 blocks (25.7%), 0 events -2026-02-04T19:04:05.574940Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34380/133889 blocks (25.7%), 0 events -2026-02-04T19:04:05.856492Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34390/133889 blocks (25.7%), 0 events -2026-02-04T19:04:06.032895Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34400/133889 blocks (25.7%), 0 events -2026-02-04T19:04:06.337296Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34410/133889 blocks (25.7%), 0 events -2026-02-04T19:04:06.398227Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34420/133889 blocks (25.7%), 0 events -2026-02-04T19:04:06.577792Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34430/133889 blocks (25.7%), 0 events -2026-02-04T19:04:06.904804Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34440/133889 blocks (25.7%), 0 events -2026-02-04T19:04:07.051900Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34450/133889 blocks (25.7%), 0 events -2026-02-04T19:04:07.171967Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34460/133889 blocks (25.7%), 0 events -2026-02-04T19:04:07.426767Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34470/133889 blocks (25.7%), 0 events -2026-02-04T19:04:07.590970Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34480/133889 blocks (25.8%), 0 events -2026-02-04T19:04:07.943933Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34490/133889 blocks (25.8%), 0 events -2026-02-04T19:04:07.983073Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34500/133889 blocks (25.8%), 0 events -2026-02-04T19:04:08.181090Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34510/133889 blocks (25.8%), 0 events -2026-02-04T19:04:08.476102Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34520/133889 blocks (25.8%), 0 events -2026-02-04T19:04:08.591845Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34530/133889 blocks (25.8%), 0 events -2026-02-04T19:04:08.829816Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34540/133889 blocks (25.8%), 0 events -2026-02-04T19:04:09.019609Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34550/133889 blocks (25.8%), 0 events -2026-02-04T19:04:09.206814Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34560/133889 blocks (25.8%), 0 events -2026-02-04T19:04:09.485122Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34570/133889 blocks (25.8%), 0 events -2026-02-04T19:04:09.659536Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34580/133889 blocks (25.8%), 0 events -2026-02-04T19:04:09.794538Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34590/133889 blocks (25.8%), 0 events -2026-02-04T19:04:10.070448Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34600/133889 blocks (25.8%), 0 events -2026-02-04T19:04:10.184297Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34610/133889 blocks (25.8%), 0 events -2026-02-04T19:04:10.430056Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34620/133889 blocks (25.9%), 0 events -2026-02-04T19:04:10.568138Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34630/133889 blocks (25.9%), 0 events -2026-02-04T19:04:10.801283Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34640/133889 blocks (25.9%), 0 events -2026-02-04T19:04:11.097297Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34650/133889 blocks (25.9%), 0 events -2026-02-04T19:04:11.181162Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34660/133889 blocks (25.9%), 0 events -2026-02-04T19:04:11.415300Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34670/133889 blocks (25.9%), 0 events -2026-02-04T19:04:11.669960Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34680/133889 blocks (25.9%), 0 events -2026-02-04T19:04:11.825366Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34690/133889 blocks (25.9%), 0 events -2026-02-04T19:04:12.107000Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34700/133889 blocks (25.9%), 0 events -2026-02-04T19:04:12.270152Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34710/133889 blocks (25.9%), 0 events -2026-02-04T19:04:12.360563Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34720/133889 blocks (25.9%), 0 events -2026-02-04T19:04:12.669454Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34730/133889 blocks (25.9%), 0 events -2026-02-04T19:04:12.819220Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34740/133889 blocks (25.9%), 0 events -2026-02-04T19:04:13.064386Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34750/133889 blocks (26.0%), 0 events -2026-02-04T19:04:13.281900Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34760/133889 blocks (26.0%), 0 events -2026-02-04T19:04:13.469983Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34770/133889 blocks (26.0%), 0 events -2026-02-04T19:04:13.679238Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34780/133889 blocks (26.0%), 0 events -2026-02-04T19:04:13.880458Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34790/133889 blocks (26.0%), 0 events -2026-02-04T19:04:14.059856Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34800/133889 blocks (26.0%), 0 events -2026-02-04T19:04:14.234217Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34810/133889 blocks (26.0%), 0 events -2026-02-04T19:04:14.372563Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34820/133889 blocks (26.0%), 0 events -2026-02-04T19:04:14.617565Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34830/133889 blocks (26.0%), 0 events -2026-02-04T19:04:14.834113Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34840/133889 blocks (26.0%), 0 events -2026-02-04T19:04:14.999368Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34850/133889 blocks (26.0%), 0 events -2026-02-04T19:04:15.289664Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34860/133889 blocks (26.0%), 0 events -2026-02-04T19:04:15.459002Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34870/133889 blocks (26.0%), 0 events -2026-02-04T19:04:15.589391Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34880/133889 blocks (26.1%), 0 events -2026-02-04T19:04:15.870535Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34890/133889 blocks (26.1%), 0 events -2026-02-04T19:04:15.988030Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34900/133889 blocks (26.1%), 0 events -2026-02-04T19:04:16.203283Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34910/133889 blocks (26.1%), 0 events -2026-02-04T19:04:16.433812Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34920/133889 blocks (26.1%), 0 events -2026-02-04T19:04:16.594148Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34930/133889 blocks (26.1%), 0 events -2026-02-04T19:04:16.861033Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34940/133889 blocks (26.1%), 0 events -2026-02-04T19:04:16.992268Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34950/133889 blocks (26.1%), 0 events -2026-02-04T19:04:17.218247Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34960/133889 blocks (26.1%), 0 events -2026-02-04T19:04:17.381433Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34970/133889 blocks (26.1%), 0 events -2026-02-04T19:04:17.590081Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34980/133889 blocks (26.1%), 0 events -2026-02-04T19:04:17.911640Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 34990/133889 blocks (26.1%), 0 events -2026-02-04T19:04:18.005679Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35000/133889 blocks (26.1%), 0 events -2026-02-04T19:04:18.168625Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35010/133889 blocks (26.1%), 0 events -2026-02-04T19:04:18.430571Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35020/133889 blocks (26.2%), 0 events -2026-02-04T19:04:18.641414Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35030/133889 blocks (26.2%), 0 events -2026-02-04T19:04:18.810671Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35040/133889 blocks (26.2%), 0 events -2026-02-04T19:04:19.032741Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35050/133889 blocks (26.2%), 0 events -2026-02-04T19:04:19.229496Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35060/133889 blocks (26.2%), 0 events -2026-02-04T19:04:19.482606Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35070/133889 blocks (26.2%), 0 events -2026-02-04T19:04:19.588815Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35080/133889 blocks (26.2%), 0 events -2026-02-04T19:04:19.824088Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35090/133889 blocks (26.2%), 0 events -2026-02-04T19:04:20.012980Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35100/133889 blocks (26.2%), 0 events -2026-02-04T19:04:20.237378Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35110/133889 blocks (26.2%), 0 events -2026-02-04T19:04:20.494370Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35120/133889 blocks (26.2%), 0 events -2026-02-04T19:04:20.663208Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35130/133889 blocks (26.2%), 0 events -2026-02-04T19:04:20.814992Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35140/133889 blocks (26.2%), 0 events -2026-02-04T19:04:21.062525Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35150/133889 blocks (26.3%), 0 events -2026-02-04T19:04:21.241539Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35160/133889 blocks (26.3%), 0 events -2026-02-04T19:04:21.409453Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35170/133889 blocks (26.3%), 0 events -2026-02-04T19:04:21.649847Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35180/133889 blocks (26.3%), 0 events -2026-02-04T19:04:21.822106Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35190/133889 blocks (26.3%), 0 events -2026-02-04T19:04:22.098744Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35200/133889 blocks (26.3%), 0 events -2026-02-04T19:04:22.181749Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35210/133889 blocks (26.3%), 0 events -2026-02-04T19:04:22.451114Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35220/133889 blocks (26.3%), 0 events -2026-02-04T19:04:22.653051Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35230/133889 blocks (26.3%), 0 events -2026-02-04T19:04:22.819872Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35240/133889 blocks (26.3%), 0 events -2026-02-04T19:04:23.116524Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35250/133889 blocks (26.3%), 0 events -2026-02-04T19:04:23.205107Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35260/133889 blocks (26.3%), 0 events -2026-02-04T19:04:23.425400Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35270/133889 blocks (26.3%), 0 events -2026-02-04T19:04:23.682300Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35280/133889 blocks (26.3%), 0 events -2026-02-04T19:04:23.828817Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35290/133889 blocks (26.4%), 0 events -2026-02-04T19:04:24.016103Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35300/133889 blocks (26.4%), 0 events -2026-02-04T19:04:24.264977Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35310/133889 blocks (26.4%), 0 events -2026-02-04T19:04:24.689233Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35320/133889 blocks (26.4%), 0 events -2026-02-04T19:04:24.730720Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35330/133889 blocks (26.4%), 0 events -2026-02-04T19:04:24.768195Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35340/133889 blocks (26.4%), 0 events -2026-02-04T19:04:25.039615Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35350/133889 blocks (26.4%), 0 events -2026-02-04T19:04:25.266834Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35360/133889 blocks (26.4%), 0 events -2026-02-04T19:04:25.464739Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35370/133889 blocks (26.4%), 0 events -2026-02-04T19:04:25.635758Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35380/133889 blocks (26.4%), 0 events -2026-02-04T19:04:25.864330Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35390/133889 blocks (26.4%), 0 events -2026-02-04T19:04:26.013841Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35400/133889 blocks (26.4%), 0 events -2026-02-04T19:04:26.293682Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35410/133889 blocks (26.4%), 0 events -2026-02-04T19:04:26.425997Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35420/133889 blocks (26.5%), 0 events -2026-02-04T19:04:26.664812Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35430/133889 blocks (26.5%), 0 events -2026-02-04T19:04:26.821495Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35440/133889 blocks (26.5%), 0 events -2026-02-04T19:04:27.036920Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35450/133889 blocks (26.5%), 0 events -2026-02-04T19:04:27.193890Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35460/133889 blocks (26.5%), 0 events -2026-02-04T19:04:27.404420Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35470/133889 blocks (26.5%), 0 events -2026-02-04T19:04:27.663472Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35480/133889 blocks (26.5%), 0 events -2026-02-04T19:04:27.870123Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35490/133889 blocks (26.5%), 0 events -2026-02-04T19:04:28.024628Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35500/133889 blocks (26.5%), 0 events -2026-02-04T19:04:28.233676Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35510/133889 blocks (26.5%), 0 events -2026-02-04T19:04:28.413985Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35520/133889 blocks (26.5%), 0 events -2026-02-04T19:04:28.571329Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35530/133889 blocks (26.5%), 0 events -2026-02-04T19:04:28.883255Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35540/133889 blocks (26.5%), 0 events -2026-02-04T19:04:29.018212Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35550/133889 blocks (26.6%), 0 events -2026-02-04T19:04:29.279028Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35560/133889 blocks (26.6%), 0 events -2026-02-04T19:04:29.445814Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35570/133889 blocks (26.6%), 0 events -2026-02-04T19:04:29.587390Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35580/133889 blocks (26.6%), 0 events -2026-02-04T19:04:29.931636Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35590/133889 blocks (26.6%), 0 events -2026-02-04T19:04:29.995488Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35600/133889 blocks (26.6%), 0 events -2026-02-04T19:04:30.266688Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35610/133889 blocks (26.6%), 0 events -2026-02-04T19:04:30.457321Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35620/133889 blocks (26.6%), 0 events -2026-02-04T19:04:30.657030Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35630/133889 blocks (26.6%), 0 events -2026-02-04T19:04:30.836383Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35640/133889 blocks (26.6%), 0 events -2026-02-04T19:04:31.014905Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35650/133889 blocks (26.6%), 0 events -2026-02-04T19:04:31.176557Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35660/133889 blocks (26.6%), 0 events -2026-02-04T19:04:31.408308Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35670/133889 blocks (26.6%), 0 events -2026-02-04T19:04:31.624560Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35680/133889 blocks (26.6%), 0 events -2026-02-04T19:04:31.816542Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35690/133889 blocks (26.7%), 0 events -2026-02-04T19:04:32.072870Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35700/133889 blocks (26.7%), 0 events -2026-02-04T19:04:32.219965Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35710/133889 blocks (26.7%), 0 events -2026-02-04T19:04:32.393851Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35720/133889 blocks (26.7%), 0 events -2026-02-04T19:04:32.619020Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35730/133889 blocks (26.7%), 0 events -2026-02-04T19:04:32.836031Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35740/133889 blocks (26.7%), 0 events -2026-02-04T19:04:33.110751Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35750/133889 blocks (26.7%), 0 events -2026-02-04T19:04:33.265001Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35760/133889 blocks (26.7%), 0 events -2026-02-04T19:04:33.464078Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35770/133889 blocks (26.7%), 0 events -2026-02-04T19:04:33.744825Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35780/133889 blocks (26.7%), 0 events -2026-02-04T19:04:33.788029Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35790/133889 blocks (26.7%), 0 events -2026-02-04T19:04:33.999178Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35800/133889 blocks (26.7%), 0 events -2026-02-04T19:04:34.187363Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35810/133889 blocks (26.7%), 0 events -2026-02-04T19:04:34.423437Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35820/133889 blocks (26.8%), 0 events -2026-02-04T19:04:34.685334Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35830/133889 blocks (26.8%), 0 events -2026-02-04T19:04:34.788967Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35840/133889 blocks (26.8%), 0 events -2026-02-04T19:04:34.998869Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35850/133889 blocks (26.8%), 0 events -2026-02-04T19:04:35.372769Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35860/133889 blocks (26.8%), 0 events -2026-02-04T19:04:35.418769Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35870/133889 blocks (26.8%), 0 events -2026-02-04T19:04:35.699777Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35880/133889 blocks (26.8%), 0 events -2026-02-04T19:04:35.872781Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35890/133889 blocks (26.8%), 0 events -2026-02-04T19:04:36.001450Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35900/133889 blocks (26.8%), 0 events -2026-02-04T19:04:36.255230Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35910/133889 blocks (26.8%), 0 events -2026-02-04T19:04:36.408421Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35920/133889 blocks (26.8%), 0 events -2026-02-04T19:04:36.586536Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35930/133889 blocks (26.8%), 0 events -2026-02-04T19:04:36.804317Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35940/133889 blocks (26.8%), 0 events -2026-02-04T19:04:37.051417Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35950/133889 blocks (26.9%), 0 events -2026-02-04T19:04:37.306606Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35960/133889 blocks (26.9%), 0 events -2026-02-04T19:04:37.380479Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35970/133889 blocks (26.9%), 0 events -2026-02-04T19:04:37.648342Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35980/133889 blocks (26.9%), 0 events -2026-02-04T19:04:37.845345Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 35990/133889 blocks (26.9%), 0 events -2026-02-04T19:04:38.037326Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36000/133889 blocks (26.9%), 0 events -2026-02-04T19:04:38.319403Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36010/133889 blocks (26.9%), 0 events -2026-02-04T19:04:38.366516Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36020/133889 blocks (26.9%), 0 events -2026-02-04T19:04:38.649718Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36030/133889 blocks (26.9%), 0 events -2026-02-04T19:04:38.875210Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36040/133889 blocks (26.9%), 0 events -2026-02-04T19:04:39.012016Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36050/133889 blocks (26.9%), 0 events -2026-02-04T19:04:39.214372Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36060/133889 blocks (26.9%), 0 events -2026-02-04T19:04:39.405081Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36070/133889 blocks (26.9%), 0 events -2026-02-04T19:04:39.606396Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36080/133889 blocks (26.9%), 0 events -2026-02-04T19:04:39.892909Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36090/133889 blocks (27.0%), 0 events -2026-02-04T19:04:40.077995Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36100/133889 blocks (27.0%), 0 events -2026-02-04T19:04:40.210261Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36110/133889 blocks (27.0%), 0 events -2026-02-04T19:04:40.460570Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36120/133889 blocks (27.0%), 0 events -2026-02-04T19:04:40.630721Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36130/133889 blocks (27.0%), 0 events -2026-02-04T19:04:40.821521Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36140/133889 blocks (27.0%), 0 events -2026-02-04T19:04:41.031186Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36150/133889 blocks (27.0%), 0 events -2026-02-04T19:04:41.238802Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36160/133889 blocks (27.0%), 0 events -2026-02-04T19:04:41.496131Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36170/133889 blocks (27.0%), 0 events -2026-02-04T19:04:41.565177Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36180/133889 blocks (27.0%), 0 events -2026-02-04T19:04:41.764696Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36190/133889 blocks (27.0%), 0 events -2026-02-04T19:04:42.020873Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36200/133889 blocks (27.0%), 0 events -2026-02-04T19:04:42.243695Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36210/133889 blocks (27.0%), 0 events -2026-02-04T19:04:42.412697Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36220/133889 blocks (27.1%), 0 events -2026-02-04T19:04:42.584017Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36230/133889 blocks (27.1%), 0 events -2026-02-04T19:04:42.808059Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36240/133889 blocks (27.1%), 0 events -2026-02-04T19:04:43.075160Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36250/133889 blocks (27.1%), 0 events -2026-02-04T19:04:43.183532Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36260/133889 blocks (27.1%), 0 events -2026-02-04T19:04:43.451246Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36270/133889 blocks (27.1%), 0 events -2026-02-04T19:04:43.653830Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36280/133889 blocks (27.1%), 0 events -2026-02-04T19:04:43.806988Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36290/133889 blocks (27.1%), 0 events -2026-02-04T19:04:44.087782Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36300/133889 blocks (27.1%), 0 events -2026-02-04T19:04:44.266575Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36310/133889 blocks (27.1%), 0 events -2026-02-04T19:04:44.376981Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36320/133889 blocks (27.1%), 0 events -2026-02-04T19:04:44.642327Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36330/133889 blocks (27.1%), 0 events -2026-02-04T19:04:44.807178Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36340/133889 blocks (27.1%), 0 events -2026-02-04T19:04:44.967646Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36350/133889 blocks (27.1%), 0 events -2026-02-04T19:04:45.220981Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36360/133889 blocks (27.2%), 0 events -2026-02-04T19:04:45.443388Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36370/133889 blocks (27.2%), 0 events -2026-02-04T19:04:45.661563Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36380/133889 blocks (27.2%), 0 events -2026-02-04T19:04:45.859128Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36390/133889 blocks (27.2%), 0 events -2026-02-04T19:04:46.011989Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36400/133889 blocks (27.2%), 0 events -2026-02-04T19:04:46.275164Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36410/133889 blocks (27.2%), 0 events -2026-02-04T19:04:46.459521Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36420/133889 blocks (27.2%), 0 events -2026-02-04T19:04:46.710395Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36430/133889 blocks (27.2%), 0 events -2026-02-04T19:04:46.780252Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36440/133889 blocks (27.2%), 0 events -2026-02-04T19:04:47.012633Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36450/133889 blocks (27.2%), 0 events -2026-02-04T19:04:47.265135Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36460/133889 blocks (27.2%), 0 events -2026-02-04T19:04:47.377631Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36470/133889 blocks (27.2%), 0 events -2026-02-04T19:04:47.667609Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36480/133889 blocks (27.2%), 0 events -2026-02-04T19:04:47.787571Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36490/133889 blocks (27.3%), 0 events -2026-02-04T19:04:48.059333Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36500/133889 blocks (27.3%), 0 events -2026-02-04T19:04:48.280410Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36510/133889 blocks (27.3%), 0 events -2026-02-04T19:04:48.379046Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36520/133889 blocks (27.3%), 0 events -2026-02-04T19:04:48.646599Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36530/133889 blocks (27.3%), 0 events -2026-02-04T19:04:48.834313Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36540/133889 blocks (27.3%), 0 events -2026-02-04T19:04:48.990834Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36550/133889 blocks (27.3%), 0 events -2026-02-04T19:04:49.229248Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36560/133889 blocks (27.3%), 0 events -2026-02-04T19:04:49.454695Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36570/133889 blocks (27.3%), 0 events -2026-02-04T19:04:49.651718Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36580/133889 blocks (27.3%), 0 events -2026-02-04T19:04:49.887398Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36590/133889 blocks (27.3%), 0 events -2026-02-04T19:04:49.987519Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36600/133889 blocks (27.3%), 0 events -2026-02-04T19:04:50.219479Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36610/133889 blocks (27.3%), 0 events -2026-02-04T19:04:50.452145Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36620/133889 blocks (27.4%), 0 events -2026-02-04T19:04:50.617787Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36630/133889 blocks (27.4%), 0 events -2026-02-04T19:04:50.936219Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36640/133889 blocks (27.4%), 0 events -2026-02-04T19:04:50.979153Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36650/133889 blocks (27.4%), 0 events -2026-02-04T19:04:51.195485Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36660/133889 blocks (27.4%), 0 events -2026-02-04T19:04:51.460401Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36670/133889 blocks (27.4%), 0 events -2026-02-04T19:04:51.653932Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36680/133889 blocks (27.4%), 0 events -2026-02-04T19:04:51.787009Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36690/133889 blocks (27.4%), 0 events -2026-02-04T19:04:51.987060Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36700/133889 blocks (27.4%), 0 events -2026-02-04T19:04:52.184428Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36710/133889 blocks (27.4%), 0 events -2026-02-04T19:04:52.508782Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36720/133889 blocks (27.4%), 0 events -2026-02-04T19:04:52.644743Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36730/133889 blocks (27.4%), 0 events -2026-02-04T19:04:52.821986Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36740/133889 blocks (27.4%), 0 events -2026-02-04T19:04:53.066217Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36750/133889 blocks (27.4%), 0 events -2026-02-04T19:04:53.185446Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36760/133889 blocks (27.5%), 0 events -2026-02-04T19:04:53.391898Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36770/133889 blocks (27.5%), 0 events -2026-02-04T19:04:53.640121Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36780/133889 blocks (27.5%), 0 events -2026-02-04T19:04:53.788411Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36790/133889 blocks (27.5%), 0 events -2026-02-04T19:04:54.084259Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36800/133889 blocks (27.5%), 0 events -2026-02-04T19:04:54.243813Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36810/133889 blocks (27.5%), 0 events -2026-02-04T19:04:54.383682Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36820/133889 blocks (27.5%), 0 events -2026-02-04T19:04:54.630416Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36830/133889 blocks (27.5%), 0 events -2026-02-04T19:04:54.827700Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36840/133889 blocks (27.5%), 0 events -2026-02-04T19:04:54.999378Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36850/133889 blocks (27.5%), 0 events -2026-02-04T19:04:55.187216Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36860/133889 blocks (27.5%), 0 events -2026-02-04T19:04:55.425241Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36870/133889 blocks (27.5%), 0 events -2026-02-04T19:04:55.651564Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36880/133889 blocks (27.5%), 0 events -2026-02-04T19:04:55.871924Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36890/133889 blocks (27.6%), 0 events -2026-02-04T19:04:56.011755Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36900/133889 blocks (27.6%), 0 events -2026-02-04T19:04:56.214242Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36910/133889 blocks (27.6%), 0 events -2026-02-04T19:04:56.443285Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36920/133889 blocks (27.6%), 0 events -2026-02-04T19:04:56.700318Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36930/133889 blocks (27.6%), 0 events -2026-02-04T19:04:56.846571Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36940/133889 blocks (27.6%), 0 events -2026-02-04T19:04:57.052633Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36950/133889 blocks (27.6%), 0 events -2026-02-04T19:04:57.229671Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36960/133889 blocks (27.6%), 0 events -2026-02-04T19:04:57.396395Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36970/133889 blocks (27.6%), 0 events -2026-02-04T19:04:57.718884Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36980/133889 blocks (27.6%), 0 events -2026-02-04T19:04:57.760440Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 36990/133889 blocks (27.6%), 0 events -2026-02-04T19:04:58.018080Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37000/133889 blocks (27.6%), 0 events -2026-02-04T19:04:58.272431Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37010/133889 blocks (27.6%), 0 events -2026-02-04T19:04:58.448598Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37020/133889 blocks (27.6%), 0 events -2026-02-04T19:04:58.638599Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37030/133889 blocks (27.7%), 0 events -2026-02-04T19:04:58.857988Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37040/133889 blocks (27.7%), 0 events -2026-02-04T19:04:58.984188Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37050/133889 blocks (27.7%), 0 events -2026-02-04T19:04:59.169520Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37060/133889 blocks (27.7%), 0 events -2026-02-04T19:04:59.417099Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37070/133889 blocks (27.7%), 0 events -2026-02-04T19:04:59.605145Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37080/133889 blocks (27.7%), 0 events -2026-02-04T19:04:59.846044Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37090/133889 blocks (27.7%), 0 events -2026-02-04T19:05:00.012943Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37100/133889 blocks (27.7%), 0 events -2026-02-04T19:05:00.229096Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37110/133889 blocks (27.7%), 0 events -2026-02-04T19:05:00.465682Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37120/133889 blocks (27.7%), 0 events -2026-02-04T19:05:00.597120Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37130/133889 blocks (27.7%), 0 events -2026-02-04T19:05:00.912703Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37140/133889 blocks (27.7%), 0 events -2026-02-04T19:05:00.990207Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37150/133889 blocks (27.7%), 0 events -2026-02-04T19:05:01.289430Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37160/133889 blocks (27.8%), 0 events -2026-02-04T19:05:01.464353Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37170/133889 blocks (27.8%), 0 events -2026-02-04T19:05:01.582443Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37180/133889 blocks (27.8%), 0 events -2026-02-04T19:05:01.782829Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37190/133889 blocks (27.8%), 0 events -2026-02-04T19:05:02.009788Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37200/133889 blocks (27.8%), 0 events -2026-02-04T19:05:02.187470Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37210/133889 blocks (27.8%), 0 events -2026-02-04T19:05:02.472236Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37220/133889 blocks (27.8%), 0 events -2026-02-04T19:05:02.609469Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37230/133889 blocks (27.8%), 0 events -2026-02-04T19:05:02.810046Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37240/133889 blocks (27.8%), 0 events -2026-02-04T19:05:02.998905Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37250/133889 blocks (27.8%), 0 events -2026-02-04T19:05:03.223955Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37260/133889 blocks (27.8%), 0 events -2026-02-04T19:05:03.484205Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37270/133889 blocks (27.8%), 0 events -2026-02-04T19:05:03.646741Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37280/133889 blocks (27.8%), 0 events -2026-02-04T19:05:03.834554Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37290/133889 blocks (27.9%), 0 events -2026-02-04T19:05:04.041449Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37300/133889 blocks (27.9%), 0 events -2026-02-04T19:05:04.258682Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37310/133889 blocks (27.9%), 0 events -2026-02-04T19:05:04.419625Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37320/133889 blocks (27.9%), 0 events -2026-02-04T19:05:04.644486Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37330/133889 blocks (27.9%), 0 events -2026-02-04T19:05:04.842628Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37340/133889 blocks (27.9%), 0 events -2026-02-04T19:05:05.057915Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37350/133889 blocks (27.9%), 0 events -2026-02-04T19:05:05.231967Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37360/133889 blocks (27.9%), 0 events -2026-02-04T19:05:05.416360Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37370/133889 blocks (27.9%), 0 events -2026-02-04T19:05:05.625451Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37380/133889 blocks (27.9%), 0 events -2026-02-04T19:05:05.805548Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37390/133889 blocks (27.9%), 0 events -2026-02-04T19:05:06.105071Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37400/133889 blocks (27.9%), 0 events -2026-02-04T19:05:06.225993Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37410/133889 blocks (27.9%), 0 events -2026-02-04T19:05:06.425075Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37420/133889 blocks (27.9%), 0 events -2026-02-04T19:05:06.662735Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37430/133889 blocks (28.0%), 0 events -2026-02-04T19:05:06.767597Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37440/133889 blocks (28.0%), 0 events -2026-02-04T19:05:07.059547Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37450/133889 blocks (28.0%), 0 events -2026-02-04T19:05:07.187319Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37460/133889 blocks (28.0%), 0 events -2026-02-04T19:05:07.369787Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37470/133889 blocks (28.0%), 0 events -2026-02-04T19:05:07.722312Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37480/133889 blocks (28.0%), 0 events -2026-02-04T19:05:07.766679Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37490/133889 blocks (28.0%), 0 events -2026-02-04T19:05:08.023289Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37500/133889 blocks (28.0%), 0 events -2026-02-04T19:05:08.245099Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37510/133889 blocks (28.0%), 0 events -2026-02-04T19:05:08.406283Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37520/133889 blocks (28.0%), 0 events -2026-02-04T19:05:08.611880Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37530/133889 blocks (28.0%), 0 events -2026-02-04T19:05:08.786557Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37540/133889 blocks (28.0%), 0 events -2026-02-04T19:05:08.973353Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37550/133889 blocks (28.0%), 0 events -2026-02-04T19:05:09.280026Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37560/133889 blocks (28.1%), 0 events -2026-02-04T19:05:09.454104Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37570/133889 blocks (28.1%), 0 events -2026-02-04T19:05:09.579987Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37580/133889 blocks (28.1%), 0 events -2026-02-04T19:05:09.807432Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37590/133889 blocks (28.1%), 0 events -2026-02-04T19:05:10.030205Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37600/133889 blocks (28.1%), 0 events -2026-02-04T19:05:10.298759Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37610/133889 blocks (28.1%), 0 events -2026-02-04T19:05:10.393575Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37620/133889 blocks (28.1%), 0 events -2026-02-04T19:05:10.659346Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37630/133889 blocks (28.1%), 0 events -2026-02-04T19:05:10.858738Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37640/133889 blocks (28.1%), 0 events -2026-02-04T19:05:11.050849Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37650/133889 blocks (28.1%), 0 events -2026-02-04T19:05:11.230196Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37660/133889 blocks (28.1%), 0 events -2026-02-04T19:05:11.382214Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37670/133889 blocks (28.1%), 0 events -2026-02-04T19:05:11.659500Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37680/133889 blocks (28.1%), 0 events -2026-02-04T19:05:11.870845Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37690/133889 blocks (28.1%), 0 events -2026-02-04T19:05:12.097867Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37700/133889 blocks (28.2%), 0 events -2026-02-04T19:05:12.242881Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37710/133889 blocks (28.2%), 0 events -2026-02-04T19:05:12.446076Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37720/133889 blocks (28.2%), 0 events -2026-02-04T19:05:12.639214Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37730/133889 blocks (28.2%), 0 events -2026-02-04T19:05:12.781199Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37740/133889 blocks (28.2%), 0 events -2026-02-04T19:05:13.019969Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37750/133889 blocks (28.2%), 0 events -2026-02-04T19:05:13.236244Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37760/133889 blocks (28.2%), 0 events -2026-02-04T19:05:13.501962Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37770/133889 blocks (28.2%), 0 events -2026-02-04T19:05:13.615322Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37780/133889 blocks (28.2%), 0 events -2026-02-04T19:05:13.834507Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37790/133889 blocks (28.2%), 0 events -2026-02-04T19:05:14.012518Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37800/133889 blocks (28.2%), 0 events -2026-02-04T19:05:14.175140Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37810/133889 blocks (28.2%), 0 events -2026-02-04T19:05:14.529218Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37820/133889 blocks (28.2%), 0 events -2026-02-04T19:05:14.573200Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37830/133889 blocks (28.3%), 0 events -2026-02-04T19:05:14.852129Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37840/133889 blocks (28.3%), 0 events -2026-02-04T19:05:15.055911Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37850/133889 blocks (28.3%), 0 events -2026-02-04T19:05:15.210155Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37860/133889 blocks (28.3%), 0 events -2026-02-04T19:05:15.379561Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37870/133889 blocks (28.3%), 0 events -2026-02-04T19:05:15.650553Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37880/133889 blocks (28.3%), 0 events -2026-02-04T19:05:15.772114Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37890/133889 blocks (28.3%), 0 events -2026-02-04T19:05:16.066597Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37900/133889 blocks (28.3%), 0 events -2026-02-04T19:05:16.261607Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37910/133889 blocks (28.3%), 0 events -2026-02-04T19:05:16.466701Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37920/133889 blocks (28.3%), 0 events -2026-02-04T19:05:16.620908Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37930/133889 blocks (28.3%), 0 events -2026-02-04T19:05:16.810462Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37940/133889 blocks (28.3%), 0 events -2026-02-04T19:05:17.114063Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37950/133889 blocks (28.3%), 0 events -2026-02-04T19:05:17.310868Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37960/133889 blocks (28.4%), 0 events -2026-02-04T19:05:17.420699Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37970/133889 blocks (28.4%), 0 events -2026-02-04T19:05:17.694516Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37980/133889 blocks (28.4%), 0 events -2026-02-04T19:05:17.883900Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 37990/133889 blocks (28.4%), 0 events -2026-02-04T19:05:18.022915Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38000/133889 blocks (28.4%), 0 events -2026-02-04T19:05:18.225136Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38010/133889 blocks (28.4%), 0 events -2026-02-04T19:05:18.432052Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38020/133889 blocks (28.4%), 0 events -2026-02-04T19:05:18.721724Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38030/133889 blocks (28.4%), 0 events -2026-02-04T19:05:18.760657Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38040/133889 blocks (28.4%), 0 events -2026-02-04T19:05:19.000178Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38050/133889 blocks (28.4%), 0 events -2026-02-04T19:05:19.243088Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38060/133889 blocks (28.4%), 0 events -2026-02-04T19:05:19.389233Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38070/133889 blocks (28.4%), 0 events -2026-02-04T19:05:19.735345Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38080/133889 blocks (28.4%), 0 events -2026-02-04T19:05:19.774845Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38090/133889 blocks (28.4%), 0 events -2026-02-04T19:05:20.046888Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38100/133889 blocks (28.5%), 0 events -2026-02-04T19:05:20.292176Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38110/133889 blocks (28.5%), 0 events -2026-02-04T19:05:20.418421Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38120/133889 blocks (28.5%), 0 events -2026-02-04T19:05:20.614544Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38130/133889 blocks (28.5%), 0 events -2026-02-04T19:05:20.843652Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38140/133889 blocks (28.5%), 0 events -2026-02-04T19:05:20.989916Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38150/133889 blocks (28.5%), 0 events -2026-02-04T19:05:21.308324Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38160/133889 blocks (28.5%), 0 events -2026-02-04T19:05:21.384743Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38170/133889 blocks (28.5%), 0 events -2026-02-04T19:05:21.615043Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38180/133889 blocks (28.5%), 0 events -2026-02-04T19:05:21.867529Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38190/133889 blocks (28.5%), 0 events -2026-02-04T19:05:21.995636Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38200/133889 blocks (28.5%), 0 events -2026-02-04T19:05:22.265012Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38210/133889 blocks (28.5%), 0 events -2026-02-04T19:05:22.397764Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38220/133889 blocks (28.5%), 0 events -2026-02-04T19:05:22.636403Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38230/133889 blocks (28.6%), 0 events -2026-02-04T19:05:22.916302Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38240/133889 blocks (28.6%), 0 events -2026-02-04T19:05:23.025949Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38250/133889 blocks (28.6%), 0 events -2026-02-04T19:05:23.175657Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38260/133889 blocks (28.6%), 0 events -2026-02-04T19:05:23.449780Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38270/133889 blocks (28.6%), 0 events -2026-02-04T19:05:23.637424Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38280/133889 blocks (28.6%), 0 events -2026-02-04T19:05:23.834169Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38290/133889 blocks (28.6%), 0 events -2026-02-04T19:05:24.000005Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38300/133889 blocks (28.6%), 0 events -2026-02-04T19:05:24.197579Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38310/133889 blocks (28.6%), 0 events -2026-02-04T19:05:24.484463Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38320/133889 blocks (28.6%), 0 events -2026-02-04T19:05:24.618460Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38330/133889 blocks (28.6%), 0 events -2026-02-04T19:05:24.774641Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38340/133889 blocks (28.6%), 0 events -2026-02-04T19:05:25.031066Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38350/133889 blocks (28.6%), 0 events -2026-02-04T19:05:25.217739Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38360/133889 blocks (28.7%), 0 events -2026-02-04T19:05:25.541657Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38370/133889 blocks (28.7%), 0 events -2026-02-04T19:05:25.612027Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38380/133889 blocks (28.7%), 0 events -2026-02-04T19:05:25.841901Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38390/133889 blocks (28.7%), 0 events -2026-02-04T19:05:26.063916Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38400/133889 blocks (28.7%), 0 events -2026-02-04T19:05:26.180315Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38410/133889 blocks (28.7%), 0 events -2026-02-04T19:05:26.394805Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38420/133889 blocks (28.7%), 0 events -2026-02-04T19:05:26.599148Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38430/133889 blocks (28.7%), 0 events -2026-02-04T19:05:26.795360Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38440/133889 blocks (28.7%), 0 events -2026-02-04T19:05:26.982534Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38450/133889 blocks (28.7%), 0 events -2026-02-04T19:05:27.266043Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38460/133889 blocks (28.7%), 0 events -2026-02-04T19:05:27.402128Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38470/133889 blocks (28.7%), 0 events -2026-02-04T19:05:27.653284Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38480/133889 blocks (28.7%), 0 events -2026-02-04T19:05:27.805998Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38490/133889 blocks (28.7%), 0 events -2026-02-04T19:05:27.997352Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38500/133889 blocks (28.8%), 0 events -2026-02-04T19:05:28.193386Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38510/133889 blocks (28.8%), 0 events -2026-02-04T19:05:28.417479Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38520/133889 blocks (28.8%), 0 events -2026-02-04T19:05:28.680822Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38530/133889 blocks (28.8%), 0 events -2026-02-04T19:05:28.847942Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38540/133889 blocks (28.8%), 0 events -2026-02-04T19:05:28.992630Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38550/133889 blocks (28.8%), 0 events -2026-02-04T19:05:29.212401Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38560/133889 blocks (28.8%), 0 events -2026-02-04T19:05:29.429862Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38570/133889 blocks (28.8%), 0 events -2026-02-04T19:05:29.600816Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38580/133889 blocks (28.8%), 0 events -2026-02-04T19:05:29.867416Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38590/133889 blocks (28.8%), 0 events -2026-02-04T19:05:29.988956Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38600/133889 blocks (28.8%), 0 events -2026-02-04T19:05:30.252019Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38610/133889 blocks (28.8%), 0 events -2026-02-04T19:05:30.434118Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38620/133889 blocks (28.8%), 0 events -2026-02-04T19:05:30.643122Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38630/133889 blocks (28.9%), 0 events -2026-02-04T19:05:30.784956Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38640/133889 blocks (28.9%), 0 events -2026-02-04T19:05:31.050159Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38650/133889 blocks (28.9%), 0 events -2026-02-04T19:05:31.467698Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38660/133889 blocks (28.9%), 0 events -2026-02-04T19:05:31.516748Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38670/133889 blocks (28.9%), 0 events -2026-02-04T19:05:31.564899Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38680/133889 blocks (28.9%), 0 events -2026-02-04T19:05:31.863127Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38690/133889 blocks (28.9%), 0 events -2026-02-04T19:05:32.034688Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38700/133889 blocks (28.9%), 0 events -2026-02-04T19:05:32.317907Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38710/133889 blocks (28.9%), 0 events -2026-02-04T19:05:32.363539Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38720/133889 blocks (28.9%), 0 events -2026-02-04T19:05:32.599038Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38730/133889 blocks (28.9%), 0 events -2026-02-04T19:05:32.877244Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38740/133889 blocks (28.9%), 0 events -2026-02-04T19:05:33.038010Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38750/133889 blocks (28.9%), 0 events -2026-02-04T19:05:33.240100Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38760/133889 blocks (28.9%), 0 events -2026-02-04T19:05:33.405534Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38770/133889 blocks (29.0%), 0 events -2026-02-04T19:05:33.595586Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38780/133889 blocks (29.0%), 0 events -2026-02-04T19:05:33.934768Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38790/133889 blocks (29.0%), 0 events -2026-02-04T19:05:34.016481Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38800/133889 blocks (29.0%), 0 events -2026-02-04T19:05:34.231752Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38810/133889 blocks (29.0%), 0 events -2026-02-04T19:05:34.456566Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38820/133889 blocks (29.0%), 0 events -2026-02-04T19:05:34.599174Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38830/133889 blocks (29.0%), 0 events -2026-02-04T19:05:34.820637Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38840/133889 blocks (29.0%), 0 events -2026-02-04T19:05:34.994729Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38850/133889 blocks (29.0%), 0 events -2026-02-04T19:05:35.267658Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38860/133889 blocks (29.0%), 0 events -2026-02-04T19:05:35.464440Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38870/133889 blocks (29.0%), 0 events -2026-02-04T19:05:35.668844Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38880/133889 blocks (29.0%), 0 events -2026-02-04T19:05:35.877449Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38890/133889 blocks (29.0%), 0 events -2026-02-04T19:05:36.066428Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38900/133889 blocks (29.1%), 0 events -2026-02-04T19:05:36.207767Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38910/133889 blocks (29.1%), 0 events -2026-02-04T19:05:36.550790Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38920/133889 blocks (29.1%), 0 events -2026-02-04T19:05:36.588099Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38930/133889 blocks (29.1%), 0 events -2026-02-04T19:05:36.793017Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38940/133889 blocks (29.1%), 0 events -2026-02-04T19:05:37.074436Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38950/133889 blocks (29.1%), 0 events -2026-02-04T19:05:37.223833Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38960/133889 blocks (29.1%), 0 events -2026-02-04T19:05:37.467042Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38970/133889 blocks (29.1%), 0 events -2026-02-04T19:05:37.594287Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38980/133889 blocks (29.1%), 0 events -2026-02-04T19:05:37.869435Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 38990/133889 blocks (29.1%), 0 events -2026-02-04T19:05:38.118398Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39000/133889 blocks (29.1%), 0 events -2026-02-04T19:05:38.154935Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39010/133889 blocks (29.1%), 0 events -2026-02-04T19:05:38.430773Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39020/133889 blocks (29.1%), 0 events -2026-02-04T19:05:38.639884Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39030/133889 blocks (29.2%), 0 events -2026-02-04T19:05:38.866035Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39040/133889 blocks (29.2%), 0 events -2026-02-04T19:05:38.968689Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39050/133889 blocks (29.2%), 0 events -2026-02-04T19:05:39.235986Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39060/133889 blocks (29.2%), 0 events -2026-02-04T19:05:39.443557Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39070/133889 blocks (29.2%), 0 events -2026-02-04T19:05:39.657150Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39080/133889 blocks (29.2%), 0 events -2026-02-04T19:05:39.813108Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39090/133889 blocks (29.2%), 0 events -2026-02-04T19:05:40.016826Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39100/133889 blocks (29.2%), 0 events -2026-02-04T19:05:40.220697Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39110/133889 blocks (29.2%), 0 events -2026-02-04T19:05:40.371917Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39120/133889 blocks (29.2%), 0 events -2026-02-04T19:05:40.614317Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39130/133889 blocks (29.2%), 0 events -2026-02-04T19:05:40.852557Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39140/133889 blocks (29.2%), 0 events -2026-02-04T19:05:40.994538Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39150/133889 blocks (29.2%), 0 events -2026-02-04T19:05:41.275488Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39160/133889 blocks (29.2%), 0 events -2026-02-04T19:05:41.388021Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39170/133889 blocks (29.3%), 0 events -2026-02-04T19:05:41.590639Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39180/133889 blocks (29.3%), 0 events -2026-02-04T19:05:41.788730Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39190/133889 blocks (29.3%), 0 events -2026-02-04T19:05:42.066561Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39200/133889 blocks (29.3%), 0 events -2026-02-04T19:05:42.280189Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39210/133889 blocks (29.3%), 0 events -2026-02-04T19:05:42.366824Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39220/133889 blocks (29.3%), 0 events -2026-02-04T19:05:42.624257Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39230/133889 blocks (29.3%), 0 events -2026-02-04T19:05:42.838918Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39240/133889 blocks (29.3%), 0 events -2026-02-04T19:05:43.032211Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39250/133889 blocks (29.3%), 0 events -2026-02-04T19:05:43.182394Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39260/133889 blocks (29.3%), 0 events -2026-02-04T19:05:43.381406Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39270/133889 blocks (29.3%), 0 events -2026-02-04T19:05:43.617833Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39280/133889 blocks (29.3%), 0 events -2026-02-04T19:05:43.852829Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39290/133889 blocks (29.3%), 0 events -2026-02-04T19:05:44.026012Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39300/133889 blocks (29.4%), 0 events -2026-02-04T19:05:44.252661Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39310/133889 blocks (29.4%), 0 events -2026-02-04T19:05:44.431518Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39320/133889 blocks (29.4%), 0 events -2026-02-04T19:05:44.575082Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39330/133889 blocks (29.4%), 0 events -2026-02-04T19:05:44.899901Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39340/133889 blocks (29.4%), 0 events -2026-02-04T19:05:45.058668Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39350/133889 blocks (29.4%), 0 events -2026-02-04T19:05:45.226184Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39360/133889 blocks (29.4%), 0 events -2026-02-04T19:05:45.457950Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39370/133889 blocks (29.4%), 0 events -2026-02-04T19:05:45.624529Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39380/133889 blocks (29.4%), 0 events -2026-02-04T19:05:45.804997Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39390/133889 blocks (29.4%), 0 events -2026-02-04T19:05:45.984473Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39400/133889 blocks (29.4%), 0 events -2026-02-04T19:05:46.231331Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39410/133889 blocks (29.4%), 0 events -2026-02-04T19:05:46.372377Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39420/133889 blocks (29.4%), 0 events -2026-02-04T19:05:46.592238Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39430/133889 blocks (29.4%), 0 events -2026-02-04T19:05:46.842303Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39440/133889 blocks (29.5%), 0 events -2026-02-04T19:05:47.030406Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39450/133889 blocks (29.5%), 0 events -2026-02-04T19:05:47.234751Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39460/133889 blocks (29.5%), 0 events -2026-02-04T19:05:47.419194Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39470/133889 blocks (29.5%), 0 events -2026-02-04T19:05:47.612356Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39480/133889 blocks (29.5%), 0 events -2026-02-04T19:05:47.857896Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39490/133889 blocks (29.5%), 0 events -2026-02-04T19:05:48.080857Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39500/133889 blocks (29.5%), 0 events -2026-02-04T19:05:48.228378Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39510/133889 blocks (29.5%), 0 events -2026-02-04T19:05:48.375040Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39520/133889 blocks (29.5%), 0 events -2026-02-04T19:05:48.673587Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39530/133889 blocks (29.5%), 0 events -2026-02-04T19:05:48.853837Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39540/133889 blocks (29.5%), 0 events -2026-02-04T19:05:49.001401Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39550/133889 blocks (29.5%), 0 events -2026-02-04T19:05:49.190942Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39560/133889 blocks (29.5%), 0 events -2026-02-04T19:05:49.360328Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39570/133889 blocks (29.6%), 0 events -2026-02-04T19:05:49.649339Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39580/133889 blocks (29.6%), 0 events -2026-02-04T19:05:49.792761Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39590/133889 blocks (29.6%), 0 events -2026-02-04T19:05:50.025046Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39600/133889 blocks (29.6%), 0 events -2026-02-04T19:05:50.262478Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39610/133889 blocks (29.6%), 0 events -2026-02-04T19:05:50.418057Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39620/133889 blocks (29.6%), 0 events -2026-02-04T19:05:50.703294Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39630/133889 blocks (29.6%), 0 events -2026-02-04T19:05:50.813746Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39640/133889 blocks (29.6%), 0 events -2026-02-04T19:05:51.061416Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39650/133889 blocks (29.6%), 0 events -2026-02-04T19:05:51.265465Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39660/133889 blocks (29.6%), 0 events -2026-02-04T19:05:51.378921Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39670/133889 blocks (29.6%), 0 events -2026-02-04T19:05:51.604322Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39680/133889 blocks (29.6%), 0 events -2026-02-04T19:05:51.762686Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39690/133889 blocks (29.6%), 0 events -2026-02-04T19:05:51.986325Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39700/133889 blocks (29.7%), 0 events -2026-02-04T19:05:52.273994Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39710/133889 blocks (29.7%), 0 events -2026-02-04T19:05:52.392848Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39720/133889 blocks (29.7%), 0 events -2026-02-04T19:05:52.573483Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39730/133889 blocks (29.7%), 0 events -2026-02-04T19:05:52.868933Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39740/133889 blocks (29.7%), 0 events -2026-02-04T19:05:53.040252Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39750/133889 blocks (29.7%), 0 events -2026-02-04T19:05:53.190349Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39760/133889 blocks (29.7%), 0 events -2026-02-04T19:05:53.466677Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39770/133889 blocks (29.7%), 0 events -2026-02-04T19:05:53.628342Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39780/133889 blocks (29.7%), 0 events -2026-02-04T19:05:53.842802Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39790/133889 blocks (29.7%), 0 events -2026-02-04T19:05:53.969850Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39800/133889 blocks (29.7%), 0 events -2026-02-04T19:05:54.337894Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39810/133889 blocks (29.7%), 0 events -2026-02-04T19:05:54.380199Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39820/133889 blocks (29.7%), 0 events -2026-02-04T19:05:54.618409Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39830/133889 blocks (29.7%), 0 events -2026-02-04T19:05:54.861566Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39840/133889 blocks (29.8%), 0 events -2026-02-04T19:05:55.068799Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39850/133889 blocks (29.8%), 0 events -2026-02-04T19:05:55.239154Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39860/133889 blocks (29.8%), 0 events -2026-02-04T19:05:55.466736Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39870/133889 blocks (29.8%), 0 events -2026-02-04T19:05:55.578108Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39880/133889 blocks (29.8%), 0 events -2026-02-04T19:05:55.912153Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39890/133889 blocks (29.8%), 0 events -2026-02-04T19:05:56.025516Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39900/133889 blocks (29.8%), 0 events -2026-02-04T19:05:56.216331Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39910/133889 blocks (29.8%), 0 events -2026-02-04T19:05:56.468025Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39920/133889 blocks (29.8%), 0 events -2026-02-04T19:05:56.631403Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39930/133889 blocks (29.8%), 0 events -2026-02-04T19:05:56.843814Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39940/133889 blocks (29.8%), 0 events -2026-02-04T19:05:56.994781Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39950/133889 blocks (29.8%), 0 events -2026-02-04T19:05:57.253976Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39960/133889 blocks (29.8%), 0 events -2026-02-04T19:05:57.516426Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39970/133889 blocks (29.9%), 0 events -2026-02-04T19:05:57.599108Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39980/133889 blocks (29.9%), 0 events -2026-02-04T19:05:57.875348Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 39990/133889 blocks (29.9%), 0 events -2026-02-04T19:05:58.037906Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40000/133889 blocks (29.9%), 0 events -2026-02-04T19:05:58.228778Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40010/133889 blocks (29.9%), 0 events -2026-02-04T19:05:58.433703Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40020/133889 blocks (29.9%), 0 events -2026-02-04T19:05:58.589694Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40030/133889 blocks (29.9%), 0 events -2026-02-04T19:05:58.811345Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40040/133889 blocks (29.9%), 0 events -2026-02-04T19:05:59.055190Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40050/133889 blocks (29.9%), 0 events -2026-02-04T19:05:59.211592Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40060/133889 blocks (29.9%), 0 events -2026-02-04T19:05:59.369826Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40070/133889 blocks (29.9%), 0 events -2026-02-04T19:05:59.660157Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40080/133889 blocks (29.9%), 0 events -2026-02-04T19:05:59.773729Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40090/133889 blocks (29.9%), 0 events -2026-02-04T19:05:59.990957Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40100/133889 blocks (29.9%), 0 events -2026-02-04T19:06:00.239641Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40110/133889 blocks (30.0%), 0 events -2026-02-04T19:06:00.403984Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40120/133889 blocks (30.0%), 0 events -2026-02-04T19:06:00.660869Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40130/133889 blocks (30.0%), 0 events -2026-02-04T19:06:00.832240Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40140/133889 blocks (30.0%), 0 events -2026-02-04T19:06:01.006401Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40150/133889 blocks (30.0%), 0 events -2026-02-04T19:06:01.188599Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40160/133889 blocks (30.0%), 0 events -2026-02-04T19:06:01.422802Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40170/133889 blocks (30.0%), 0 events -2026-02-04T19:06:01.715271Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40180/133889 blocks (30.0%), 0 events -2026-02-04T19:06:01.829309Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40190/133889 blocks (30.0%), 0 events -2026-02-04T19:06:02.021916Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40200/133889 blocks (30.0%), 0 events -2026-02-04T19:06:02.234694Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40210/133889 blocks (30.0%), 0 events -2026-02-04T19:06:02.409066Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40220/133889 blocks (30.0%), 0 events -2026-02-04T19:06:02.617390Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40230/133889 blocks (30.0%), 0 events -2026-02-04T19:06:02.865865Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40240/133889 blocks (30.1%), 0 events -2026-02-04T19:06:02.976893Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40250/133889 blocks (30.1%), 0 events -2026-02-04T19:06:03.282040Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40260/133889 blocks (30.1%), 0 events -2026-02-04T19:06:03.420056Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40270/133889 blocks (30.1%), 0 events -2026-02-04T19:06:03.660245Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40280/133889 blocks (30.1%), 0 events -2026-02-04T19:06:03.806864Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40290/133889 blocks (30.1%), 0 events -2026-02-04T19:06:04.008265Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40300/133889 blocks (30.1%), 0 events -2026-02-04T19:06:04.334446Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40310/133889 blocks (30.1%), 0 events -2026-02-04T19:06:04.374847Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40320/133889 blocks (30.1%), 0 events -2026-02-04T19:06:04.625559Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40330/133889 blocks (30.1%), 0 events -2026-02-04T19:06:04.854304Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40340/133889 blocks (30.1%), 0 events -2026-02-04T19:06:05.040169Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40350/133889 blocks (30.1%), 0 events -2026-02-04T19:06:05.347121Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40360/133889 blocks (30.1%), 0 events -2026-02-04T19:06:05.399679Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40370/133889 blocks (30.2%), 0 events -2026-02-04T19:06:05.571960Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40380/133889 blocks (30.2%), 0 events -2026-02-04T19:06:05.871002Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40390/133889 blocks (30.2%), 0 events -2026-02-04T19:06:05.999436Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40400/133889 blocks (30.2%), 0 events -2026-02-04T19:06:06.201791Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40410/133889 blocks (30.2%), 0 events -2026-02-04T19:06:06.433290Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40420/133889 blocks (30.2%), 0 events -2026-02-04T19:06:06.659894Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40430/133889 blocks (30.2%), 0 events -2026-02-04T19:06:06.920071Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40440/133889 blocks (30.2%), 0 events -2026-02-04T19:06:06.970910Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40450/133889 blocks (30.2%), 0 events -2026-02-04T19:06:07.164078Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40460/133889 blocks (30.2%), 0 events -2026-02-04T19:06:07.445188Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40470/133889 blocks (30.2%), 0 events -2026-02-04T19:06:07.654311Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40480/133889 blocks (30.2%), 0 events -2026-02-04T19:06:07.861666Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40490/133889 blocks (30.2%), 0 events -2026-02-04T19:06:08.002467Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40500/133889 blocks (30.2%), 0 events -2026-02-04T19:06:08.187641Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40510/133889 blocks (30.3%), 0 events -2026-02-04T19:06:08.529768Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40520/133889 blocks (30.3%), 0 events -2026-02-04T19:06:08.566037Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40530/133889 blocks (30.3%), 0 events -2026-02-04T19:06:08.838105Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40540/133889 blocks (30.3%), 0 events -2026-02-04T19:06:09.049590Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40550/133889 blocks (30.3%), 0 events -2026-02-04T19:06:09.249825Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40560/133889 blocks (30.3%), 0 events -2026-02-04T19:06:09.437456Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40570/133889 blocks (30.3%), 0 events -2026-02-04T19:06:09.579362Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40580/133889 blocks (30.3%), 0 events -2026-02-04T19:06:09.782193Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40590/133889 blocks (30.3%), 0 events -2026-02-04T19:06:10.065355Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40600/133889 blocks (30.3%), 0 events -2026-02-04T19:06:10.213256Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40610/133889 blocks (30.3%), 0 events -2026-02-04T19:06:10.386765Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40620/133889 blocks (30.3%), 0 events -2026-02-04T19:06:10.645042Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40630/133889 blocks (30.3%), 0 events -2026-02-04T19:06:10.852843Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40640/133889 blocks (30.4%), 0 events -2026-02-04T19:06:10.976210Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40650/133889 blocks (30.4%), 0 events -2026-02-04T19:06:11.243041Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40660/133889 blocks (30.4%), 0 events -2026-02-04T19:06:11.469816Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40670/133889 blocks (30.4%), 0 events -2026-02-04T19:06:11.671004Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40680/133889 blocks (30.4%), 0 events -2026-02-04T19:06:11.818283Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40690/133889 blocks (30.4%), 0 events -2026-02-04T19:06:12.049623Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40700/133889 blocks (30.4%), 0 events -2026-02-04T19:06:12.197485Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40710/133889 blocks (30.4%), 0 events -2026-02-04T19:06:12.426586Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40720/133889 blocks (30.4%), 0 events -2026-02-04T19:06:12.591592Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40730/133889 blocks (30.4%), 0 events -2026-02-04T19:06:12.870354Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40740/133889 blocks (30.4%), 0 events -2026-02-04T19:06:13.030391Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40750/133889 blocks (30.4%), 0 events -2026-02-04T19:06:13.245411Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40760/133889 blocks (30.4%), 0 events -2026-02-04T19:06:13.370825Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40770/133889 blocks (30.5%), 0 events -2026-02-04T19:06:13.737231Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40780/133889 blocks (30.5%), 0 events -2026-02-04T19:06:13.775240Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40790/133889 blocks (30.5%), 0 events -2026-02-04T19:06:13.979962Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40800/133889 blocks (30.5%), 0 events -2026-02-04T19:06:14.291350Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40810/133889 blocks (30.5%), 0 events -2026-02-04T19:06:14.429139Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40820/133889 blocks (30.5%), 0 events -2026-02-04T19:06:14.638457Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40830/133889 blocks (30.5%), 0 events -2026-02-04T19:06:14.827920Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40840/133889 blocks (30.5%), 0 events -2026-02-04T19:06:15.056612Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40850/133889 blocks (30.5%), 0 events -2026-02-04T19:06:15.309645Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40860/133889 blocks (30.5%), 0 events -2026-02-04T19:06:15.448635Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40870/133889 blocks (30.5%), 0 events -2026-02-04T19:06:15.590403Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40880/133889 blocks (30.5%), 0 events -2026-02-04T19:06:15.887248Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40890/133889 blocks (30.5%), 0 events -2026-02-04T19:06:15.968067Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40900/133889 blocks (30.5%), 0 events -2026-02-04T19:06:16.191944Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40910/133889 blocks (30.6%), 0 events -2026-02-04T19:06:16.407512Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40920/133889 blocks (30.6%), 0 events -2026-02-04T19:06:16.645023Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40930/133889 blocks (30.6%), 0 events -2026-02-04T19:06:16.926185Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40940/133889 blocks (30.6%), 0 events -2026-02-04T19:06:16.963642Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40950/133889 blocks (30.6%), 0 events -2026-02-04T19:06:17.250313Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40960/133889 blocks (30.6%), 0 events -2026-02-04T19:06:17.444759Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40970/133889 blocks (30.6%), 0 events -2026-02-04T19:06:17.584607Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40980/133889 blocks (30.6%), 0 events -2026-02-04T19:06:17.835944Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 40990/133889 blocks (30.6%), 0 events -2026-02-04T19:06:18.016348Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41000/133889 blocks (30.6%), 0 events -2026-02-04T19:06:18.208555Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41010/133889 blocks (30.6%), 0 events -2026-02-04T19:06:18.484675Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41020/133889 blocks (30.6%), 0 events -2026-02-04T19:06:18.654598Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41030/133889 blocks (30.6%), 0 events -2026-02-04T19:06:18.833236Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41040/133889 blocks (30.7%), 0 events -2026-02-04T19:06:19.013899Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41050/133889 blocks (30.7%), 0 events -2026-02-04T19:06:19.267945Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41060/133889 blocks (30.7%), 0 events -2026-02-04T19:06:19.536601Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41070/133889 blocks (30.7%), 0 events -2026-02-04T19:06:19.576384Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41080/133889 blocks (30.7%), 0 events -2026-02-04T19:06:19.817007Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41090/133889 blocks (30.7%), 0 events -2026-02-04T19:06:20.057700Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41100/133889 blocks (30.7%), 0 events -2026-02-04T19:06:20.215392Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41110/133889 blocks (30.7%), 0 events -2026-02-04T19:06:20.387548Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41120/133889 blocks (30.7%), 0 events -2026-02-04T19:06:20.661169Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41130/133889 blocks (30.7%), 0 events -2026-02-04T19:06:20.806041Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41140/133889 blocks (30.7%), 0 events -2026-02-04T19:06:21.110257Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41150/133889 blocks (30.7%), 0 events -2026-02-04T19:06:21.201739Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41160/133889 blocks (30.7%), 0 events -2026-02-04T19:06:21.453322Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41170/133889 blocks (30.7%), 0 events -2026-02-04T19:06:21.645834Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41180/133889 blocks (30.8%), 0 events -2026-02-04T19:06:21.854753Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41190/133889 blocks (30.8%), 0 events -2026-02-04T19:06:21.985301Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41200/133889 blocks (30.8%), 0 events -2026-02-04T19:06:22.252103Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41210/133889 blocks (30.8%), 0 events -2026-02-04T19:06:22.450834Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41220/133889 blocks (30.8%), 0 events -2026-02-04T19:06:22.680499Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41230/133889 blocks (30.8%), 0 events -2026-02-04T19:06:22.796071Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41240/133889 blocks (30.8%), 0 events -2026-02-04T19:06:23.054577Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41250/133889 blocks (30.8%), 0 events -2026-02-04T19:06:23.253642Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41260/133889 blocks (30.8%), 0 events -2026-02-04T19:06:23.396629Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41270/133889 blocks (30.8%), 0 events -2026-02-04T19:06:23.576616Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41280/133889 blocks (30.8%), 0 events -2026-02-04T19:06:23.819362Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41290/133889 blocks (30.8%), 0 events -2026-02-04T19:06:23.978736Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41300/133889 blocks (30.8%), 0 events -2026-02-04T19:06:24.250945Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41310/133889 blocks (30.9%), 0 events -2026-02-04T19:06:24.428320Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41320/133889 blocks (30.9%), 0 events -2026-02-04T19:06:24.650714Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41330/133889 blocks (30.9%), 0 events -2026-02-04T19:06:24.839156Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41340/133889 blocks (30.9%), 0 events -2026-02-04T19:06:24.995397Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41350/133889 blocks (30.9%), 0 events -2026-02-04T19:06:25.269763Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41360/133889 blocks (30.9%), 0 events -2026-02-04T19:06:25.437901Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41370/133889 blocks (30.9%), 0 events -2026-02-04T19:06:25.624474Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41380/133889 blocks (30.9%), 0 events -2026-02-04T19:06:25.828727Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41390/133889 blocks (30.9%), 0 events -2026-02-04T19:06:25.987330Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41400/133889 blocks (30.9%), 0 events -2026-02-04T19:06:26.317040Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41410/133889 blocks (30.9%), 0 events -2026-02-04T19:06:26.409866Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41420/133889 blocks (30.9%), 0 events -2026-02-04T19:06:26.592546Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41430/133889 blocks (30.9%), 0 events -2026-02-04T19:06:26.883881Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41440/133889 blocks (31.0%), 0 events -2026-02-04T19:06:27.042952Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41450/133889 blocks (31.0%), 0 events -2026-02-04T19:06:27.243035Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41460/133889 blocks (31.0%), 0 events -2026-02-04T19:06:27.418556Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41470/133889 blocks (31.0%), 0 events -2026-02-04T19:06:27.571319Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41480/133889 blocks (31.0%), 0 events -2026-02-04T19:06:27.796607Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41490/133889 blocks (31.0%), 0 events -2026-02-04T19:06:28.105418Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41500/133889 blocks (31.0%), 0 events -2026-02-04T19:06:28.234295Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41510/133889 blocks (31.0%), 0 events -2026-02-04T19:06:28.465243Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41520/133889 blocks (31.0%), 0 events -2026-02-04T19:06:28.635596Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41530/133889 blocks (31.0%), 0 events -2026-02-04T19:06:28.836735Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41540/133889 blocks (31.0%), 0 events -2026-02-04T19:06:29.010915Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41550/133889 blocks (31.0%), 0 events -2026-02-04T19:06:29.181761Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41560/133889 blocks (31.0%), 0 events -2026-02-04T19:06:29.463981Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41570/133889 blocks (31.0%), 0 events -2026-02-04T19:06:29.600449Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41580/133889 blocks (31.1%), 0 events -2026-02-04T19:06:29.844963Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41590/133889 blocks (31.1%), 0 events -2026-02-04T19:06:30.061340Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41600/133889 blocks (31.1%), 0 events -2026-02-04T19:06:30.202092Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41610/133889 blocks (31.1%), 0 events -2026-02-04T19:06:30.409053Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41620/133889 blocks (31.1%), 0 events -2026-02-04T19:06:30.596370Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41630/133889 blocks (31.1%), 0 events -2026-02-04T19:06:30.846774Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41640/133889 blocks (31.1%), 0 events -2026-02-04T19:06:31.036422Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41650/133889 blocks (31.1%), 0 events -2026-02-04T19:06:31.183986Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41660/133889 blocks (31.1%), 0 events -2026-02-04T19:06:31.429552Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41670/133889 blocks (31.1%), 0 events -2026-02-04T19:06:31.622521Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41680/133889 blocks (31.1%), 0 events -2026-02-04T19:06:31.777216Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41690/133889 blocks (31.1%), 0 events -2026-02-04T19:06:32.123212Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41700/133889 blocks (31.1%), 0 events -2026-02-04T19:06:32.160803Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41710/133889 blocks (31.2%), 0 events -2026-02-04T19:06:32.401454Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41720/133889 blocks (31.2%), 0 events -2026-02-04T19:06:32.644402Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41730/133889 blocks (31.2%), 0 events -2026-02-04T19:06:32.791514Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41740/133889 blocks (31.2%), 0 events -2026-02-04T19:06:33.133011Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41750/133889 blocks (31.2%), 0 events -2026-02-04T19:06:33.181719Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41760/133889 blocks (31.2%), 0 events -2026-02-04T19:06:33.412635Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41770/133889 blocks (31.2%), 0 events -2026-02-04T19:06:33.659743Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41780/133889 blocks (31.2%), 0 events -2026-02-04T19:06:33.846548Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41790/133889 blocks (31.2%), 0 events -2026-02-04T19:06:34.003137Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41800/133889 blocks (31.2%), 0 events -2026-02-04T19:06:34.221440Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41810/133889 blocks (31.2%), 0 events -2026-02-04T19:06:34.462031Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41820/133889 blocks (31.2%), 0 events -2026-02-04T19:06:34.571267Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41830/133889 blocks (31.2%), 0 events -2026-02-04T19:06:34.902882Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41840/133889 blocks (31.2%), 0 events -2026-02-04T19:06:35.052082Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41850/133889 blocks (31.3%), 0 events -2026-02-04T19:06:35.270981Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41860/133889 blocks (31.3%), 0 events -2026-02-04T19:06:35.469848Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41870/133889 blocks (31.3%), 0 events -2026-02-04T19:06:35.623863Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41880/133889 blocks (31.3%), 0 events -2026-02-04T19:06:35.808264Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41890/133889 blocks (31.3%), 0 events -2026-02-04T19:06:36.051472Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41900/133889 blocks (31.3%), 0 events -2026-02-04T19:06:36.177999Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41910/133889 blocks (31.3%), 0 events -2026-02-04T19:06:36.363262Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41920/133889 blocks (31.3%), 0 events -2026-02-04T19:06:36.665293Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41930/133889 blocks (31.3%), 0 events -2026-02-04T19:06:36.857634Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41940/133889 blocks (31.3%), 0 events -2026-02-04T19:06:37.004892Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41950/133889 blocks (31.3%), 0 events -2026-02-04T19:06:37.178569Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41960/133889 blocks (31.3%), 0 events -2026-02-04T19:06:37.547536Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41970/133889 blocks (31.3%), 0 events -2026-02-04T19:06:37.591396Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41980/133889 blocks (31.4%), 0 events -2026-02-04T19:06:37.907778Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 41990/133889 blocks (31.4%), 0 events -2026-02-04T19:06:38.083646Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42000/133889 blocks (31.4%), 0 events -2026-02-04T19:06:38.197454Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42010/133889 blocks (31.4%), 0 events -2026-02-04T19:06:38.408411Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42020/133889 blocks (31.4%), 0 events -2026-02-04T19:06:38.605093Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42030/133889 blocks (31.4%), 0 events -2026-02-04T19:06:38.770237Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42040/133889 blocks (31.4%), 0 events -2026-02-04T19:06:39.035778Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42050/133889 blocks (31.4%), 0 events -2026-02-04T19:06:39.217528Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42060/133889 blocks (31.4%), 0 events -2026-02-04T19:06:39.455969Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42070/133889 blocks (31.4%), 0 events -2026-02-04T19:06:39.653229Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42080/133889 blocks (31.4%), 0 events -2026-02-04T19:06:39.795838Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42090/133889 blocks (31.4%), 0 events -2026-02-04T19:06:40.064280Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42100/133889 blocks (31.4%), 0 events -2026-02-04T19:06:40.246466Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42110/133889 blocks (31.5%), 0 events -2026-02-04T19:06:40.506967Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42120/133889 blocks (31.5%), 0 events -2026-02-04T19:06:40.559145Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42130/133889 blocks (31.5%), 0 events -2026-02-04T19:06:40.770842Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42140/133889 blocks (31.5%), 0 events -2026-02-04T19:06:41.038178Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42150/133889 blocks (31.5%), 0 events -2026-02-04T19:06:41.215187Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42160/133889 blocks (31.5%), 0 events -2026-02-04T19:06:41.422146Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42170/133889 blocks (31.5%), 0 events -2026-02-04T19:06:41.630291Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42180/133889 blocks (31.5%), 0 events -2026-02-04T19:06:41.793156Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42190/133889 blocks (31.5%), 0 events -2026-02-04T19:06:42.094356Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42200/133889 blocks (31.5%), 0 events -2026-02-04T19:06:42.219156Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42210/133889 blocks (31.5%), 0 events -2026-02-04T19:06:42.405869Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42220/133889 blocks (31.5%), 0 events -2026-02-04T19:06:42.654703Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42230/133889 blocks (31.5%), 0 events -2026-02-04T19:06:42.846467Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42240/133889 blocks (31.5%), 0 events -2026-02-04T19:06:43.130050Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42250/133889 blocks (31.6%), 0 events -2026-02-04T19:06:43.171104Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42260/133889 blocks (31.6%), 0 events -2026-02-04T19:06:43.395398Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42270/133889 blocks (31.6%), 0 events -2026-02-04T19:06:43.667253Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42280/133889 blocks (31.6%), 0 events -2026-02-04T19:06:43.843549Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42290/133889 blocks (31.6%), 0 events -2026-02-04T19:06:44.142611Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42300/133889 blocks (31.6%), 0 events -2026-02-04T19:06:44.178222Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42310/133889 blocks (31.6%), 0 events -2026-02-04T19:06:44.451473Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42320/133889 blocks (31.6%), 0 events -2026-02-04T19:06:44.666122Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42330/133889 blocks (31.6%), 0 events -2026-02-04T19:06:44.861902Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42340/133889 blocks (31.6%), 0 events -2026-02-04T19:06:44.985434Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42350/133889 blocks (31.6%), 0 events -2026-02-04T19:06:45.228142Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42360/133889 blocks (31.6%), 0 events -2026-02-04T19:06:45.421758Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42370/133889 blocks (31.6%), 0 events -2026-02-04T19:06:45.579839Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42380/133889 blocks (31.7%), 0 events -2026-02-04T19:06:45.810075Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42390/133889 blocks (31.7%), 0 events -2026-02-04T19:06:46.047860Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42400/133889 blocks (31.7%), 0 events -2026-02-04T19:06:46.239002Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42410/133889 blocks (31.7%), 0 events -2026-02-04T19:06:46.411326Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42420/133889 blocks (31.7%), 0 events -2026-02-04T19:06:46.619511Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42430/133889 blocks (31.7%), 0 events -2026-02-04T19:06:46.803371Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42440/133889 blocks (31.7%), 0 events -2026-02-04T19:06:47.042701Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42450/133889 blocks (31.7%), 0 events -2026-02-04T19:06:47.333656Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42460/133889 blocks (31.7%), 0 events -2026-02-04T19:06:47.379177Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42470/133889 blocks (31.7%), 0 events -2026-02-04T19:06:47.629385Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42480/133889 blocks (31.7%), 0 events -2026-02-04T19:06:47.853397Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42490/133889 blocks (31.7%), 0 events -2026-02-04T19:06:47.979150Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42500/133889 blocks (31.7%), 0 events -2026-02-04T19:06:48.179287Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42510/133889 blocks (31.7%), 0 events -2026-02-04T19:06:48.460480Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42520/133889 blocks (31.8%), 0 events -2026-02-04T19:06:48.581826Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42530/133889 blocks (31.8%), 0 events -2026-02-04T19:06:48.891682Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42540/133889 blocks (31.8%), 0 events -2026-02-04T19:06:49.043912Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42550/133889 blocks (31.8%), 0 events -2026-02-04T19:06:49.187637Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42560/133889 blocks (31.8%), 0 events -2026-02-04T19:06:49.421270Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42570/133889 blocks (31.8%), 0 events -2026-02-04T19:06:49.633231Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42580/133889 blocks (31.8%), 0 events -2026-02-04T19:06:49.802916Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42590/133889 blocks (31.8%), 0 events -2026-02-04T19:06:49.996642Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42600/133889 blocks (31.8%), 0 events -2026-02-04T19:06:50.188155Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42610/133889 blocks (31.8%), 0 events -2026-02-04T19:06:50.466743Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42620/133889 blocks (31.8%), 0 events -2026-02-04T19:06:50.645197Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42630/133889 blocks (31.8%), 0 events -2026-02-04T19:06:50.773207Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42640/133889 blocks (31.8%), 0 events -2026-02-04T19:06:51.024492Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42650/133889 blocks (31.9%), 0 events -2026-02-04T19:06:51.220174Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42660/133889 blocks (31.9%), 0 events -2026-02-04T19:06:51.512781Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42670/133889 blocks (31.9%), 0 events -2026-02-04T19:06:51.664899Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42680/133889 blocks (31.9%), 0 events -2026-02-04T19:06:51.833736Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42690/133889 blocks (31.9%), 0 events -2026-02-04T19:06:52.040947Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42700/133889 blocks (31.9%), 0 events -2026-02-04T19:06:52.219213Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42710/133889 blocks (31.9%), 0 events -2026-02-04T19:06:52.531645Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42720/133889 blocks (31.9%), 0 events -2026-02-04T19:06:52.569520Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42730/133889 blocks (31.9%), 0 events -2026-02-04T19:06:52.782162Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42740/133889 blocks (31.9%), 0 events -2026-02-04T19:06:53.085721Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42750/133889 blocks (31.9%), 0 events -2026-02-04T19:06:53.197791Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42760/133889 blocks (31.9%), 0 events -2026-02-04T19:06:53.486422Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42770/133889 blocks (31.9%), 0 events -2026-02-04T19:06:53.637484Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42780/133889 blocks (32.0%), 0 events -2026-02-04T19:06:53.784323Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42790/133889 blocks (32.0%), 0 events -2026-02-04T19:06:53.981050Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42800/133889 blocks (32.0%), 0 events -2026-02-04T19:06:54.254324Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42810/133889 blocks (32.0%), 0 events -2026-02-04T19:06:54.431813Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42820/133889 blocks (32.0%), 0 events -2026-02-04T19:06:54.662383Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42830/133889 blocks (32.0%), 0 events -2026-02-04T19:06:54.830429Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42840/133889 blocks (32.0%), 0 events -2026-02-04T19:06:55.033589Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42850/133889 blocks (32.0%), 0 events -2026-02-04T19:06:55.216735Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42860/133889 blocks (32.0%), 0 events -2026-02-04T19:06:55.375539Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42870/133889 blocks (32.0%), 0 events -2026-02-04T19:06:55.723914Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42880/133889 blocks (32.0%), 0 events -2026-02-04T19:06:55.769375Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42890/133889 blocks (32.0%), 0 events -2026-02-04T19:06:55.969688Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42900/133889 blocks (32.0%), 0 events -2026-02-04T19:06:56.236735Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42910/133889 blocks (32.0%), 0 events -2026-02-04T19:06:56.367629Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42920/133889 blocks (32.1%), 0 events -2026-02-04T19:06:56.602223Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42930/133889 blocks (32.1%), 0 events -2026-02-04T19:06:56.844364Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42940/133889 blocks (32.1%), 0 events -2026-02-04T19:06:57.033979Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42950/133889 blocks (32.1%), 0 events -2026-02-04T19:06:57.283569Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42960/133889 blocks (32.1%), 0 events -2026-02-04T19:06:57.428412Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42970/133889 blocks (32.1%), 0 events -2026-02-04T19:06:57.628004Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42980/133889 blocks (32.1%), 0 events -2026-02-04T19:06:57.812332Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 42990/133889 blocks (32.1%), 0 events -2026-02-04T19:06:58.064488Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43000/133889 blocks (32.1%), 0 events -2026-02-04T19:06:58.338679Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43010/133889 blocks (32.1%), 0 events -2026-02-04T19:06:58.378240Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43020/133889 blocks (32.1%), 0 events -2026-02-04T19:06:58.580983Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43030/133889 blocks (32.1%), 0 events -2026-02-04T19:06:58.854640Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43040/133889 blocks (32.1%), 0 events -2026-02-04T19:06:58.986503Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43050/133889 blocks (32.2%), 0 events -2026-02-04T19:06:59.230180Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43060/133889 blocks (32.2%), 0 events -2026-02-04T19:06:59.453976Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43070/133889 blocks (32.2%), 0 events -2026-02-04T19:06:59.571318Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43080/133889 blocks (32.2%), 0 events -2026-02-04T19:06:59.871142Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43090/133889 blocks (32.2%), 0 events -2026-02-04T19:07:00.024975Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43100/133889 blocks (32.2%), 0 events -2026-02-04T19:07:00.221603Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43110/133889 blocks (32.2%), 0 events -2026-02-04T19:07:00.439864Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43120/133889 blocks (32.2%), 0 events -2026-02-04T19:07:00.640022Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43130/133889 blocks (32.2%), 0 events -2026-02-04T19:07:00.789481Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43140/133889 blocks (32.2%), 0 events -2026-02-04T19:07:01.048720Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43150/133889 blocks (32.2%), 0 events -2026-02-04T19:07:01.212069Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43160/133889 blocks (32.2%), 0 events -2026-02-04T19:07:01.444368Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43170/133889 blocks (32.2%), 0 events -2026-02-04T19:07:01.577779Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43180/133889 blocks (32.3%), 0 events -2026-02-04T19:07:01.817052Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43190/133889 blocks (32.3%), 0 events -2026-02-04T19:07:01.998908Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43200/133889 blocks (32.3%), 0 events -2026-02-04T19:07:02.208426Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43210/133889 blocks (32.3%), 0 events -2026-02-04T19:07:02.525366Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43220/133889 blocks (32.3%), 0 events -2026-02-04T19:07:02.563396Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43230/133889 blocks (32.3%), 0 events -2026-02-04T19:07:02.848925Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43240/133889 blocks (32.3%), 0 events -2026-02-04T19:07:03.064116Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43250/133889 blocks (32.3%), 0 events -2026-02-04T19:07:03.241601Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43260/133889 blocks (32.3%), 0 events -2026-02-04T19:07:03.395210Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43270/133889 blocks (32.3%), 0 events -2026-02-04T19:07:03.589548Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43280/133889 blocks (32.3%), 0 events -2026-02-04T19:07:03.809792Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43290/133889 blocks (32.3%), 0 events -2026-02-04T19:07:04.100959Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43300/133889 blocks (32.3%), 0 events -2026-02-04T19:07:04.219392Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43310/133889 blocks (32.3%), 0 events -2026-02-04T19:07:04.405070Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43320/133889 blocks (32.4%), 0 events -2026-02-04T19:07:04.628894Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43330/133889 blocks (32.4%), 0 events -2026-02-04T19:07:04.806265Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43340/133889 blocks (32.4%), 0 events -2026-02-04T19:07:05.113254Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43350/133889 blocks (32.4%), 0 events -2026-02-04T19:07:05.189527Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43360/133889 blocks (32.4%), 0 events -2026-02-04T19:07:05.374957Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43370/133889 blocks (32.4%), 0 events -2026-02-04T19:07:05.674628Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43380/133889 blocks (32.4%), 0 events -2026-02-04T19:07:05.831907Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43390/133889 blocks (32.4%), 0 events -2026-02-04T19:07:05.979868Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43400/133889 blocks (32.4%), 0 events -2026-02-04T19:07:06.204997Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43410/133889 blocks (32.4%), 0 events -2026-02-04T19:07:06.382736Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43420/133889 blocks (32.4%), 0 events -2026-02-04T19:07:06.576317Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43430/133889 blocks (32.4%), 0 events -2026-02-04T19:07:06.793321Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43440/133889 blocks (32.4%), 0 events -2026-02-04T19:07:06.988058Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43450/133889 blocks (32.5%), 0 events -2026-02-04T19:07:07.269762Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43460/133889 blocks (32.5%), 0 events -2026-02-04T19:07:07.388532Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43470/133889 blocks (32.5%), 0 events -2026-02-04T19:07:07.567834Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43480/133889 blocks (32.5%), 0 events -2026-02-04T19:07:07.852867Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43490/133889 blocks (32.5%), 0 events -2026-02-04T19:07:07.986111Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43500/133889 blocks (32.5%), 0 events -2026-02-04T19:07:08.261224Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43510/133889 blocks (32.5%), 0 events -2026-02-04T19:07:08.379068Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43520/133889 blocks (32.5%), 0 events -2026-02-04T19:07:08.664454Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43530/133889 blocks (32.5%), 0 events -2026-02-04T19:07:08.855219Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43540/133889 blocks (32.5%), 0 events -2026-02-04T19:07:08.976298Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43550/133889 blocks (32.5%), 0 events -2026-02-04T19:07:09.180922Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43560/133889 blocks (32.5%), 0 events -2026-02-04T19:07:09.433188Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43570/133889 blocks (32.5%), 0 events -2026-02-04T19:07:09.662137Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43580/133889 blocks (32.5%), 0 events -2026-02-04T19:07:09.865206Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43590/133889 blocks (32.6%), 0 events -2026-02-04T19:07:10.017028Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43600/133889 blocks (32.6%), 0 events -2026-02-04T19:07:10.225899Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43610/133889 blocks (32.6%), 0 events -2026-02-04T19:07:10.387506Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43620/133889 blocks (32.6%), 0 events -2026-02-04T19:07:10.645367Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43630/133889 blocks (32.6%), 0 events -2026-02-04T19:07:10.879769Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43640/133889 blocks (32.6%), 0 events -2026-02-04T19:07:10.986660Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43650/133889 blocks (32.6%), 0 events -2026-02-04T19:07:11.206871Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43660/133889 blocks (32.6%), 0 events -2026-02-04T19:07:11.442385Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43670/133889 blocks (32.6%), 0 events -2026-02-04T19:07:11.633964Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43680/133889 blocks (32.6%), 0 events -2026-02-04T19:07:11.784329Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43690/133889 blocks (32.6%), 0 events -2026-02-04T19:07:12.015880Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43700/133889 blocks (32.6%), 0 events -2026-02-04T19:07:12.230790Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43710/133889 blocks (32.6%), 0 events -2026-02-04T19:07:12.499643Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43720/133889 blocks (32.7%), 0 events -2026-02-04T19:07:12.616031Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43730/133889 blocks (32.7%), 0 events -2026-02-04T19:07:12.811582Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43740/133889 blocks (32.7%), 0 events -2026-02-04T19:07:13.054649Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43750/133889 blocks (32.7%), 0 events -2026-02-04T19:07:13.201629Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43760/133889 blocks (32.7%), 0 events -2026-02-04T19:07:13.377109Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43770/133889 blocks (32.7%), 0 events -2026-02-04T19:07:13.621423Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43780/133889 blocks (32.7%), 0 events -2026-02-04T19:07:13.866875Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43790/133889 blocks (32.7%), 0 events -2026-02-04T19:07:14.060661Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43800/133889 blocks (32.7%), 0 events -2026-02-04T19:07:14.245350Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43810/133889 blocks (32.7%), 0 events -2026-02-04T19:07:14.435441Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43820/133889 blocks (32.7%), 0 events -2026-02-04T19:07:14.586490Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43830/133889 blocks (32.7%), 0 events -2026-02-04T19:07:14.861725Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43840/133889 blocks (32.7%), 0 events -2026-02-04T19:07:15.075243Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43850/133889 blocks (32.8%), 0 events -2026-02-04T19:07:15.183054Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43860/133889 blocks (32.8%), 0 events -2026-02-04T19:07:15.377012Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43870/133889 blocks (32.8%), 0 events -2026-02-04T19:07:15.654280Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43880/133889 blocks (32.8%), 0 events -2026-02-04T19:07:15.826100Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43890/133889 blocks (32.8%), 0 events -2026-02-04T19:07:15.983915Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43900/133889 blocks (32.8%), 0 events -2026-02-04T19:07:16.173996Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43910/133889 blocks (32.8%), 0 events -2026-02-04T19:07:16.385762Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43920/133889 blocks (32.8%), 0 events -2026-02-04T19:07:16.729809Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43930/133889 blocks (32.8%), 0 events -2026-02-04T19:07:16.768992Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43940/133889 blocks (32.8%), 0 events -2026-02-04T19:07:17.020703Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43950/133889 blocks (32.8%), 0 events -2026-02-04T19:07:17.205603Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43960/133889 blocks (32.8%), 0 events -2026-02-04T19:07:17.368037Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43970/133889 blocks (32.8%), 0 events -2026-02-04T19:07:17.596795Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43980/133889 blocks (32.8%), 0 events -2026-02-04T19:07:17.803599Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 43990/133889 blocks (32.9%), 0 events -2026-02-04T19:07:18.011647Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44000/133889 blocks (32.9%), 0 events -2026-02-04T19:07:18.256697Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44010/133889 blocks (32.9%), 0 events -2026-02-04T19:07:18.454797Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44020/133889 blocks (32.9%), 0 events -2026-02-04T19:07:18.568235Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44030/133889 blocks (32.9%), 0 events -2026-02-04T19:07:18.816191Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44040/133889 blocks (32.9%), 0 events -2026-02-04T19:07:18.978428Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44050/133889 blocks (32.9%), 0 events -2026-02-04T19:07:19.268701Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44060/133889 blocks (32.9%), 0 events -2026-02-04T19:07:19.415355Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44070/133889 blocks (32.9%), 0 events -2026-02-04T19:07:19.637445Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44080/133889 blocks (32.9%), 0 events -2026-02-04T19:07:19.828373Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44090/133889 blocks (32.9%), 0 events -2026-02-04T19:07:20.024896Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44100/133889 blocks (32.9%), 0 events -2026-02-04T19:07:20.173426Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44110/133889 blocks (32.9%), 0 events -2026-02-04T19:07:20.427717Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44120/133889 blocks (33.0%), 0 events -2026-02-04T19:07:20.588748Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44130/133889 blocks (33.0%), 0 events -2026-02-04T19:07:20.879427Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44140/133889 blocks (33.0%), 0 events -2026-02-04T19:07:20.970274Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44150/133889 blocks (33.0%), 0 events -2026-02-04T19:07:21.183547Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44160/133889 blocks (33.0%), 0 events -2026-02-04T19:07:21.433687Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44170/133889 blocks (33.0%), 0 events -2026-02-04T19:07:21.571358Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44180/133889 blocks (33.0%), 0 events -2026-02-04T19:07:21.889833Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44190/133889 blocks (33.0%), 0 events -2026-02-04T19:07:21.975975Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44200/133889 blocks (33.0%), 0 events -2026-02-04T19:07:22.212188Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44210/133889 blocks (33.0%), 0 events -2026-02-04T19:07:22.445236Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44220/133889 blocks (33.0%), 0 events -2026-02-04T19:07:22.651221Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44230/133889 blocks (33.0%), 0 events -2026-02-04T19:07:22.940306Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44240/133889 blocks (33.0%), 0 events -2026-02-04T19:07:22.983637Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44250/133889 blocks (33.0%), 0 events -2026-02-04T19:07:23.215721Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44260/133889 blocks (33.1%), 0 events -2026-02-04T19:07:23.499183Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44270/133889 blocks (33.1%), 0 events -2026-02-04T19:07:23.641117Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44280/133889 blocks (33.1%), 0 events -2026-02-04T19:07:23.794009Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44290/133889 blocks (33.1%), 0 events -2026-02-04T19:07:24.053354Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44300/133889 blocks (33.1%), 0 events -2026-02-04T19:07:24.237101Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44310/133889 blocks (33.1%), 0 events -2026-02-04T19:07:24.418888Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44320/133889 blocks (33.1%), 0 events -2026-02-04T19:07:24.647196Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44330/133889 blocks (33.1%), 0 events -2026-02-04T19:07:24.807100Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44340/133889 blocks (33.1%), 0 events -2026-02-04T19:07:25.072913Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44350/133889 blocks (33.1%), 0 events -2026-02-04T19:07:25.241576Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44360/133889 blocks (33.1%), 0 events -2026-02-04T19:07:25.447028Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44370/133889 blocks (33.1%), 0 events -2026-02-04T19:07:25.626588Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44380/133889 blocks (33.1%), 0 events -2026-02-04T19:07:25.812823Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44390/133889 blocks (33.2%), 0 events -2026-02-04T19:07:25.986725Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44400/133889 blocks (33.2%), 0 events -2026-02-04T19:07:26.188127Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44410/133889 blocks (33.2%), 0 events -2026-02-04T19:07:26.412656Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44420/133889 blocks (33.2%), 0 events -2026-02-04T19:07:26.654212Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44430/133889 blocks (33.2%), 0 events -2026-02-04T19:07:26.819469Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44440/133889 blocks (33.2%), 0 events -2026-02-04T19:07:27.027131Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44450/133889 blocks (33.2%), 0 events -2026-02-04T19:07:27.262983Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44460/133889 blocks (33.2%), 0 events -2026-02-04T19:07:27.460068Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44470/133889 blocks (33.2%), 0 events -2026-02-04T19:07:27.686165Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44480/133889 blocks (33.2%), 0 events -2026-02-04T19:07:27.774409Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44490/133889 blocks (33.2%), 0 events -2026-02-04T19:07:28.043026Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44500/133889 blocks (33.2%), 0 events -2026-02-04T19:07:28.217140Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44510/133889 blocks (33.2%), 0 events -2026-02-04T19:07:28.377482Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44520/133889 blocks (33.3%), 0 events -2026-02-04T19:07:28.744371Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44530/133889 blocks (33.3%), 0 events -2026-02-04T19:07:28.786784Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44540/133889 blocks (33.3%), 0 events -2026-02-04T19:07:28.964933Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44550/133889 blocks (33.3%), 0 events -2026-02-04T19:07:29.228630Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44560/133889 blocks (33.3%), 0 events -2026-02-04T19:07:29.650441Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44570/133889 blocks (33.3%), 0 events -2026-02-04T19:07:29.754328Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44580/133889 blocks (33.3%), 0 events -2026-02-04T19:07:29.794172Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44590/133889 blocks (33.3%), 0 events -2026-02-04T19:07:29.995375Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44600/133889 blocks (33.3%), 0 events -2026-02-04T19:07:30.318843Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44610/133889 blocks (33.3%), 0 events -2026-02-04T19:07:30.358787Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44620/133889 blocks (33.3%), 0 events -2026-02-04T19:07:30.619104Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44630/133889 blocks (33.3%), 0 events -2026-02-04T19:07:30.860711Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44640/133889 blocks (33.3%), 0 events -2026-02-04T19:07:30.969701Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44650/133889 blocks (33.3%), 0 events -2026-02-04T19:07:31.210430Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44660/133889 blocks (33.4%), 0 events -2026-02-04T19:07:31.415726Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44670/133889 blocks (33.4%), 0 events -2026-02-04T19:07:31.596736Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44680/133889 blocks (33.4%), 0 events -2026-02-04T19:07:31.882280Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44690/133889 blocks (33.4%), 0 events -2026-02-04T19:07:32.015221Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44700/133889 blocks (33.4%), 0 events -2026-02-04T19:07:32.192371Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44710/133889 blocks (33.4%), 0 events -2026-02-04T19:07:32.476437Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44720/133889 blocks (33.4%), 0 events -2026-02-04T19:07:32.640282Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44730/133889 blocks (33.4%), 0 events -2026-02-04T19:07:32.787920Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44740/133889 blocks (33.4%), 0 events -2026-02-04T19:07:33.032968Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44750/133889 blocks (33.4%), 0 events -2026-02-04T19:07:33.203677Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44760/133889 blocks (33.4%), 0 events -2026-02-04T19:07:33.464393Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44770/133889 blocks (33.4%), 0 events -2026-02-04T19:07:33.559976Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44780/133889 blocks (33.4%), 0 events -2026-02-04T19:07:33.828956Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44790/133889 blocks (33.5%), 0 events -2026-02-04T19:07:33.980989Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44800/133889 blocks (33.5%), 0 events -2026-02-04T19:07:34.261897Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44810/133889 blocks (33.5%), 0 events -2026-02-04T19:07:34.376026Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44820/133889 blocks (33.5%), 0 events -2026-02-04T19:07:34.582314Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44830/133889 blocks (33.5%), 0 events -2026-02-04T19:07:34.770963Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44840/133889 blocks (33.5%), 0 events -2026-02-04T19:07:35.030731Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44850/133889 blocks (33.5%), 0 events -2026-02-04T19:07:35.186434Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44860/133889 blocks (33.5%), 0 events -2026-02-04T19:07:35.561950Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44870/133889 blocks (33.5%), 0 events -2026-02-04T19:07:35.602534Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44880/133889 blocks (33.5%), 0 events -2026-02-04T19:07:35.851825Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44890/133889 blocks (33.5%), 0 events -2026-02-04T19:07:36.084075Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44900/133889 blocks (33.5%), 0 events -2026-02-04T19:07:36.259798Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44910/133889 blocks (33.5%), 0 events -2026-02-04T19:07:36.425371Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44920/133889 blocks (33.5%), 0 events -2026-02-04T19:07:36.603072Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44930/133889 blocks (33.6%), 0 events -2026-02-04T19:07:36.804180Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44940/133889 blocks (33.6%), 0 events -2026-02-04T19:07:37.093670Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44950/133889 blocks (33.6%), 0 events -2026-02-04T19:07:37.193880Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44960/133889 blocks (33.6%), 0 events -2026-02-04T19:07:37.375794Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44970/133889 blocks (33.6%), 0 events -2026-02-04T19:07:37.649681Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44980/133889 blocks (33.6%), 0 events -2026-02-04T19:07:37.817738Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 44990/133889 blocks (33.6%), 0 events -2026-02-04T19:07:37.977945Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45000/133889 blocks (33.6%), 0 events -2026-02-04T19:07:38.210067Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45010/133889 blocks (33.6%), 0 events -2026-02-04T19:07:38.388908Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45020/133889 blocks (33.6%), 0 events -2026-02-04T19:07:38.698959Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45030/133889 blocks (33.6%), 0 events -2026-02-04T19:07:38.768930Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45040/133889 blocks (33.6%), 0 events -2026-02-04T19:07:39.002913Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45050/133889 blocks (33.6%), 0 events -2026-02-04T19:07:39.222440Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45060/133889 blocks (33.7%), 0 events -2026-02-04T19:07:39.417509Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45070/133889 blocks (33.7%), 0 events -2026-02-04T19:07:39.714723Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45080/133889 blocks (33.7%), 0 events -2026-02-04T19:07:39.808261Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45090/133889 blocks (33.7%), 0 events -2026-02-04T19:07:40.012497Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45100/133889 blocks (33.7%), 0 events -2026-02-04T19:07:40.275598Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45110/133889 blocks (33.7%), 0 events -2026-02-04T19:07:40.437215Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45120/133889 blocks (33.7%), 0 events -2026-02-04T19:07:40.574687Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45130/133889 blocks (33.7%), 0 events -2026-02-04T19:07:40.804361Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45140/133889 blocks (33.7%), 0 events -2026-02-04T19:07:40.989224Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45150/133889 blocks (33.7%), 0 events -2026-02-04T19:07:41.290535Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45160/133889 blocks (33.7%), 0 events -2026-02-04T19:07:41.406022Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45170/133889 blocks (33.7%), 0 events -2026-02-04T19:07:41.592526Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45180/133889 blocks (33.7%), 0 events -2026-02-04T19:07:41.851005Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45190/133889 blocks (33.8%), 0 events -2026-02-04T19:07:42.034383Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45200/133889 blocks (33.8%), 0 events -2026-02-04T19:07:42.190339Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45210/133889 blocks (33.8%), 0 events -2026-02-04T19:07:42.372760Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45220/133889 blocks (33.8%), 0 events -2026-02-04T19:07:42.654007Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45230/133889 blocks (33.8%), 0 events -2026-02-04T19:07:42.859338Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45240/133889 blocks (33.8%), 0 events -2026-02-04T19:07:43.053995Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45250/133889 blocks (33.8%), 0 events -2026-02-04T19:07:43.170368Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45260/133889 blocks (33.8%), 0 events -2026-02-04T19:07:43.445590Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45270/133889 blocks (33.8%), 0 events -2026-02-04T19:07:43.578070Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45280/133889 blocks (33.8%), 0 events -2026-02-04T19:07:43.908876Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45290/133889 blocks (33.8%), 0 events -2026-02-04T19:07:44.103074Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45300/133889 blocks (33.8%), 0 events -2026-02-04T19:07:44.232976Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45310/133889 blocks (33.8%), 0 events -2026-02-04T19:07:44.468494Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45320/133889 blocks (33.8%), 0 events -2026-02-04T19:07:44.661807Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45330/133889 blocks (33.9%), 0 events -2026-02-04T19:07:44.806542Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45340/133889 blocks (33.9%), 0 events -2026-02-04T19:07:44.999873Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45350/133889 blocks (33.9%), 0 events -2026-02-04T19:07:45.224560Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45360/133889 blocks (33.9%), 0 events -2026-02-04T19:07:45.367922Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45370/133889 blocks (33.9%), 0 events -2026-02-04T19:07:45.567592Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45380/133889 blocks (33.9%), 0 events -2026-02-04T19:07:45.831848Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45390/133889 blocks (33.9%), 0 events -2026-02-04T19:07:46.038727Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45400/133889 blocks (33.9%), 0 events -2026-02-04T19:07:46.191552Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45410/133889 blocks (33.9%), 0 events -2026-02-04T19:07:46.381330Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45420/133889 blocks (33.9%), 0 events -2026-02-04T19:07:46.657957Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45430/133889 blocks (33.9%), 0 events -2026-02-04T19:07:46.839141Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45440/133889 blocks (33.9%), 0 events -2026-02-04T19:07:47.083672Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45450/133889 blocks (33.9%), 0 events -2026-02-04T19:07:47.289032Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45460/133889 blocks (34.0%), 0 events -2026-02-04T19:07:47.391716Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45470/133889 blocks (34.0%), 0 events -2026-02-04T19:07:47.625698Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45480/133889 blocks (34.0%), 0 events -2026-02-04T19:07:47.814166Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45490/133889 blocks (34.0%), 0 events -2026-02-04T19:07:47.985143Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45500/133889 blocks (34.0%), 0 events -2026-02-04T19:07:48.330592Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45510/133889 blocks (34.0%), 0 events -2026-02-04T19:07:48.367951Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45520/133889 blocks (34.0%), 0 events -2026-02-04T19:07:48.659744Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45530/133889 blocks (34.0%), 0 events -2026-02-04T19:07:48.851848Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45540/133889 blocks (34.0%), 0 events -2026-02-04T19:07:48.997996Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45550/133889 blocks (34.0%), 0 events -2026-02-04T19:07:49.211621Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45560/133889 blocks (34.0%), 0 events -2026-02-04T19:07:49.403832Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45570/133889 blocks (34.0%), 0 events -2026-02-04T19:07:49.710789Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45580/133889 blocks (34.0%), 0 events -2026-02-04T19:07:49.901544Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45590/133889 blocks (34.1%), 0 events -2026-02-04T19:07:49.996440Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45600/133889 blocks (34.1%), 0 events -2026-02-04T19:07:50.247826Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45610/133889 blocks (34.1%), 0 events -2026-02-04T19:07:50.429993Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45620/133889 blocks (34.1%), 0 events -2026-02-04T19:07:50.722773Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45630/133889 blocks (34.1%), 0 events -2026-02-04T19:07:50.815352Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45640/133889 blocks (34.1%), 0 events -2026-02-04T19:07:51.003868Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45650/133889 blocks (34.1%), 0 events -2026-02-04T19:07:51.288704Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45660/133889 blocks (34.1%), 0 events -2026-02-04T19:07:51.483039Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45670/133889 blocks (34.1%), 0 events -2026-02-04T19:07:51.605357Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45680/133889 blocks (34.1%), 0 events -2026-02-04T19:07:51.808286Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45690/133889 blocks (34.1%), 0 events -2026-02-04T19:07:52.021781Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45700/133889 blocks (34.1%), 0 events -2026-02-04T19:07:52.331788Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45710/133889 blocks (34.1%), 0 events -2026-02-04T19:07:52.367577Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45720/133889 blocks (34.1%), 0 events -2026-02-04T19:07:52.655455Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45730/133889 blocks (34.2%), 0 events -2026-02-04T19:07:52.851395Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45740/133889 blocks (34.2%), 0 events -2026-02-04T19:07:53.051347Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45750/133889 blocks (34.2%), 0 events -2026-02-04T19:07:53.246419Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45760/133889 blocks (34.2%), 0 events -2026-02-04T19:07:53.408198Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45770/133889 blocks (34.2%), 0 events -2026-02-04T19:07:53.620701Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45780/133889 blocks (34.2%), 0 events -2026-02-04T19:07:53.867694Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45790/133889 blocks (34.2%), 0 events -2026-02-04T19:07:54.065019Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45800/133889 blocks (34.2%), 0 events -2026-02-04T19:07:54.165579Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45810/133889 blocks (34.2%), 0 events -2026-02-04T19:07:54.428299Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45820/133889 blocks (34.2%), 0 events -2026-02-04T19:07:54.565883Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45830/133889 blocks (34.2%), 0 events -2026-02-04T19:07:54.822732Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45840/133889 blocks (34.2%), 0 events -2026-02-04T19:07:55.032129Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45850/133889 blocks (34.2%), 0 events -2026-02-04T19:07:55.256423Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45860/133889 blocks (34.3%), 0 events -2026-02-04T19:07:55.478249Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45870/133889 blocks (34.3%), 0 events -2026-02-04T19:07:55.657866Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45880/133889 blocks (34.3%), 0 events -2026-02-04T19:07:55.764293Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45890/133889 blocks (34.3%), 0 events -2026-02-04T19:07:56.005651Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45900/133889 blocks (34.3%), 0 events -2026-02-04T19:07:56.258189Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45910/133889 blocks (34.3%), 0 events -2026-02-04T19:07:56.524846Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45920/133889 blocks (34.3%), 0 events -2026-02-04T19:07:56.559816Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45930/133889 blocks (34.3%), 0 events -2026-02-04T19:07:56.797432Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45940/133889 blocks (34.3%), 0 events -2026-02-04T19:07:57.043790Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45950/133889 blocks (34.3%), 0 events -2026-02-04T19:07:57.226045Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45960/133889 blocks (34.3%), 0 events -2026-02-04T19:07:57.406917Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45970/133889 blocks (34.3%), 0 events -2026-02-04T19:07:57.579652Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45980/133889 blocks (34.3%), 0 events -2026-02-04T19:07:57.859562Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 45990/133889 blocks (34.3%), 0 events -2026-02-04T19:07:58.118372Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46000/133889 blocks (34.4%), 0 events -2026-02-04T19:07:58.158934Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46010/133889 blocks (34.4%), 0 events -2026-02-04T19:07:58.384433Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46020/133889 blocks (34.4%), 0 events -2026-02-04T19:07:58.645768Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46030/133889 blocks (34.4%), 0 events -2026-02-04T19:07:58.837607Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46040/133889 blocks (34.4%), 0 events -2026-02-04T19:07:59.109986Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46050/133889 blocks (34.4%), 0 events -2026-02-04T19:07:59.243784Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46060/133889 blocks (34.4%), 0 events -2026-02-04T19:07:59.427805Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46070/133889 blocks (34.4%), 0 events -2026-02-04T19:07:59.664431Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46080/133889 blocks (34.4%), 0 events -2026-02-04T19:07:59.803546Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46090/133889 blocks (34.4%), 0 events -2026-02-04T19:08:00.001108Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46100/133889 blocks (34.4%), 0 events -2026-02-04T19:08:00.192965Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46110/133889 blocks (34.4%), 0 events -2026-02-04T19:08:00.416599Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46120/133889 blocks (34.4%), 0 events -2026-02-04T19:08:00.716822Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46130/133889 blocks (34.5%), 0 events -2026-02-04T19:08:00.782018Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46140/133889 blocks (34.5%), 0 events -2026-02-04T19:08:00.977552Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46150/133889 blocks (34.5%), 0 events -2026-02-04T19:08:01.250026Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46160/133889 blocks (34.5%), 0 events -2026-02-04T19:08:01.409778Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46170/133889 blocks (34.5%), 0 events -2026-02-04T19:08:01.602458Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46180/133889 blocks (34.5%), 0 events -2026-02-04T19:08:01.818816Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46190/133889 blocks (34.5%), 0 events -2026-02-04T19:08:02.043138Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46200/133889 blocks (34.5%), 0 events -2026-02-04T19:08:02.258552Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46210/133889 blocks (34.5%), 0 events -2026-02-04T19:08:02.407671Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46220/133889 blocks (34.5%), 0 events -2026-02-04T19:08:02.869174Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46230/133889 blocks (34.5%), 0 events -2026-02-04T19:08:02.910406Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46240/133889 blocks (34.5%), 0 events -2026-02-04T19:08:03.040475Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46250/133889 blocks (34.5%), 0 events -2026-02-04T19:08:03.305069Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46260/133889 blocks (34.6%), 0 events -2026-02-04T19:08:03.368995Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46270/133889 blocks (34.6%), 0 events -2026-02-04T19:08:03.622808Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46280/133889 blocks (34.6%), 0 events -2026-02-04T19:08:03.859525Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46290/133889 blocks (34.6%), 0 events -2026-02-04T19:08:04.029506Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46300/133889 blocks (34.6%), 0 events -2026-02-04T19:08:04.186317Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46310/133889 blocks (34.6%), 0 events -2026-02-04T19:08:04.389190Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46320/133889 blocks (34.6%), 0 events -2026-02-04T19:08:04.615108Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46330/133889 blocks (34.6%), 0 events -2026-02-04T19:08:04.772519Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46340/133889 blocks (34.6%), 0 events -2026-02-04T19:08:05.036548Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46350/133889 blocks (34.6%), 0 events -2026-02-04T19:08:05.184695Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46360/133889 blocks (34.6%), 0 events -2026-02-04T19:08:05.458281Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46370/133889 blocks (34.6%), 0 events -2026-02-04T19:08:05.589515Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46380/133889 blocks (34.6%), 0 events -2026-02-04T19:08:05.810752Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46390/133889 blocks (34.6%), 0 events -2026-02-04T19:08:05.978219Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46400/133889 blocks (34.7%), 0 events -2026-02-04T19:08:06.164759Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46410/133889 blocks (34.7%), 0 events -2026-02-04T19:08:06.486249Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46420/133889 blocks (34.7%), 0 events -2026-02-04T19:08:06.598053Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46430/133889 blocks (34.7%), 0 events -2026-02-04T19:08:06.776922Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46440/133889 blocks (34.7%), 0 events -2026-02-04T19:08:07.009846Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46450/133889 blocks (34.7%), 0 events -2026-02-04T19:08:07.262288Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46460/133889 blocks (34.7%), 0 events -2026-02-04T19:08:07.375742Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46470/133889 blocks (34.7%), 0 events -2026-02-04T19:08:07.592289Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46480/133889 blocks (34.7%), 0 events -2026-02-04T19:08:07.810134Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46490/133889 blocks (34.7%), 0 events -2026-02-04T19:08:08.062046Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46500/133889 blocks (34.7%), 0 events -2026-02-04T19:08:08.252551Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46510/133889 blocks (34.7%), 0 events -2026-02-04T19:08:08.456399Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46520/133889 blocks (34.7%), 0 events -2026-02-04T19:08:08.658175Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46530/133889 blocks (34.8%), 0 events -2026-02-04T19:08:08.796143Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46540/133889 blocks (34.8%), 0 events -2026-02-04T19:08:08.973006Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46550/133889 blocks (34.8%), 0 events -2026-02-04T19:08:09.313125Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46560/133889 blocks (34.8%), 0 events -2026-02-04T19:08:09.444996Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46570/133889 blocks (34.8%), 0 events -2026-02-04T19:08:09.630903Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46580/133889 blocks (34.8%), 0 events -2026-02-04T19:08:09.827524Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46590/133889 blocks (34.8%), 0 events -2026-02-04T19:08:09.991581Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46600/133889 blocks (34.8%), 0 events -2026-02-04T19:08:10.216332Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46610/133889 blocks (34.8%), 0 events -2026-02-04T19:08:10.458808Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46620/133889 blocks (34.8%), 0 events -2026-02-04T19:08:10.680677Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46630/133889 blocks (34.8%), 0 events -2026-02-04T19:08:10.875757Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46640/133889 blocks (34.8%), 0 events -2026-02-04T19:08:11.024702Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46650/133889 blocks (34.8%), 0 events -2026-02-04T19:08:11.210706Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46660/133889 blocks (34.8%), 0 events -2026-02-04T19:08:11.421888Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46670/133889 blocks (34.9%), 0 events -2026-02-04T19:08:11.693463Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46680/133889 blocks (34.9%), 0 events -2026-02-04T19:08:11.843620Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46690/133889 blocks (34.9%), 0 events -2026-02-04T19:08:12.026221Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46700/133889 blocks (34.9%), 0 events -2026-02-04T19:08:12.252023Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46710/133889 blocks (34.9%), 0 events -2026-02-04T19:08:12.381696Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46720/133889 blocks (34.9%), 0 events -2026-02-04T19:08:12.607835Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46730/133889 blocks (34.9%), 0 events -2026-02-04T19:08:12.834385Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46740/133889 blocks (34.9%), 0 events -2026-02-04T19:08:12.997037Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46750/133889 blocks (34.9%), 0 events -2026-02-04T19:08:13.266787Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46760/133889 blocks (34.9%), 0 events -2026-02-04T19:08:13.384397Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46770/133889 blocks (34.9%), 0 events -2026-02-04T19:08:13.610295Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46780/133889 blocks (34.9%), 0 events -2026-02-04T19:08:13.830888Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46790/133889 blocks (34.9%), 0 events -2026-02-04T19:08:13.972492Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46800/133889 blocks (35.0%), 0 events -2026-02-04T19:08:14.316299Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46810/133889 blocks (35.0%), 0 events -2026-02-04T19:08:14.513893Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46820/133889 blocks (35.0%), 0 events -2026-02-04T19:08:14.577982Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46830/133889 blocks (35.0%), 0 events -2026-02-04T19:08:14.875931Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46840/133889 blocks (35.0%), 0 events -2026-02-04T19:08:15.074452Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46850/133889 blocks (35.0%), 0 events -2026-02-04T19:08:15.266664Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46860/133889 blocks (35.0%), 0 events -2026-02-04T19:08:15.444912Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46870/133889 blocks (35.0%), 0 events -2026-02-04T19:08:15.599096Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46880/133889 blocks (35.0%), 0 events -2026-02-04T19:08:15.889324Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46890/133889 blocks (35.0%), 0 events -2026-02-04T19:08:15.971894Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46900/133889 blocks (35.0%), 0 events -2026-02-04T19:08:16.230630Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46910/133889 blocks (35.0%), 0 events -2026-02-04T19:08:16.468165Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46920/133889 blocks (35.0%), 0 events -2026-02-04T19:08:16.615018Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46930/133889 blocks (35.1%), 0 events -2026-02-04T19:08:16.838190Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46940/133889 blocks (35.1%), 0 events -2026-02-04T19:08:17.013649Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46950/133889 blocks (35.1%), 0 events -2026-02-04T19:08:17.172315Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46960/133889 blocks (35.1%), 0 events -2026-02-04T19:08:17.463005Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46970/133889 blocks (35.1%), 0 events -2026-02-04T19:08:17.653536Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46980/133889 blocks (35.1%), 0 events -2026-02-04T19:08:17.786213Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 46990/133889 blocks (35.1%), 0 events -2026-02-04T19:08:18.022247Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47000/133889 blocks (35.1%), 0 events -2026-02-04T19:08:18.252747Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47010/133889 blocks (35.1%), 0 events -2026-02-04T19:08:18.363283Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47020/133889 blocks (35.1%), 0 events -2026-02-04T19:08:18.604996Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47030/133889 blocks (35.1%), 0 events -2026-02-04T19:08:18.799869Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47040/133889 blocks (35.1%), 0 events -2026-02-04T19:08:19.077967Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47050/133889 blocks (35.1%), 0 events -2026-02-04T19:08:19.193844Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47060/133889 blocks (35.1%), 0 events -2026-02-04T19:08:19.398082Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47070/133889 blocks (35.2%), 0 events -2026-02-04T19:08:19.624855Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47080/133889 blocks (35.2%), 0 events -2026-02-04T19:08:19.830266Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47090/133889 blocks (35.2%), 0 events -2026-02-04T19:08:19.992984Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47100/133889 blocks (35.2%), 0 events -2026-02-04T19:08:20.195877Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47110/133889 blocks (35.2%), 0 events -2026-02-04T19:08:20.374218Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47120/133889 blocks (35.2%), 0 events -2026-02-04T19:08:20.638042Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47130/133889 blocks (35.2%), 0 events -2026-02-04T19:08:20.792821Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47140/133889 blocks (35.2%), 0 events -2026-02-04T19:08:21.028806Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47150/133889 blocks (35.2%), 0 events -2026-02-04T19:08:21.248399Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47160/133889 blocks (35.2%), 0 events -2026-02-04T19:08:21.390230Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47170/133889 blocks (35.2%), 0 events -2026-02-04T19:08:21.698543Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47180/133889 blocks (35.2%), 0 events -2026-02-04T19:08:21.817588Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47190/133889 blocks (35.2%), 0 events -2026-02-04T19:08:21.990519Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47200/133889 blocks (35.3%), 0 events -2026-02-04T19:08:22.218462Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47210/133889 blocks (35.3%), 0 events -2026-02-04T19:08:22.444762Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47220/133889 blocks (35.3%), 0 events -2026-02-04T19:08:22.604081Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47230/133889 blocks (35.3%), 0 events -2026-02-04T19:08:22.789632Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47240/133889 blocks (35.3%), 0 events -2026-02-04T19:08:23.010782Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47250/133889 blocks (35.3%), 0 events -2026-02-04T19:08:23.260980Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47260/133889 blocks (35.3%), 0 events -2026-02-04T19:08:23.382666Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47270/133889 blocks (35.3%), 0 events -2026-02-04T19:08:23.627989Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47280/133889 blocks (35.3%), 0 events -2026-02-04T19:08:23.840357Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47290/133889 blocks (35.3%), 0 events -2026-02-04T19:08:24.019787Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47300/133889 blocks (35.3%), 0 events -2026-02-04T19:08:24.310456Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47310/133889 blocks (35.3%), 0 events -2026-02-04T19:08:24.453952Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47320/133889 blocks (35.3%), 0 events -2026-02-04T19:08:24.604967Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47330/133889 blocks (35.3%), 0 events -2026-02-04T19:08:24.836135Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47340/133889 blocks (35.4%), 0 events -2026-02-04T19:08:25.058209Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47350/133889 blocks (35.4%), 0 events -2026-02-04T19:08:25.324512Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47360/133889 blocks (35.4%), 0 events -2026-02-04T19:08:25.372480Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47370/133889 blocks (35.4%), 0 events -2026-02-04T19:08:25.597218Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47380/133889 blocks (35.4%), 0 events -2026-02-04T19:08:25.882699Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47390/133889 blocks (35.4%), 0 events -2026-02-04T19:08:25.985561Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47400/133889 blocks (35.4%), 0 events -2026-02-04T19:08:26.221810Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47410/133889 blocks (35.4%), 0 events -2026-02-04T19:08:26.417495Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47420/133889 blocks (35.4%), 0 events -2026-02-04T19:08:26.646003Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47430/133889 blocks (35.4%), 0 events -2026-02-04T19:08:26.767009Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47440/133889 blocks (35.4%), 0 events -2026-02-04T19:08:27.017018Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47450/133889 blocks (35.4%), 0 events -2026-02-04T19:08:27.228833Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47460/133889 blocks (35.4%), 0 events -2026-02-04T19:08:27.465293Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47470/133889 blocks (35.5%), 0 events -2026-02-04T19:08:27.626437Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47480/133889 blocks (35.5%), 0 events -2026-02-04T19:08:27.811090Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47490/133889 blocks (35.5%), 0 events -2026-02-04T19:08:27.981760Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47500/133889 blocks (35.5%), 0 events -2026-02-04T19:08:28.172055Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47510/133889 blocks (35.5%), 0 events -2026-02-04T19:08:28.510131Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47520/133889 blocks (35.5%), 0 events -2026-02-04T19:08:28.624772Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47530/133889 blocks (35.5%), 0 events -2026-02-04T19:08:28.805989Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47540/133889 blocks (35.5%), 0 events -2026-02-04T19:08:29.025437Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47550/133889 blocks (35.5%), 0 events -2026-02-04T19:08:29.234614Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47560/133889 blocks (35.5%), 0 events -2026-02-04T19:08:29.369709Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47570/133889 blocks (35.5%), 0 events -2026-02-04T19:08:29.649347Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47580/133889 blocks (35.5%), 0 events -2026-02-04T19:08:29.807001Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47590/133889 blocks (35.5%), 0 events -2026-02-04T19:08:30.078073Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47600/133889 blocks (35.6%), 0 events -2026-02-04T19:08:30.257424Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47610/133889 blocks (35.6%), 0 events -2026-02-04T19:08:30.433235Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47620/133889 blocks (35.6%), 0 events -2026-02-04T19:08:30.635139Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47630/133889 blocks (35.6%), 0 events -2026-02-04T19:08:30.855266Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47640/133889 blocks (35.6%), 0 events -2026-02-04T19:08:31.195032Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47650/133889 blocks (35.6%), 0 events -2026-02-04T19:08:31.234499Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47660/133889 blocks (35.6%), 0 events -2026-02-04T19:08:31.402773Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47670/133889 blocks (35.6%), 0 events -2026-02-04T19:08:31.657172Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47680/133889 blocks (35.6%), 0 events -2026-02-04T19:08:31.848236Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47690/133889 blocks (35.6%), 0 events -2026-02-04T19:08:31.977546Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47700/133889 blocks (35.6%), 0 events -2026-02-04T19:08:32.192599Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47710/133889 blocks (35.6%), 0 events -2026-02-04T19:08:32.423780Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47720/133889 blocks (35.6%), 0 events -2026-02-04T19:08:32.699088Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47730/133889 blocks (35.6%), 0 events -2026-02-04T19:08:32.776059Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47740/133889 blocks (35.7%), 0 events -2026-02-04T19:08:32.962912Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47750/133889 blocks (35.7%), 0 events -2026-02-04T19:08:33.220416Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47760/133889 blocks (35.7%), 0 events -2026-02-04T19:08:33.367459Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47770/133889 blocks (35.7%), 0 events -2026-02-04T19:08:33.714576Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47780/133889 blocks (35.7%), 0 events -2026-02-04T19:08:33.806854Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47790/133889 blocks (35.7%), 0 events -2026-02-04T19:08:34.015624Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47800/133889 blocks (35.7%), 0 events -2026-02-04T19:08:34.269951Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47810/133889 blocks (35.7%), 0 events -2026-02-04T19:08:34.391001Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47820/133889 blocks (35.7%), 0 events -2026-02-04T19:08:34.575502Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47830/133889 blocks (35.7%), 0 events -2026-02-04T19:08:34.835664Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47840/133889 blocks (35.7%), 0 events -2026-02-04T19:08:35.029286Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47850/133889 blocks (35.7%), 0 events -2026-02-04T19:08:35.338744Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47860/133889 blocks (35.7%), 0 events -2026-02-04T19:08:35.373542Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47870/133889 blocks (35.8%), 0 events -2026-02-04T19:08:35.575605Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47880/133889 blocks (35.8%), 0 events -2026-02-04T19:08:35.843003Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47890/133889 blocks (35.8%), 0 events -2026-02-04T19:08:36.022815Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47900/133889 blocks (35.8%), 0 events -2026-02-04T19:08:36.207066Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47910/133889 blocks (35.8%), 0 events -2026-02-04T19:08:36.446369Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47920/133889 blocks (35.8%), 0 events -2026-02-04T19:08:36.566769Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47930/133889 blocks (35.8%), 0 events -2026-02-04T19:08:36.860252Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47940/133889 blocks (35.8%), 0 events -2026-02-04T19:08:37.005534Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47950/133889 blocks (35.8%), 0 events -2026-02-04T19:08:37.260157Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47960/133889 blocks (35.8%), 0 events -2026-02-04T19:08:37.431314Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47970/133889 blocks (35.8%), 0 events -2026-02-04T19:08:37.621894Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47980/133889 blocks (35.8%), 0 events -2026-02-04T19:08:37.909079Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 47990/133889 blocks (35.8%), 0 events -2026-02-04T19:08:37.961201Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48000/133889 blocks (35.9%), 0 events -2026-02-04T19:08:38.213565Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48010/133889 blocks (35.9%), 0 events -2026-02-04T19:08:38.470165Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48020/133889 blocks (35.9%), 0 events -2026-02-04T19:08:38.647871Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48030/133889 blocks (35.9%), 0 events -2026-02-04T19:08:38.835793Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48040/133889 blocks (35.9%), 0 events -2026-02-04T19:08:38.991697Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48050/133889 blocks (35.9%), 0 events -2026-02-04T19:08:39.188120Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48060/133889 blocks (35.9%), 0 events -2026-02-04T19:08:39.381365Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48070/133889 blocks (35.9%), 0 events -2026-02-04T19:08:39.599581Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48080/133889 blocks (35.9%), 0 events -2026-02-04T19:08:39.861460Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48090/133889 blocks (35.9%), 0 events -2026-02-04T19:08:40.046141Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48100/133889 blocks (35.9%), 0 events -2026-02-04T19:08:40.208430Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48110/133889 blocks (35.9%), 0 events -2026-02-04T19:08:40.388888Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48120/133889 blocks (35.9%), 0 events -2026-02-04T19:08:40.655823Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48130/133889 blocks (35.9%), 0 events -2026-02-04T19:08:40.780177Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48140/133889 blocks (36.0%), 0 events -2026-02-04T19:08:41.089023Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48150/133889 blocks (36.0%), 0 events -2026-02-04T19:08:41.217534Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48160/133889 blocks (36.0%), 0 events -2026-02-04T19:08:41.401744Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48170/133889 blocks (36.0%), 0 events -2026-02-04T19:08:41.617333Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48180/133889 blocks (36.0%), 0 events -2026-02-04T19:08:41.786366Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48190/133889 blocks (36.0%), 0 events -2026-02-04T19:08:41.998256Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48200/133889 blocks (36.0%), 0 events -2026-02-04T19:08:42.173887Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48210/133889 blocks (36.0%), 0 events -2026-02-04T19:08:42.434001Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48220/133889 blocks (36.0%), 0 events -2026-02-04T19:08:42.660349Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48230/133889 blocks (36.0%), 0 events -2026-02-04T19:08:42.816729Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48240/133889 blocks (36.0%), 0 events -2026-02-04T19:08:42.982219Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48250/133889 blocks (36.0%), 0 events -2026-02-04T19:08:43.185152Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48260/133889 blocks (36.0%), 0 events -2026-02-04T19:08:43.427968Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48270/133889 blocks (36.1%), 0 events -2026-02-04T19:08:43.706795Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48280/133889 blocks (36.1%), 0 events -2026-02-04T19:08:43.840888Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48290/133889 blocks (36.1%), 0 events -2026-02-04T19:08:44.020991Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48300/133889 blocks (36.1%), 0 events -2026-02-04T19:08:44.230387Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48310/133889 blocks (36.1%), 0 events -2026-02-04T19:08:44.385420Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48320/133889 blocks (36.1%), 0 events -2026-02-04T19:08:44.605092Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48330/133889 blocks (36.1%), 0 events -2026-02-04T19:08:44.785919Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48340/133889 blocks (36.1%), 0 events -2026-02-04T19:08:45.031232Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48350/133889 blocks (36.1%), 0 events -2026-02-04T19:08:45.250655Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48360/133889 blocks (36.1%), 0 events -2026-02-04T19:08:45.476625Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48370/133889 blocks (36.1%), 0 events -2026-02-04T19:08:45.593572Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48380/133889 blocks (36.1%), 0 events -2026-02-04T19:08:45.814592Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48390/133889 blocks (36.1%), 0 events -2026-02-04T19:08:46.000749Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48400/133889 blocks (36.1%), 0 events -2026-02-04T19:08:46.296653Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48410/133889 blocks (36.2%), 0 events -2026-02-04T19:08:46.359781Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48420/133889 blocks (36.2%), 0 events -2026-02-04T19:08:46.590473Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48430/133889 blocks (36.2%), 0 events -2026-02-04T19:08:46.862236Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48440/133889 blocks (36.2%), 0 events -2026-02-04T19:08:47.059841Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48450/133889 blocks (36.2%), 0 events -2026-02-04T19:08:47.213311Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48460/133889 blocks (36.2%), 0 events -2026-02-04T19:08:47.541958Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48470/133889 blocks (36.2%), 0 events -2026-02-04T19:08:47.586074Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48480/133889 blocks (36.2%), 0 events -2026-02-04T19:08:47.900612Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48490/133889 blocks (36.2%), 0 events -2026-02-04T19:08:47.960117Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48500/133889 blocks (36.2%), 0 events -2026-02-04T19:08:48.170229Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48510/133889 blocks (36.2%), 0 events -2026-02-04T19:08:48.423202Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48520/133889 blocks (36.2%), 0 events -2026-02-04T19:08:48.626019Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48530/133889 blocks (36.2%), 0 events -2026-02-04T19:08:48.816234Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48540/133889 blocks (36.3%), 0 events -2026-02-04T19:08:49.115500Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48550/133889 blocks (36.3%), 0 events -2026-02-04T19:08:49.174618Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48560/133889 blocks (36.3%), 0 events -2026-02-04T19:08:49.475074Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48570/133889 blocks (36.3%), 0 events -2026-02-04T19:08:49.670680Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48580/133889 blocks (36.3%), 0 events -2026-02-04T19:08:49.776252Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48590/133889 blocks (36.3%), 0 events -2026-02-04T19:08:50.004953Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48600/133889 blocks (36.3%), 0 events -2026-02-04T19:08:50.197303Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48610/133889 blocks (36.3%), 0 events -2026-02-04T19:08:50.391133Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48620/133889 blocks (36.3%), 0 events -2026-02-04T19:08:50.592587Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48630/133889 blocks (36.3%), 0 events -2026-02-04T19:08:50.805606Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48640/133889 blocks (36.3%), 0 events -2026-02-04T19:08:51.054589Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48650/133889 blocks (36.3%), 0 events -2026-02-04T19:08:51.419984Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48660/133889 blocks (36.3%), 0 events -2026-02-04T19:08:51.539558Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48670/133889 blocks (36.4%), 0 events -2026-02-04T19:08:51.579550Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48680/133889 blocks (36.4%), 0 events -2026-02-04T19:08:51.800085Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48690/133889 blocks (36.4%), 0 events -2026-02-04T19:08:51.972622Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48700/133889 blocks (36.4%), 0 events -2026-02-04T19:08:52.189079Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48710/133889 blocks (36.4%), 0 events -2026-02-04T19:08:52.359970Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48720/133889 blocks (36.4%), 0 events -2026-02-04T19:08:52.629710Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48730/133889 blocks (36.4%), 0 events -2026-02-04T19:08:52.806496Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48740/133889 blocks (36.4%), 0 events -2026-02-04T19:08:52.962405Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48750/133889 blocks (36.4%), 0 events -2026-02-04T19:08:53.211925Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48760/133889 blocks (36.4%), 0 events -2026-02-04T19:08:53.429444Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48770/133889 blocks (36.4%), 0 events -2026-02-04T19:08:53.670208Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48780/133889 blocks (36.4%), 0 events -2026-02-04T19:08:53.864901Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48790/133889 blocks (36.4%), 0 events -2026-02-04T19:08:54.060999Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48800/133889 blocks (36.4%), 0 events -2026-02-04T19:08:54.253485Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48810/133889 blocks (36.5%), 0 events -2026-02-04T19:08:54.391341Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48820/133889 blocks (36.5%), 0 events -2026-02-04T19:08:54.685016Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48830/133889 blocks (36.5%), 0 events -2026-02-04T19:08:54.881843Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48840/133889 blocks (36.5%), 0 events -2026-02-04T19:08:54.998717Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48850/133889 blocks (36.5%), 0 events -2026-02-04T19:08:55.251522Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48860/133889 blocks (36.5%), 0 events -2026-02-04T19:08:55.407109Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48870/133889 blocks (36.5%), 0 events -2026-02-04T19:08:55.584931Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48880/133889 blocks (36.5%), 0 events -2026-02-04T19:08:55.769471Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48890/133889 blocks (36.5%), 0 events -2026-02-04T19:08:56.015355Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48900/133889 blocks (36.5%), 0 events -2026-02-04T19:08:56.295241Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48910/133889 blocks (36.5%), 0 events -2026-02-04T19:08:56.413290Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48920/133889 blocks (36.5%), 0 events -2026-02-04T19:08:56.649281Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48930/133889 blocks (36.5%), 0 events -2026-02-04T19:08:56.813645Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48940/133889 blocks (36.6%), 0 events -2026-02-04T19:08:56.979306Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48950/133889 blocks (36.6%), 0 events -2026-02-04T19:08:57.196515Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48960/133889 blocks (36.6%), 0 events -2026-02-04T19:08:57.455850Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48970/133889 blocks (36.6%), 0 events -2026-02-04T19:08:57.612910Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48980/133889 blocks (36.6%), 0 events -2026-02-04T19:08:57.859247Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 48990/133889 blocks (36.6%), 0 events -2026-02-04T19:08:58.038407Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49000/133889 blocks (36.6%), 0 events -2026-02-04T19:08:58.248349Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49010/133889 blocks (36.6%), 0 events -2026-02-04T19:08:58.390420Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49020/133889 blocks (36.6%), 0 events -2026-02-04T19:08:58.580519Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49030/133889 blocks (36.6%), 0 events -2026-02-04T19:08:58.778671Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49040/133889 blocks (36.6%), 0 events -2026-02-04T19:08:58.987449Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49050/133889 blocks (36.6%), 0 events -2026-02-04T19:08:59.209216Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49060/133889 blocks (36.6%), 0 events -2026-02-04T19:08:59.437028Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49070/133889 blocks (36.6%), 0 events -2026-02-04T19:08:59.631704Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49080/133889 blocks (36.7%), 0 events -2026-02-04T19:08:59.789508Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49090/133889 blocks (36.7%), 0 events -2026-02-04T19:09:00.037470Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49100/133889 blocks (36.7%), 0 events -2026-02-04T19:09:00.219825Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49110/133889 blocks (36.7%), 0 events -2026-02-04T19:09:00.453400Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49120/133889 blocks (36.7%), 0 events -2026-02-04T19:09:00.655534Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49130/133889 blocks (36.7%), 0 events -2026-02-04T19:09:00.759501Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49140/133889 blocks (36.7%), 0 events -2026-02-04T19:09:01.045606Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49150/133889 blocks (36.7%), 0 events -2026-02-04T19:09:01.172016Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49160/133889 blocks (36.7%), 0 events -2026-02-04T19:09:01.370796Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49170/133889 blocks (36.7%), 0 events -2026-02-04T19:09:01.619653Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49180/133889 blocks (36.7%), 0 events -2026-02-04T19:09:01.780005Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49190/133889 blocks (36.7%), 0 events -2026-02-04T19:09:02.066872Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49200/133889 blocks (36.7%), 0 events -2026-02-04T19:09:02.169757Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49210/133889 blocks (36.8%), 0 events -2026-02-04T19:09:02.424548Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49220/133889 blocks (36.8%), 0 events -2026-02-04T19:09:02.593708Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49230/133889 blocks (36.8%), 0 events -2026-02-04T19:09:02.815570Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49240/133889 blocks (36.8%), 0 events -2026-02-04T19:09:03.104733Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49250/133889 blocks (36.8%), 0 events -2026-02-04T19:09:03.251063Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49260/133889 blocks (36.8%), 0 events -2026-02-04T19:09:03.423010Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49270/133889 blocks (36.8%), 0 events -2026-02-04T19:09:03.650484Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49280/133889 blocks (36.8%), 0 events -2026-02-04T19:09:03.818066Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49290/133889 blocks (36.8%), 0 events -2026-02-04T19:09:04.120751Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49300/133889 blocks (36.8%), 0 events -2026-02-04T19:09:04.159592Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49310/133889 blocks (36.8%), 0 events -2026-02-04T19:09:04.448211Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49320/133889 blocks (36.8%), 0 events -2026-02-04T19:09:04.646211Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49330/133889 blocks (36.8%), 0 events -2026-02-04T19:09:04.783875Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49340/133889 blocks (36.9%), 0 events -2026-02-04T19:09:05.035042Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49350/133889 blocks (36.9%), 0 events -2026-02-04T19:09:05.204676Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49360/133889 blocks (36.9%), 0 events -2026-02-04T19:09:05.392694Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49370/133889 blocks (36.9%), 0 events -2026-02-04T19:09:05.726292Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49380/133889 blocks (36.9%), 0 events -2026-02-04T19:09:05.766353Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49390/133889 blocks (36.9%), 0 events -2026-02-04T19:09:06.004882Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49400/133889 blocks (36.9%), 0 events -2026-02-04T19:09:06.254105Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49410/133889 blocks (36.9%), 0 events -2026-02-04T19:09:06.444521Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49420/133889 blocks (36.9%), 0 events -2026-02-04T19:09:06.570596Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49430/133889 blocks (36.9%), 0 events -2026-02-04T19:09:06.800772Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49440/133889 blocks (36.9%), 0 events -2026-02-04T19:09:07.044982Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49450/133889 blocks (36.9%), 0 events -2026-02-04T19:09:07.267810Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49460/133889 blocks (36.9%), 0 events -2026-02-04T19:09:07.448637Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49470/133889 blocks (36.9%), 0 events -2026-02-04T19:09:07.642935Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49480/133889 blocks (37.0%), 0 events -2026-02-04T19:09:07.824458Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49490/133889 blocks (37.0%), 0 events -2026-02-04T19:09:08.040017Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49500/133889 blocks (37.0%), 0 events -2026-02-04T19:09:08.219626Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49510/133889 blocks (37.0%), 0 events -2026-02-04T19:09:08.459390Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49520/133889 blocks (37.0%), 0 events -2026-02-04T19:09:08.605338Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49530/133889 blocks (37.0%), 0 events -2026-02-04T19:09:08.841020Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49540/133889 blocks (37.0%), 0 events -2026-02-04T19:09:09.041260Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49550/133889 blocks (37.0%), 0 events -2026-02-04T19:09:09.259414Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49560/133889 blocks (37.0%), 0 events -2026-02-04T19:09:09.395313Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49570/133889 blocks (37.0%), 0 events -2026-02-04T19:09:09.641382Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49580/133889 blocks (37.0%), 0 events -2026-02-04T19:09:09.774421Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49590/133889 blocks (37.0%), 0 events -2026-02-04T19:09:10.026125Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49600/133889 blocks (37.0%), 0 events -2026-02-04T19:09:10.192137Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49610/133889 blocks (37.1%), 0 events -2026-02-04T19:09:10.450019Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49620/133889 blocks (37.1%), 0 events -2026-02-04T19:09:10.642322Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49630/133889 blocks (37.1%), 0 events -2026-02-04T19:09:10.808945Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49640/133889 blocks (37.1%), 0 events -2026-02-04T19:09:11.048819Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49650/133889 blocks (37.1%), 0 events -2026-02-04T19:09:11.246907Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49660/133889 blocks (37.1%), 0 events -2026-02-04T19:09:11.498319Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49670/133889 blocks (37.1%), 0 events -2026-02-04T19:09:11.572091Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49680/133889 blocks (37.1%), 0 events -2026-02-04T19:09:11.777356Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49690/133889 blocks (37.1%), 0 events -2026-02-04T19:09:12.019477Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49700/133889 blocks (37.1%), 0 events -2026-02-04T19:09:12.248445Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49710/133889 blocks (37.1%), 0 events -2026-02-04T19:09:12.377476Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49720/133889 blocks (37.1%), 0 events -2026-02-04T19:09:12.630250Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49730/133889 blocks (37.1%), 0 events -2026-02-04T19:09:12.810484Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49740/133889 blocks (37.1%), 0 events -2026-02-04T19:09:13.065748Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49750/133889 blocks (37.2%), 0 events -2026-02-04T19:09:13.233296Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49760/133889 blocks (37.2%), 0 events -2026-02-04T19:09:13.411243Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49770/133889 blocks (37.2%), 0 events -2026-02-04T19:09:13.611190Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49780/133889 blocks (37.2%), 0 events -2026-02-04T19:09:13.805155Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49790/133889 blocks (37.2%), 0 events -2026-02-04T19:09:14.119098Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49800/133889 blocks (37.2%), 0 events -2026-02-04T19:09:14.158384Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49810/133889 blocks (37.2%), 0 events -2026-02-04T19:09:14.371286Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49820/133889 blocks (37.2%), 0 events -2026-02-04T19:09:14.637028Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49830/133889 blocks (37.2%), 0 events -2026-02-04T19:09:14.840565Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49840/133889 blocks (37.2%), 0 events -2026-02-04T19:09:15.024014Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49850/133889 blocks (37.2%), 0 events -2026-02-04T19:09:15.225996Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49860/133889 blocks (37.2%), 0 events -2026-02-04T19:09:15.457955Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49870/133889 blocks (37.2%), 0 events -2026-02-04T19:09:15.691381Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49880/133889 blocks (37.3%), 0 events -2026-02-04T19:09:15.840918Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49890/133889 blocks (37.3%), 0 events -2026-02-04T19:09:16.055127Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49900/133889 blocks (37.3%), 0 events -2026-02-04T19:09:16.219781Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49910/133889 blocks (37.3%), 0 events -2026-02-04T19:09:16.401178Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49920/133889 blocks (37.3%), 0 events -2026-02-04T19:09:16.704118Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49930/133889 blocks (37.3%), 0 events -2026-02-04T19:09:16.816312Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49940/133889 blocks (37.3%), 0 events -2026-02-04T19:09:17.055243Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49950/133889 blocks (37.3%), 0 events -2026-02-04T19:09:17.268318Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49960/133889 blocks (37.3%), 0 events -2026-02-04T19:09:17.417379Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49970/133889 blocks (37.3%), 0 events -2026-02-04T19:09:17.750466Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49980/133889 blocks (37.3%), 0 events -2026-02-04T19:09:17.791836Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 49990/133889 blocks (37.3%), 0 events -2026-02-04T19:09:18.033164Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50000/133889 blocks (37.3%), 0 events -2026-02-04T19:09:18.315158Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50010/133889 blocks (37.4%), 0 events -2026-02-04T19:09:18.441875Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50020/133889 blocks (37.4%), 0 events -2026-02-04T19:09:18.582573Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50030/133889 blocks (37.4%), 0 events -2026-02-04T19:09:18.841487Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50040/133889 blocks (37.4%), 0 events -2026-02-04T19:09:19.067627Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50050/133889 blocks (37.4%), 0 events -2026-02-04T19:09:19.198566Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50060/133889 blocks (37.4%), 0 events -2026-02-04T19:09:19.365723Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50070/133889 blocks (37.4%), 0 events -2026-02-04T19:09:19.645404Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50080/133889 blocks (37.4%), 0 events -2026-02-04T19:09:19.881451Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50090/133889 blocks (37.4%), 0 events -2026-02-04T19:09:19.975125Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50100/133889 blocks (37.4%), 0 events -2026-02-04T19:09:20.159545Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50110/133889 blocks (37.4%), 0 events -2026-02-04T19:09:20.671921Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50120/133889 blocks (37.4%), 0 events -2026-02-04T19:09:20.709046Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50130/133889 blocks (37.4%), 0 events -2026-02-04T19:09:20.926951Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50140/133889 blocks (37.4%), 0 events -2026-02-04T19:09:20.963178Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50150/133889 blocks (37.5%), 0 events -2026-02-04T19:09:21.176111Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50160/133889 blocks (37.5%), 0 events -2026-02-04T19:09:21.456427Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50170/133889 blocks (37.5%), 0 events -2026-02-04T19:09:21.661085Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50180/133889 blocks (37.5%), 0 events -2026-02-04T19:09:21.797714Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50190/133889 blocks (37.5%), 0 events -2026-02-04T19:09:22.066180Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50200/133889 blocks (37.5%), 0 events -2026-02-04T19:09:22.177226Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50210/133889 blocks (37.5%), 0 events -2026-02-04T19:09:22.503799Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50220/133889 blocks (37.5%), 0 events -2026-02-04T19:09:22.577394Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50230/133889 blocks (37.5%), 0 events -2026-02-04T19:09:22.824190Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50240/133889 blocks (37.5%), 0 events -2026-02-04T19:09:23.027252Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50250/133889 blocks (37.5%), 0 events -2026-02-04T19:09:23.179475Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50260/133889 blocks (37.5%), 0 events -2026-02-04T19:09:23.370711Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50270/133889 blocks (37.5%), 0 events -2026-02-04T19:09:23.585262Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50280/133889 blocks (37.6%), 0 events -2026-02-04T19:09:23.810910Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50290/133889 blocks (37.6%), 0 events -2026-02-04T19:09:24.078056Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50300/133889 blocks (37.6%), 0 events -2026-02-04T19:09:24.245211Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50310/133889 blocks (37.6%), 0 events -2026-02-04T19:09:24.463176Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50320/133889 blocks (37.6%), 0 events -2026-02-04T19:09:24.608461Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50330/133889 blocks (37.6%), 0 events -2026-02-04T19:09:24.779383Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50340/133889 blocks (37.6%), 0 events -2026-02-04T19:09:25.093133Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50350/133889 blocks (37.6%), 0 events -2026-02-04T19:09:25.218105Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50360/133889 blocks (37.6%), 0 events -2026-02-04T19:09:25.462516Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50370/133889 blocks (37.6%), 0 events -2026-02-04T19:09:25.653855Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50380/133889 blocks (37.6%), 0 events -2026-02-04T19:09:25.800068Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50390/133889 blocks (37.6%), 0 events -2026-02-04T19:09:26.017646Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50400/133889 blocks (37.6%), 0 events -2026-02-04T19:09:26.201069Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50410/133889 blocks (37.7%), 0 events -2026-02-04T19:09:26.387552Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50420/133889 blocks (37.7%), 0 events -2026-02-04T19:09:26.696088Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50430/133889 blocks (37.7%), 0 events -2026-02-04T19:09:26.770814Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50440/133889 blocks (37.7%), 0 events -2026-02-04T19:09:27.025907Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50450/133889 blocks (37.7%), 0 events -2026-02-04T19:09:27.223113Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50460/133889 blocks (37.7%), 0 events -2026-02-04T19:09:27.423478Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50470/133889 blocks (37.7%), 0 events -2026-02-04T19:09:27.765965Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50480/133889 blocks (37.7%), 0 events -2026-02-04T19:09:27.820839Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50490/133889 blocks (37.7%), 0 events -2026-02-04T19:09:27.965046Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50500/133889 blocks (37.7%), 0 events -2026-02-04T19:09:28.279757Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50510/133889 blocks (37.7%), 0 events -2026-02-04T19:09:28.445968Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50520/133889 blocks (37.7%), 0 events -2026-02-04T19:09:28.615758Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50530/133889 blocks (37.7%), 0 events -2026-02-04T19:09:28.813810Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50540/133889 blocks (37.7%), 0 events -2026-02-04T19:09:29.036850Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50550/133889 blocks (37.8%), 0 events -2026-02-04T19:09:29.319163Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50560/133889 blocks (37.8%), 0 events -2026-02-04T19:09:29.357293Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50570/133889 blocks (37.8%), 0 events -2026-02-04T19:09:29.587317Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50580/133889 blocks (37.8%), 0 events -2026-02-04T19:09:29.847403Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50590/133889 blocks (37.8%), 0 events -2026-02-04T19:09:30.060950Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50600/133889 blocks (37.8%), 0 events -2026-02-04T19:09:30.235544Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50610/133889 blocks (37.8%), 0 events -2026-02-04T19:09:30.458989Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50620/133889 blocks (37.8%), 0 events -2026-02-04T19:09:30.577691Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50630/133889 blocks (37.8%), 0 events -2026-02-04T19:09:30.860071Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50640/133889 blocks (37.8%), 0 events -2026-02-04T19:09:31.033437Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50650/133889 blocks (37.8%), 0 events -2026-02-04T19:09:31.264966Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50660/133889 blocks (37.8%), 0 events -2026-02-04T19:09:31.432609Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50670/133889 blocks (37.8%), 0 events -2026-02-04T19:09:31.652605Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50680/133889 blocks (37.9%), 0 events -2026-02-04T19:09:31.908001Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50690/133889 blocks (37.9%), 0 events -2026-02-04T19:09:32.032574Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50700/133889 blocks (37.9%), 0 events -2026-02-04T19:09:32.245691Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50710/133889 blocks (37.9%), 0 events -2026-02-04T19:09:32.431886Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50720/133889 blocks (37.9%), 0 events -2026-02-04T19:09:32.603135Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50730/133889 blocks (37.9%), 0 events -2026-02-04T19:09:32.846433Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50740/133889 blocks (37.9%), 0 events -2026-02-04T19:09:32.991957Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50750/133889 blocks (37.9%), 0 events -2026-02-04T19:09:33.173125Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50760/133889 blocks (37.9%), 0 events -2026-02-04T19:09:33.511786Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50770/133889 blocks (37.9%), 0 events -2026-02-04T19:09:33.653914Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50780/133889 blocks (37.9%), 0 events -2026-02-04T19:09:33.768182Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50790/133889 blocks (37.9%), 0 events -2026-02-04T19:09:34.040721Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50800/133889 blocks (37.9%), 0 events -2026-02-04T19:09:34.190929Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50810/133889 blocks (37.9%), 0 events -2026-02-04T19:09:34.427024Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50820/133889 blocks (38.0%), 0 events -2026-02-04T19:09:34.650607Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50830/133889 blocks (38.0%), 0 events -2026-02-04T19:09:34.769248Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50840/133889 blocks (38.0%), 0 events -2026-02-04T19:09:35.085850Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50850/133889 blocks (38.0%), 0 events -2026-02-04T19:09:35.188417Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50860/133889 blocks (38.0%), 0 events -2026-02-04T19:09:35.369262Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50870/133889 blocks (38.0%), 0 events -2026-02-04T19:09:35.642406Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50880/133889 blocks (38.0%), 0 events -2026-02-04T19:09:35.819346Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50890/133889 blocks (38.0%), 0 events -2026-02-04T19:09:36.143824Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50900/133889 blocks (38.0%), 0 events -2026-02-04T19:09:36.181171Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50910/133889 blocks (38.0%), 0 events -2026-02-04T19:09:36.420414Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50920/133889 blocks (38.0%), 0 events -2026-02-04T19:09:36.626176Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50930/133889 blocks (38.0%), 0 events -2026-02-04T19:09:36.849201Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50940/133889 blocks (38.0%), 0 events -2026-02-04T19:09:37.150843Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50950/133889 blocks (38.1%), 0 events -2026-02-04T19:09:37.192430Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50960/133889 blocks (38.1%), 0 events -2026-02-04T19:09:37.421735Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50970/133889 blocks (38.1%), 0 events -2026-02-04T19:09:37.579754Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50980/133889 blocks (38.1%), 0 events -2026-02-04T19:09:37.836774Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 50990/133889 blocks (38.1%), 0 events -2026-02-04T19:09:37.967471Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51000/133889 blocks (38.1%), 0 events -2026-02-04T19:09:38.249423Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51010/133889 blocks (38.1%), 0 events -2026-02-04T19:09:38.429219Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51020/133889 blocks (38.1%), 0 events -2026-02-04T19:09:38.722737Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51030/133889 blocks (38.1%), 0 events -2026-02-04T19:09:38.763567Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51040/133889 blocks (38.1%), 0 events -2026-02-04T19:09:39.011643Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51050/133889 blocks (38.1%), 0 events -2026-02-04T19:09:39.284611Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51060/133889 blocks (38.1%), 0 events -2026-02-04T19:09:39.483239Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51070/133889 blocks (38.1%), 0 events -2026-02-04T19:09:39.571664Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51080/133889 blocks (38.2%), 0 events -2026-02-04T19:09:39.804578Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51090/133889 blocks (38.2%), 0 events -2026-02-04T19:09:40.062605Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51100/133889 blocks (38.2%), 0 events -2026-02-04T19:09:40.336807Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51110/133889 blocks (38.2%), 0 events -2026-02-04T19:09:40.373340Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51120/133889 blocks (38.2%), 0 events -2026-02-04T19:09:40.636457Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51130/133889 blocks (38.2%), 0 events -2026-02-04T19:09:40.852460Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51140/133889 blocks (38.2%), 0 events -2026-02-04T19:09:41.056395Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51150/133889 blocks (38.2%), 0 events -2026-02-04T19:09:41.226104Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51160/133889 blocks (38.2%), 0 events -2026-02-04T19:09:41.430712Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51170/133889 blocks (38.2%), 0 events -2026-02-04T19:09:41.599159Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51180/133889 blocks (38.2%), 0 events -2026-02-04T19:09:41.905165Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51190/133889 blocks (38.2%), 0 events -2026-02-04T19:09:41.973648Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51200/133889 blocks (38.2%), 0 events -2026-02-04T19:09:42.252731Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51210/133889 blocks (38.2%), 0 events -2026-02-04T19:09:42.423396Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51220/133889 blocks (38.3%), 0 events -2026-02-04T19:09:42.648779Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51230/133889 blocks (38.3%), 0 events -2026-02-04T19:09:42.798100Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51240/133889 blocks (38.3%), 0 events -2026-02-04T19:09:42.969147Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51250/133889 blocks (38.3%), 0 events -2026-02-04T19:09:43.189348Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51260/133889 blocks (38.3%), 0 events -2026-02-04T19:09:43.441113Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51270/133889 blocks (38.3%), 0 events -2026-02-04T19:09:43.626383Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51280/133889 blocks (38.3%), 0 events -2026-02-04T19:09:43.846823Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51290/133889 blocks (38.3%), 0 events -2026-02-04T19:09:43.997131Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51300/133889 blocks (38.3%), 0 events -2026-02-04T19:09:44.207909Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51310/133889 blocks (38.3%), 0 events -2026-02-04T19:09:44.522736Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51320/133889 blocks (38.3%), 0 events -2026-02-04T19:09:44.562797Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51330/133889 blocks (38.3%), 0 events -2026-02-04T19:09:44.829824Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51340/133889 blocks (38.3%), 0 events -2026-02-04T19:09:45.045439Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51350/133889 blocks (38.4%), 0 events -2026-02-04T19:09:45.262537Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51360/133889 blocks (38.4%), 0 events -2026-02-04T19:09:45.369437Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51370/133889 blocks (38.4%), 0 events -2026-02-04T19:09:45.626596Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51380/133889 blocks (38.4%), 0 events -2026-02-04T19:09:45.836204Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51390/133889 blocks (38.4%), 0 events -2026-02-04T19:09:46.095170Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51400/133889 blocks (38.4%), 0 events -2026-02-04T19:09:46.190035Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51410/133889 blocks (38.4%), 0 events -2026-02-04T19:09:46.400305Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51420/133889 blocks (38.4%), 0 events -2026-02-04T19:09:46.655696Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51430/133889 blocks (38.4%), 0 events -2026-02-04T19:09:46.814665Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51440/133889 blocks (38.4%), 0 events -2026-02-04T19:09:47.000505Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51450/133889 blocks (38.4%), 0 events -2026-02-04T19:09:47.340091Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51460/133889 blocks (38.4%), 0 events -2026-02-04T19:09:47.377993Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51470/133889 blocks (38.4%), 0 events -2026-02-04T19:09:47.678097Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51480/133889 blocks (38.4%), 0 events -2026-02-04T19:09:47.862249Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51490/133889 blocks (38.5%), 0 events -2026-02-04T19:09:47.973386Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51500/133889 blocks (38.5%), 0 events -2026-02-04T19:09:48.223168Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51510/133889 blocks (38.5%), 0 events -2026-02-04T19:09:48.424604Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51520/133889 blocks (38.5%), 0 events -2026-02-04T19:09:48.571701Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51530/133889 blocks (38.5%), 0 events -2026-02-04T19:09:48.879260Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51540/133889 blocks (38.5%), 0 events -2026-02-04T19:09:48.978362Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51550/133889 blocks (38.5%), 0 events -2026-02-04T19:09:49.251639Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51560/133889 blocks (38.5%), 0 events -2026-02-04T19:09:49.441055Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51570/133889 blocks (38.5%), 0 events -2026-02-04T19:09:49.732566Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51580/133889 blocks (38.5%), 0 events -2026-02-04T19:09:49.779384Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51590/133889 blocks (38.5%), 0 events -2026-02-04T19:09:50.014723Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51600/133889 blocks (38.5%), 0 events -2026-02-04T19:09:50.254831Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51610/133889 blocks (38.5%), 0 events -2026-02-04T19:09:50.485250Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51620/133889 blocks (38.6%), 0 events -2026-02-04T19:09:50.645884Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51630/133889 blocks (38.6%), 0 events -2026-02-04T19:09:50.835845Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51640/133889 blocks (38.6%), 0 events -2026-02-04T19:09:51.024100Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51650/133889 blocks (38.6%), 0 events -2026-02-04T19:09:51.165381Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51660/133889 blocks (38.6%), 0 events -2026-02-04T19:09:51.384325Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51670/133889 blocks (38.6%), 0 events -2026-02-04T19:09:51.597967Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51680/133889 blocks (38.6%), 0 events -2026-02-04T19:09:51.860491Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51690/133889 blocks (38.6%), 0 events -2026-02-04T19:09:52.064472Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51700/133889 blocks (38.6%), 0 events -2026-02-04T19:09:52.168933Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51710/133889 blocks (38.6%), 0 events -2026-02-04T19:09:52.387911Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51720/133889 blocks (38.6%), 0 events -2026-02-04T19:09:52.584972Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51730/133889 blocks (38.6%), 0 events -2026-02-04T19:09:52.909311Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51740/133889 blocks (38.6%), 0 events -2026-02-04T19:09:53.036456Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51750/133889 blocks (38.7%), 0 events -2026-02-04T19:09:53.261615Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51760/133889 blocks (38.7%), 0 events -2026-02-04T19:09:53.437278Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51770/133889 blocks (38.7%), 0 events -2026-02-04T19:09:53.606435Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51780/133889 blocks (38.7%), 0 events -2026-02-04T19:09:53.777025Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51790/133889 blocks (38.7%), 0 events -2026-02-04T19:09:54.042334Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51800/133889 blocks (38.7%), 0 events -2026-02-04T19:09:54.198027Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51810/133889 blocks (38.7%), 0 events -2026-02-04T19:09:54.451351Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51820/133889 blocks (38.7%), 0 events -2026-02-04T19:09:54.660099Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51830/133889 blocks (38.7%), 0 events -2026-02-04T19:09:54.765244Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51840/133889 blocks (38.7%), 0 events -2026-02-04T19:09:55.020513Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51850/133889 blocks (38.7%), 0 events -2026-02-04T19:09:55.259103Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51860/133889 blocks (38.7%), 0 events -2026-02-04T19:09:55.499836Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51870/133889 blocks (38.7%), 0 events -2026-02-04T19:09:55.566221Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51880/133889 blocks (38.7%), 0 events -2026-02-04T19:09:55.851083Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51890/133889 blocks (38.8%), 0 events -2026-02-04T19:09:56.057763Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51900/133889 blocks (38.8%), 0 events -2026-02-04T19:09:56.229608Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51910/133889 blocks (38.8%), 0 events -2026-02-04T19:09:56.401309Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51920/133889 blocks (38.8%), 0 events -2026-02-04T19:09:56.645138Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51930/133889 blocks (38.8%), 0 events -2026-02-04T19:09:56.851405Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51940/133889 blocks (38.8%), 0 events -2026-02-04T19:09:57.072886Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51950/133889 blocks (38.8%), 0 events -2026-02-04T19:09:57.173085Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51960/133889 blocks (38.8%), 0 events -2026-02-04T19:09:57.376175Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51970/133889 blocks (38.8%), 0 events -2026-02-04T19:09:57.627171Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51980/133889 blocks (38.8%), 0 events -2026-02-04T19:09:57.788506Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 51990/133889 blocks (38.8%), 0 events -2026-02-04T19:09:57.981933Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52000/133889 blocks (38.8%), 0 events -2026-02-04T19:09:58.177524Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52010/133889 blocks (38.8%), 0 events -2026-02-04T19:09:58.385060Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52020/133889 blocks (38.9%), 0 events -2026-02-04T19:09:58.677485Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52030/133889 blocks (38.9%), 0 events -2026-02-04T19:09:58.847324Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52040/133889 blocks (38.9%), 0 events -2026-02-04T19:09:58.972344Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52050/133889 blocks (38.9%), 0 events -2026-02-04T19:09:59.199262Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52060/133889 blocks (38.9%), 0 events -2026-02-04T19:09:59.431902Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52070/133889 blocks (38.9%), 0 events -2026-02-04T19:09:59.727042Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52080/133889 blocks (38.9%), 0 events -2026-02-04T19:09:59.764091Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52090/133889 blocks (38.9%), 0 events -2026-02-04T19:10:00.017811Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52100/133889 blocks (38.9%), 0 events -2026-02-04T19:10:00.253984Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52110/133889 blocks (38.9%), 0 events -2026-02-04T19:10:00.374709Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52120/133889 blocks (38.9%), 0 events -2026-02-04T19:10:00.620984Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52130/133889 blocks (38.9%), 0 events -2026-02-04T19:10:00.792899Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52140/133889 blocks (38.9%), 0 events -2026-02-04T19:10:01.007587Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52150/133889 blocks (38.9%), 0 events -2026-02-04T19:10:01.266293Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52160/133889 blocks (39.0%), 0 events -2026-02-04T19:10:01.365683Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52170/133889 blocks (39.0%), 0 events -2026-02-04T19:10:01.630171Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52180/133889 blocks (39.0%), 0 events -2026-02-04T19:10:01.828006Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52190/133889 blocks (39.0%), 0 events -2026-02-04T19:10:02.030706Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52200/133889 blocks (39.0%), 0 events -2026-02-04T19:10:02.199740Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52210/133889 blocks (39.0%), 0 events -2026-02-04T19:10:02.417179Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52220/133889 blocks (39.0%), 0 events -2026-02-04T19:10:02.596571Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52230/133889 blocks (39.0%), 0 events -2026-02-04T19:10:02.874769Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52240/133889 blocks (39.0%), 0 events -2026-02-04T19:10:03.084692Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52250/133889 blocks (39.0%), 0 events -2026-02-04T19:10:03.238546Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52260/133889 blocks (39.0%), 0 events -2026-02-04T19:10:03.402744Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52270/133889 blocks (39.0%), 0 events -2026-02-04T19:10:03.593040Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52280/133889 blocks (39.0%), 0 events -2026-02-04T19:10:03.889265Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52290/133889 blocks (39.1%), 0 events -2026-02-04T19:10:04.084444Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52300/133889 blocks (39.1%), 0 events -2026-02-04T19:10:04.198010Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52310/133889 blocks (39.1%), 0 events -2026-02-04T19:10:04.449126Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52320/133889 blocks (39.1%), 0 events -2026-02-04T19:10:04.577337Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52330/133889 blocks (39.1%), 0 events -2026-02-04T19:10:04.845129Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52340/133889 blocks (39.1%), 0 events -2026-02-04T19:10:05.035416Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52350/133889 blocks (39.1%), 0 events -2026-02-04T19:10:05.222451Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52360/133889 blocks (39.1%), 0 events -2026-02-04T19:10:05.460996Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52370/133889 blocks (39.1%), 0 events -2026-02-04T19:10:05.621246Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52380/133889 blocks (39.1%), 0 events -2026-02-04T19:10:05.782098Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52390/133889 blocks (39.1%), 0 events -2026-02-04T19:10:06.065494Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52400/133889 blocks (39.1%), 0 events -2026-02-04T19:10:06.260209Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52410/133889 blocks (39.1%), 0 events -2026-02-04T19:10:06.508980Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52420/133889 blocks (39.2%), 0 events -2026-02-04T19:10:06.575595Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52430/133889 blocks (39.2%), 0 events -2026-02-04T19:10:06.817808Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52440/133889 blocks (39.2%), 0 events -2026-02-04T19:10:07.067901Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52450/133889 blocks (39.2%), 0 events -2026-02-04T19:10:07.165567Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52460/133889 blocks (39.2%), 0 events -2026-02-04T19:10:07.396231Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52470/133889 blocks (39.2%), 0 events -2026-02-04T19:10:07.601519Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52480/133889 blocks (39.2%), 0 events -2026-02-04T19:10:07.827579Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52490/133889 blocks (39.2%), 0 events -2026-02-04T19:10:07.978093Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52500/133889 blocks (39.2%), 0 events -2026-02-04T19:10:08.242682Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52510/133889 blocks (39.2%), 0 events -2026-02-04T19:10:08.429557Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52520/133889 blocks (39.2%), 0 events -2026-02-04T19:10:08.664878Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52530/133889 blocks (39.2%), 0 events -2026-02-04T19:10:08.780918Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52540/133889 blocks (39.2%), 0 events -2026-02-04T19:10:08.980558Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52550/133889 blocks (39.2%), 0 events -2026-02-04T19:10:09.187229Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52560/133889 blocks (39.3%), 0 events -2026-02-04T19:10:09.420749Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52570/133889 blocks (39.3%), 0 events -2026-02-04T19:10:09.691177Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52580/133889 blocks (39.3%), 0 events -2026-02-04T19:10:09.844825Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52590/133889 blocks (39.3%), 0 events -2026-02-04T19:10:10.001190Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52600/133889 blocks (39.3%), 0 events -2026-02-04T19:10:10.252987Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52610/133889 blocks (39.3%), 0 events -2026-02-04T19:10:10.377690Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52620/133889 blocks (39.3%), 0 events -2026-02-04T19:10:10.570616Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52630/133889 blocks (39.3%), 0 events -2026-02-04T19:10:10.837479Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52640/133889 blocks (39.3%), 0 events -2026-02-04T19:10:10.982897Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52650/133889 blocks (39.3%), 0 events -2026-02-04T19:10:11.227880Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52660/133889 blocks (39.3%), 0 events -2026-02-04T19:10:11.431464Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52670/133889 blocks (39.3%), 0 events -2026-02-04T19:10:11.631604Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52680/133889 blocks (39.3%), 0 events -2026-02-04T19:10:11.845993Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52690/133889 blocks (39.4%), 0 events -2026-02-04T19:10:11.989243Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52700/133889 blocks (39.4%), 0 events -2026-02-04T19:10:12.276335Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52710/133889 blocks (39.4%), 0 events -2026-02-04T19:10:12.450890Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52720/133889 blocks (39.4%), 0 events -2026-02-04T19:10:12.577863Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52730/133889 blocks (39.4%), 0 events -2026-02-04T19:10:12.833969Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52740/133889 blocks (39.4%), 0 events -2026-02-04T19:10:13.006134Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52750/133889 blocks (39.4%), 0 events -2026-02-04T19:10:13.190866Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52760/133889 blocks (39.4%), 0 events -2026-02-04T19:10:13.390884Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52770/133889 blocks (39.4%), 0 events -2026-02-04T19:10:13.588650Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52780/133889 blocks (39.4%), 0 events -2026-02-04T19:10:13.884632Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52790/133889 blocks (39.4%), 0 events -2026-02-04T19:10:13.963886Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52800/133889 blocks (39.4%), 0 events -2026-02-04T19:10:14.210594Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52810/133889 blocks (39.4%), 0 events -2026-02-04T19:10:14.413658Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52820/133889 blocks (39.5%), 0 events -2026-02-04T19:10:14.612721Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52830/133889 blocks (39.5%), 0 events -2026-02-04T19:10:14.897057Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52840/133889 blocks (39.5%), 0 events -2026-02-04T19:10:14.969636Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52850/133889 blocks (39.5%), 0 events -2026-02-04T19:10:15.240260Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52860/133889 blocks (39.5%), 0 events -2026-02-04T19:10:15.455556Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52870/133889 blocks (39.5%), 0 events -2026-02-04T19:10:15.623715Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52880/133889 blocks (39.5%), 0 events -2026-02-04T19:10:15.808322Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52890/133889 blocks (39.5%), 0 events -2026-02-04T19:10:16.014491Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52900/133889 blocks (39.5%), 0 events -2026-02-04T19:10:16.236127Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52910/133889 blocks (39.5%), 0 events -2026-02-04T19:10:16.470113Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52920/133889 blocks (39.5%), 0 events -2026-02-04T19:10:16.578574Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52930/133889 blocks (39.5%), 0 events -2026-02-04T19:10:16.787690Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52940/133889 blocks (39.5%), 0 events -2026-02-04T19:10:17.030789Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52950/133889 blocks (39.5%), 0 events -2026-02-04T19:10:17.241888Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52960/133889 blocks (39.6%), 0 events -2026-02-04T19:10:17.394181Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52970/133889 blocks (39.6%), 0 events -2026-02-04T19:10:17.589240Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52980/133889 blocks (39.6%), 0 events -2026-02-04T19:10:17.849601Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 52990/133889 blocks (39.6%), 0 events -2026-02-04T19:10:18.093149Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53000/133889 blocks (39.6%), 0 events -2026-02-04T19:10:18.223071Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53010/133889 blocks (39.6%), 0 events -2026-02-04T19:10:18.411086Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53020/133889 blocks (39.6%), 0 events -2026-02-04T19:10:18.597728Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53030/133889 blocks (39.6%), 0 events -2026-02-04T19:10:18.833736Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53040/133889 blocks (39.6%), 0 events -2026-02-04T19:10:18.979375Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53050/133889 blocks (39.6%), 0 events -2026-02-04T19:10:19.168176Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53060/133889 blocks (39.6%), 0 events -2026-02-04T19:10:19.432700Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53070/133889 blocks (39.6%), 0 events -2026-02-04T19:10:19.659686Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53080/133889 blocks (39.6%), 0 events -2026-02-04T19:10:19.846857Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53090/133889 blocks (39.7%), 0 events -2026-02-04T19:10:19.983502Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53100/133889 blocks (39.7%), 0 events -2026-02-04T19:10:20.233008Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53110/133889 blocks (39.7%), 0 events -2026-02-04T19:10:20.395379Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53120/133889 blocks (39.7%), 0 events -2026-02-04T19:10:20.696792Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53130/133889 blocks (39.7%), 0 events -2026-02-04T19:10:20.893774Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53140/133889 blocks (39.7%), 0 events -2026-02-04T19:10:20.968352Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53150/133889 blocks (39.7%), 0 events -2026-02-04T19:10:21.219840Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53160/133889 blocks (39.7%), 0 events -2026-02-04T19:10:21.443440Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53170/133889 blocks (39.7%), 0 events -2026-02-04T19:10:21.751418Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53180/133889 blocks (39.7%), 0 events -2026-02-04T19:10:21.796384Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53190/133889 blocks (39.7%), 0 events -2026-02-04T19:10:22.035570Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53200/133889 blocks (39.7%), 0 events -2026-02-04T19:10:22.290961Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53210/133889 blocks (39.7%), 0 events -2026-02-04T19:10:22.466017Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53220/133889 blocks (39.7%), 0 events -2026-02-04T19:10:22.577744Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53230/133889 blocks (39.8%), 0 events -2026-02-04T19:10:22.856649Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53240/133889 blocks (39.8%), 0 events -2026-02-04T19:10:22.988714Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53250/133889 blocks (39.8%), 0 events -2026-02-04T19:10:23.285295Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53260/133889 blocks (39.8%), 0 events -2026-02-04T19:10:23.426248Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53270/133889 blocks (39.8%), 0 events -2026-02-04T19:10:23.644013Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53280/133889 blocks (39.8%), 0 events -2026-02-04T19:10:23.849846Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53290/133889 blocks (39.8%), 0 events -2026-02-04T19:10:24.014945Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53300/133889 blocks (39.8%), 0 events -2026-02-04T19:10:24.206618Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53310/133889 blocks (39.8%), 0 events -2026-02-04T19:10:24.372622Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53320/133889 blocks (39.8%), 0 events -2026-02-04T19:10:24.576870Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53330/133889 blocks (39.8%), 0 events -2026-02-04T19:10:24.897839Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53340/133889 blocks (39.8%), 0 events -2026-02-04T19:10:25.018933Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53350/133889 blocks (39.8%), 0 events -2026-02-04T19:10:25.184933Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53360/133889 blocks (39.9%), 0 events -2026-02-04T19:10:25.441089Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53370/133889 blocks (39.9%), 0 events -2026-02-04T19:10:25.620418Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53380/133889 blocks (39.9%), 0 events -2026-02-04T19:10:25.808876Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53390/133889 blocks (39.9%), 0 events -2026-02-04T19:10:26.070712Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53400/133889 blocks (39.9%), 0 events -2026-02-04T19:10:26.216398Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53410/133889 blocks (39.9%), 0 events -2026-02-04T19:10:26.464269Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53420/133889 blocks (39.9%), 0 events -2026-02-04T19:10:26.622349Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53430/133889 blocks (39.9%), 0 events -2026-02-04T19:10:26.800201Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53440/133889 blocks (39.9%), 0 events -2026-02-04T19:10:27.042447Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53450/133889 blocks (39.9%), 0 events -2026-02-04T19:10:27.195224Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53460/133889 blocks (39.9%), 0 events -2026-02-04T19:10:27.517634Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53470/133889 blocks (39.9%), 0 events -2026-02-04T19:10:27.555623Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53480/133889 blocks (39.9%), 0 events -2026-02-04T19:10:27.862260Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53490/133889 blocks (40.0%), 0 events -2026-02-04T19:10:28.044251Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53500/133889 blocks (40.0%), 0 events -2026-02-04T19:10:28.168474Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53510/133889 blocks (40.0%), 0 events -2026-02-04T19:10:28.387640Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53520/133889 blocks (40.0%), 0 events -2026-02-04T19:10:28.616287Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53530/133889 blocks (40.0%), 0 events -2026-02-04T19:10:28.851451Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53540/133889 blocks (40.0%), 0 events -2026-02-04T19:10:29.082416Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53550/133889 blocks (40.0%), 0 events -2026-02-04T19:10:29.226521Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53560/133889 blocks (40.0%), 0 events -2026-02-04T19:10:29.426801Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53570/133889 blocks (40.0%), 0 events -2026-02-04T19:10:29.619564Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53580/133889 blocks (40.0%), 0 events -2026-02-04T19:10:29.826197Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53590/133889 blocks (40.0%), 0 events -2026-02-04T19:10:29.967860Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53600/133889 blocks (40.0%), 0 events -2026-02-04T19:10:30.226777Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53610/133889 blocks (40.0%), 0 events -2026-02-04T19:10:30.436965Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53620/133889 blocks (40.0%), 0 events -2026-02-04T19:10:30.661844Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53630/133889 blocks (40.1%), 0 events -2026-02-04T19:10:30.809705Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53640/133889 blocks (40.1%), 0 events -2026-02-04T19:10:31.149935Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53650/133889 blocks (40.1%), 0 events -2026-02-04T19:10:31.192736Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53660/133889 blocks (40.1%), 0 events -2026-02-04T19:10:31.413297Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53670/133889 blocks (40.1%), 0 events -2026-02-04T19:10:31.673891Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53680/133889 blocks (40.1%), 0 events -2026-02-04T19:10:31.787282Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53690/133889 blocks (40.1%), 0 events -2026-02-04T19:10:32.010574Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53700/133889 blocks (40.1%), 0 events -2026-02-04T19:10:32.236115Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53710/133889 blocks (40.1%), 0 events -2026-02-04T19:10:32.455164Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53720/133889 blocks (40.1%), 0 events -2026-02-04T19:10:32.628519Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53730/133889 blocks (40.1%), 0 events -2026-02-04T19:10:32.848129Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53740/133889 blocks (40.1%), 0 events -2026-02-04T19:10:33.004165Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53750/133889 blocks (40.1%), 0 events -2026-02-04T19:10:33.285029Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53760/133889 blocks (40.2%), 0 events -2026-02-04T19:10:33.375739Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53770/133889 blocks (40.2%), 0 events -2026-02-04T19:10:33.584344Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53780/133889 blocks (40.2%), 0 events -2026-02-04T19:10:33.839165Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53790/133889 blocks (40.2%), 0 events -2026-02-04T19:10:34.011700Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53800/133889 blocks (40.2%), 0 events -2026-02-04T19:10:34.186167Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53810/133889 blocks (40.2%), 0 events -2026-02-04T19:10:34.470631Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53820/133889 blocks (40.2%), 0 events -2026-02-04T19:10:34.566479Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53830/133889 blocks (40.2%), 0 events -2026-02-04T19:10:34.860841Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53840/133889 blocks (40.2%), 0 events -2026-02-04T19:10:35.035326Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53850/133889 blocks (40.2%), 0 events -2026-02-04T19:10:35.212673Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53860/133889 blocks (40.2%), 0 events -2026-02-04T19:10:35.401749Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53870/133889 blocks (40.2%), 0 events -2026-02-04T19:10:35.580127Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53880/133889 blocks (40.2%), 0 events -2026-02-04T19:10:35.900544Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53890/133889 blocks (40.2%), 0 events -2026-02-04T19:10:36.047502Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53900/133889 blocks (40.3%), 0 events -2026-02-04T19:10:36.200548Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53910/133889 blocks (40.3%), 0 events -2026-02-04T19:10:36.449612Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53920/133889 blocks (40.3%), 0 events -2026-02-04T19:10:36.586754Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53930/133889 blocks (40.3%), 0 events -2026-02-04T19:10:36.916526Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53940/133889 blocks (40.3%), 0 events -2026-02-04T19:10:36.958531Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53950/133889 blocks (40.3%), 0 events -2026-02-04T19:10:37.259000Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53960/133889 blocks (40.3%), 0 events -2026-02-04T19:10:37.477004Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53970/133889 blocks (40.3%), 0 events -2026-02-04T19:10:37.632166Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53980/133889 blocks (40.3%), 0 events -2026-02-04T19:10:37.798525Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 53990/133889 blocks (40.3%), 0 events -2026-02-04T19:10:37.996353Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54000/133889 blocks (40.3%), 0 events -2026-02-04T19:10:38.240761Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54010/133889 blocks (40.3%), 0 events -2026-02-04T19:10:38.530700Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54020/133889 blocks (40.3%), 0 events -2026-02-04T19:10:38.569810Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54030/133889 blocks (40.4%), 0 events -2026-02-04T19:10:38.855687Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54040/133889 blocks (40.4%), 0 events -2026-02-04T19:10:39.048474Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54050/133889 blocks (40.4%), 0 events -2026-02-04T19:10:39.238577Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54060/133889 blocks (40.4%), 0 events -2026-02-04T19:10:39.388641Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54070/133889 blocks (40.4%), 0 events -2026-02-04T19:10:39.580761Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54080/133889 blocks (40.4%), 0 events -2026-02-04T19:10:39.828365Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54090/133889 blocks (40.4%), 0 events -2026-02-04T19:10:40.066382Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54100/133889 blocks (40.4%), 0 events -2026-02-04T19:10:40.256222Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54110/133889 blocks (40.4%), 0 events -2026-02-04T19:10:40.445542Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54120/133889 blocks (40.4%), 0 events -2026-02-04T19:10:40.660000Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54130/133889 blocks (40.4%), 0 events -2026-02-04T19:10:40.837338Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54140/133889 blocks (40.4%), 0 events -2026-02-04T19:10:40.966730Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54150/133889 blocks (40.4%), 0 events -2026-02-04T19:10:41.213829Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54160/133889 blocks (40.5%), 0 events -2026-02-04T19:10:41.368689Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54170/133889 blocks (40.5%), 0 events -2026-02-04T19:10:41.673879Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54180/133889 blocks (40.5%), 0 events -2026-02-04T19:10:41.785021Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54190/133889 blocks (40.5%), 0 events -2026-02-04T19:10:42.067062Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54200/133889 blocks (40.5%), 0 events -2026-02-04T19:10:42.209830Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54210/133889 blocks (40.5%), 0 events -2026-02-04T19:10:42.458544Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54220/133889 blocks (40.5%), 0 events -2026-02-04T19:10:42.718888Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54230/133889 blocks (40.5%), 0 events -2026-02-04T19:10:42.757577Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54240/133889 blocks (40.5%), 0 events -2026-02-04T19:10:43.049702Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54250/133889 blocks (40.5%), 0 events -2026-02-04T19:10:43.247112Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54260/133889 blocks (40.5%), 0 events -2026-02-04T19:10:43.400228Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54270/133889 blocks (40.5%), 0 events -2026-02-04T19:10:43.586607Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54280/133889 blocks (40.5%), 0 events -2026-02-04T19:10:43.787812Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54290/133889 blocks (40.5%), 0 events -2026-02-04T19:10:43.986403Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54300/133889 blocks (40.6%), 0 events -2026-02-04T19:10:44.299793Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54310/133889 blocks (40.6%), 0 events -2026-02-04T19:10:44.366855Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54320/133889 blocks (40.6%), 0 events -2026-02-04T19:10:44.663433Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54330/133889 blocks (40.6%), 0 events -2026-02-04T19:10:44.814799Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54340/133889 blocks (40.6%), 0 events -2026-02-04T19:10:45.003622Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54350/133889 blocks (40.6%), 0 events -2026-02-04T19:10:45.185639Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54360/133889 blocks (40.6%), 0 events -2026-02-04T19:10:45.402401Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54370/133889 blocks (40.6%), 0 events -2026-02-04T19:10:45.642843Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54380/133889 blocks (40.6%), 0 events -2026-02-04T19:10:45.863059Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54390/133889 blocks (40.6%), 0 events -2026-02-04T19:10:45.991769Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54400/133889 blocks (40.6%), 0 events -2026-02-04T19:10:46.249887Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54410/133889 blocks (40.6%), 0 events -2026-02-04T19:10:46.413238Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54420/133889 blocks (40.6%), 0 events -2026-02-04T19:10:46.910052Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54430/133889 blocks (40.7%), 0 events -2026-02-04T19:10:46.951811Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54440/133889 blocks (40.7%), 0 events -2026-02-04T19:10:46.985827Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54450/133889 blocks (40.7%), 0 events -2026-02-04T19:10:47.245245Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54460/133889 blocks (40.7%), 0 events -2026-02-04T19:10:47.439990Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54470/133889 blocks (40.7%), 0 events -2026-02-04T19:10:47.598234Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54480/133889 blocks (40.7%), 0 events -2026-02-04T19:10:47.923313Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54490/133889 blocks (40.7%), 0 events -2026-02-04T19:10:47.972755Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54500/133889 blocks (40.7%), 0 events -2026-02-04T19:10:48.192020Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54510/133889 blocks (40.7%), 0 events -2026-02-04T19:10:48.450862Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54520/133889 blocks (40.7%), 0 events -2026-02-04T19:10:48.646706Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54530/133889 blocks (40.7%), 0 events -2026-02-04T19:10:48.849604Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54540/133889 blocks (40.7%), 0 events -2026-02-04T19:10:49.007626Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54550/133889 blocks (40.7%), 0 events -2026-02-04T19:10:49.230149Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54560/133889 blocks (40.7%), 0 events -2026-02-04T19:10:49.496162Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54570/133889 blocks (40.8%), 0 events -2026-02-04T19:10:49.893371Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54580/133889 blocks (40.8%), 0 events -2026-02-04T19:10:49.926096Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54590/133889 blocks (40.8%), 0 events -2026-02-04T19:10:50.020239Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54600/133889 blocks (40.8%), 0 events -2026-02-04T19:10:50.163996Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54610/133889 blocks (40.8%), 0 events -2026-02-04T19:10:50.742052Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54620/133889 blocks (40.8%), 0 events -2026-02-04T19:10:50.782852Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54630/133889 blocks (40.8%), 0 events -2026-02-04T19:10:50.820382Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54640/133889 blocks (40.8%), 0 events -2026-02-04T19:10:51.106208Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54650/133889 blocks (40.8%), 0 events -2026-02-04T19:10:51.163124Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54660/133889 blocks (40.8%), 0 events -2026-02-04T19:10:51.421455Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54670/133889 blocks (40.8%), 0 events -2026-02-04T19:10:51.656868Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54680/133889 blocks (40.8%), 0 events -2026-02-04T19:10:51.830440Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54690/133889 blocks (40.8%), 0 events -2026-02-04T19:10:52.120319Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54700/133889 blocks (40.9%), 0 events -2026-02-04T19:10:52.158118Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54710/133889 blocks (40.9%), 0 events -2026-02-04T19:10:52.383713Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54720/133889 blocks (40.9%), 0 events -2026-02-04T19:10:52.644608Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54730/133889 blocks (40.9%), 0 events -2026-02-04T19:10:52.802388Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54740/133889 blocks (40.9%), 0 events -2026-02-04T19:10:52.992525Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54750/133889 blocks (40.9%), 0 events -2026-02-04T19:10:53.200906Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54760/133889 blocks (40.9%), 0 events -2026-02-04T19:10:53.470327Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54770/133889 blocks (40.9%), 0 events -2026-02-04T19:10:53.579414Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54780/133889 blocks (40.9%), 0 events -2026-02-04T19:10:53.830175Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54790/133889 blocks (40.9%), 0 events -2026-02-04T19:10:54.062706Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54800/133889 blocks (40.9%), 0 events -2026-02-04T19:10:54.249517Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54810/133889 blocks (40.9%), 0 events -2026-02-04T19:10:54.408316Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54820/133889 blocks (40.9%), 0 events -2026-02-04T19:10:54.739167Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54830/133889 blocks (41.0%), 0 events -2026-02-04T19:10:54.774559Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54840/133889 blocks (41.0%), 0 events -2026-02-04T19:10:55.038136Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54850/133889 blocks (41.0%), 0 events -2026-02-04T19:10:55.298146Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54860/133889 blocks (41.0%), 0 events -2026-02-04T19:10:55.461910Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54870/133889 blocks (41.0%), 0 events -2026-02-04T19:10:55.603848Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54880/133889 blocks (41.0%), 0 events -2026-02-04T19:10:55.820844Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54890/133889 blocks (41.0%), 0 events -2026-02-04T19:10:56.020881Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54900/133889 blocks (41.0%), 0 events -2026-02-04T19:10:56.178189Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54910/133889 blocks (41.0%), 0 events -2026-02-04T19:10:56.377279Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54920/133889 blocks (41.0%), 0 events -2026-02-04T19:10:56.660056Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54930/133889 blocks (41.0%), 0 events -2026-02-04T19:10:56.869266Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54940/133889 blocks (41.0%), 0 events -2026-02-04T19:10:57.055939Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54950/133889 blocks (41.0%), 0 events -2026-02-04T19:10:57.224318Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54960/133889 blocks (41.0%), 0 events -2026-02-04T19:10:57.396881Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54970/133889 blocks (41.1%), 0 events -2026-02-04T19:10:57.595615Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54980/133889 blocks (41.1%), 0 events -2026-02-04T19:10:57.883739Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 54990/133889 blocks (41.1%), 0 events -2026-02-04T19:10:58.052062Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55000/133889 blocks (41.1%), 0 events -2026-02-04T19:10:58.243954Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55010/133889 blocks (41.1%), 0 events -2026-02-04T19:10:58.448248Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55020/133889 blocks (41.1%), 0 events -2026-02-04T19:10:58.625998Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55030/133889 blocks (41.1%), 0 events -2026-02-04T19:10:58.765588Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55040/133889 blocks (41.1%), 0 events -2026-02-04T19:10:59.008694Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55050/133889 blocks (41.1%), 0 events -2026-02-04T19:10:59.218790Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55060/133889 blocks (41.1%), 0 events -2026-02-04T19:10:59.497325Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55070/133889 blocks (41.1%), 0 events -2026-02-04T19:10:59.629589Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55080/133889 blocks (41.1%), 0 events -2026-02-04T19:10:59.846925Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55090/133889 blocks (41.1%), 0 events -2026-02-04T19:11:00.056512Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55100/133889 blocks (41.2%), 0 events -2026-02-04T19:11:00.196096Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55110/133889 blocks (41.2%), 0 events -2026-02-04T19:11:00.540954Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55120/133889 blocks (41.2%), 0 events -2026-02-04T19:11:00.583619Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55130/133889 blocks (41.2%), 0 events -2026-02-04T19:11:00.861525Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55140/133889 blocks (41.2%), 0 events -2026-02-04T19:11:01.062918Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55150/133889 blocks (41.2%), 0 events -2026-02-04T19:11:01.243819Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55160/133889 blocks (41.2%), 0 events -2026-02-04T19:11:01.442710Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55170/133889 blocks (41.2%), 0 events -2026-02-04T19:11:01.617899Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55180/133889 blocks (41.2%), 0 events -2026-02-04T19:11:01.838426Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55190/133889 blocks (41.2%), 0 events -2026-02-04T19:11:02.080841Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55200/133889 blocks (41.2%), 0 events -2026-02-04T19:11:02.215763Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55210/133889 blocks (41.2%), 0 events -2026-02-04T19:11:02.399273Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55220/133889 blocks (41.2%), 0 events -2026-02-04T19:11:02.643182Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55230/133889 blocks (41.3%), 0 events -2026-02-04T19:11:02.815308Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55240/133889 blocks (41.3%), 0 events -2026-02-04T19:11:03.129626Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55250/133889 blocks (41.3%), 0 events -2026-02-04T19:11:03.168276Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55260/133889 blocks (41.3%), 0 events -2026-02-04T19:11:03.448665Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55270/133889 blocks (41.3%), 0 events -2026-02-04T19:11:03.653260Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55280/133889 blocks (41.3%), 0 events -2026-02-04T19:11:03.855289Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55290/133889 blocks (41.3%), 0 events -2026-02-04T19:11:03.969576Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55300/133889 blocks (41.3%), 0 events -2026-02-04T19:11:04.223353Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55310/133889 blocks (41.3%), 0 events -2026-02-04T19:11:04.453580Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55320/133889 blocks (41.3%), 0 events -2026-02-04T19:11:04.735734Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55330/133889 blocks (41.3%), 0 events -2026-02-04T19:11:04.799111Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55340/133889 blocks (41.3%), 0 events -2026-02-04T19:11:05.054639Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55350/133889 blocks (41.3%), 0 events -2026-02-04T19:11:05.267763Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55360/133889 blocks (41.3%), 0 events -2026-02-04T19:11:05.376694Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55370/133889 blocks (41.4%), 0 events -2026-02-04T19:11:05.619686Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55380/133889 blocks (41.4%), 0 events -2026-02-04T19:11:05.795464Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55390/133889 blocks (41.4%), 0 events -2026-02-04T19:11:06.029678Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55400/133889 blocks (41.4%), 0 events -2026-02-04T19:11:06.275484Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55410/133889 blocks (41.4%), 0 events -2026-02-04T19:11:06.360442Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55420/133889 blocks (41.4%), 0 events -2026-02-04T19:11:06.636236Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55430/133889 blocks (41.4%), 0 events -2026-02-04T19:11:06.833680Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55440/133889 blocks (41.4%), 0 events -2026-02-04T19:11:07.014062Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55450/133889 blocks (41.4%), 0 events -2026-02-04T19:11:07.216429Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55460/133889 blocks (41.4%), 0 events -2026-02-04T19:11:07.464149Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55470/133889 blocks (41.4%), 0 events -2026-02-04T19:11:07.586875Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55480/133889 blocks (41.4%), 0 events -2026-02-04T19:11:07.846975Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55490/133889 blocks (41.4%), 0 events -2026-02-04T19:11:08.038193Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55500/133889 blocks (41.5%), 0 events -2026-02-04T19:11:08.220304Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55510/133889 blocks (41.5%), 0 events -2026-02-04T19:11:08.411196Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55520/133889 blocks (41.5%), 0 events -2026-02-04T19:11:08.573598Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55530/133889 blocks (41.5%), 0 events -2026-02-04T19:11:08.777647Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55540/133889 blocks (41.5%), 0 events -2026-02-04T19:11:09.025210Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55550/133889 blocks (41.5%), 0 events -2026-02-04T19:11:09.197383Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55560/133889 blocks (41.5%), 0 events -2026-02-04T19:11:09.454662Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55570/133889 blocks (41.5%), 0 events -2026-02-04T19:11:09.630325Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55580/133889 blocks (41.5%), 0 events -2026-02-04T19:11:09.839330Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55590/133889 blocks (41.5%), 0 events -2026-02-04T19:11:09.983549Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55600/133889 blocks (41.5%), 0 events -2026-02-04T19:11:10.194233Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55610/133889 blocks (41.5%), 0 events -2026-02-04T19:11:10.502772Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55620/133889 blocks (41.5%), 0 events -2026-02-04T19:11:10.644062Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55630/133889 blocks (41.5%), 0 events -2026-02-04T19:11:10.832652Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55640/133889 blocks (41.6%), 0 events -2026-02-04T19:11:11.034638Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55650/133889 blocks (41.6%), 0 events -2026-02-04T19:11:11.229386Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55660/133889 blocks (41.6%), 0 events -2026-02-04T19:11:11.376784Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55670/133889 blocks (41.6%), 0 events -2026-02-04T19:11:11.569370Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55680/133889 blocks (41.6%), 0 events -2026-02-04T19:11:11.836666Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55690/133889 blocks (41.6%), 0 events -2026-02-04T19:11:12.076242Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55700/133889 blocks (41.6%), 0 events -2026-02-04T19:11:12.250809Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55710/133889 blocks (41.6%), 0 events -2026-02-04T19:11:12.377793Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55720/133889 blocks (41.6%), 0 events -2026-02-04T19:11:12.665746Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55730/133889 blocks (41.6%), 0 events -2026-02-04T19:11:12.860440Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55740/133889 blocks (41.6%), 0 events -2026-02-04T19:11:13.089941Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55750/133889 blocks (41.6%), 0 events -2026-02-04T19:11:13.209096Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55760/133889 blocks (41.6%), 0 events -2026-02-04T19:11:13.398541Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55770/133889 blocks (41.7%), 0 events -2026-02-04T19:11:13.647523Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55780/133889 blocks (41.7%), 0 events -2026-02-04T19:11:13.834892Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55790/133889 blocks (41.7%), 0 events -2026-02-04T19:11:14.139656Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55800/133889 blocks (41.7%), 0 events -2026-02-04T19:11:14.181802Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55810/133889 blocks (41.7%), 0 events -2026-02-04T19:11:14.393863Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55820/133889 blocks (41.7%), 0 events -2026-02-04T19:11:14.663635Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55830/133889 blocks (41.7%), 0 events -2026-02-04T19:11:14.806567Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55840/133889 blocks (41.7%), 0 events -2026-02-04T19:11:14.977808Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55850/133889 blocks (41.7%), 0 events -2026-02-04T19:11:15.221306Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55860/133889 blocks (41.7%), 0 events -2026-02-04T19:11:15.427627Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55870/133889 blocks (41.7%), 0 events -2026-02-04T19:11:15.712283Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55880/133889 blocks (41.7%), 0 events -2026-02-04T19:11:15.820976Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55890/133889 blocks (41.7%), 0 events -2026-02-04T19:11:15.971539Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55900/133889 blocks (41.8%), 0 events -2026-02-04T19:11:16.265947Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55910/133889 blocks (41.8%), 0 events -2026-02-04T19:11:16.409387Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55920/133889 blocks (41.8%), 0 events -2026-02-04T19:11:16.643838Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55930/133889 blocks (41.8%), 0 events -2026-02-04T19:11:16.823725Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55940/133889 blocks (41.8%), 0 events -2026-02-04T19:11:16.968839Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55950/133889 blocks (41.8%), 0 events -2026-02-04T19:11:17.285192Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55960/133889 blocks (41.8%), 0 events -2026-02-04T19:11:17.416405Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55970/133889 blocks (41.8%), 0 events -2026-02-04T19:11:17.571219Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55980/133889 blocks (41.8%), 0 events -2026-02-04T19:11:17.859796Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 55990/133889 blocks (41.8%), 0 events -2026-02-04T19:11:17.993803Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56000/133889 blocks (41.8%), 0 events -2026-02-04T19:11:18.173498Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56010/133889 blocks (41.8%), 0 events -2026-02-04T19:11:18.529269Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56020/133889 blocks (41.8%), 0 events -2026-02-04T19:11:18.568363Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56030/133889 blocks (41.8%), 0 events -2026-02-04T19:11:18.896500Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56040/133889 blocks (41.9%), 0 events -2026-02-04T19:11:19.087299Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56050/133889 blocks (41.9%), 0 events -2026-02-04T19:11:19.196563Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56060/133889 blocks (41.9%), 0 events -2026-02-04T19:11:19.412332Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56070/133889 blocks (41.9%), 0 events -2026-02-04T19:11:19.615000Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56080/133889 blocks (41.9%), 0 events -2026-02-04T19:11:19.782189Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56090/133889 blocks (41.9%), 0 events -2026-02-04T19:11:20.102317Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56100/133889 blocks (41.9%), 0 events -2026-02-04T19:11:20.187653Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56110/133889 blocks (41.9%), 0 events -2026-02-04T19:11:20.470110Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56120/133889 blocks (41.9%), 0 events -2026-02-04T19:11:20.626058Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56130/133889 blocks (41.9%), 0 events -2026-02-04T19:11:20.827946Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56140/133889 blocks (41.9%), 0 events -2026-02-04T19:11:21.017148Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56150/133889 blocks (41.9%), 0 events -2026-02-04T19:11:21.184174Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56160/133889 blocks (41.9%), 0 events -2026-02-04T19:11:21.523246Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56170/133889 blocks (42.0%), 0 events -2026-02-04T19:11:21.563121Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56180/133889 blocks (42.0%), 0 events -2026-02-04T19:11:21.804448Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56190/133889 blocks (42.0%), 0 events -2026-02-04T19:11:22.041980Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56200/133889 blocks (42.0%), 0 events -2026-02-04T19:11:22.237428Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56210/133889 blocks (42.0%), 0 events -2026-02-04T19:11:22.526851Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56220/133889 blocks (42.0%), 0 events -2026-02-04T19:11:22.569025Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56230/133889 blocks (42.0%), 0 events -2026-02-04T19:11:22.778578Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56240/133889 blocks (42.0%), 0 events -2026-02-04T19:11:23.084854Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56250/133889 blocks (42.0%), 0 events -2026-02-04T19:11:23.280885Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56260/133889 blocks (42.0%), 0 events -2026-02-04T19:11:23.418435Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56270/133889 blocks (42.0%), 0 events -2026-02-04T19:11:23.608439Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56280/133889 blocks (42.0%), 0 events -2026-02-04T19:11:23.864585Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56290/133889 blocks (42.0%), 0 events -2026-02-04T19:11:23.979638Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56300/133889 blocks (42.0%), 0 events -2026-02-04T19:11:24.198306Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56310/133889 blocks (42.1%), 0 events -2026-02-04T19:11:24.453443Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56320/133889 blocks (42.1%), 0 events -2026-02-04T19:11:24.653052Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56330/133889 blocks (42.1%), 0 events -2026-02-04T19:11:24.782796Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56340/133889 blocks (42.1%), 0 events -2026-02-04T19:11:24.969025Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56350/133889 blocks (42.1%), 0 events -2026-02-04T19:11:25.256907Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56360/133889 blocks (42.1%), 0 events -2026-02-04T19:11:25.368215Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56370/133889 blocks (42.1%), 0 events -2026-02-04T19:11:25.707802Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56380/133889 blocks (42.1%), 0 events -2026-02-04T19:11:25.797628Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56390/133889 blocks (42.1%), 0 events -2026-02-04T19:11:25.988108Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56400/133889 blocks (42.1%), 0 events -2026-02-04T19:11:26.230680Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56410/133889 blocks (42.1%), 0 events -2026-02-04T19:11:26.396432Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56420/133889 blocks (42.1%), 0 events -2026-02-04T19:11:26.601491Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56430/133889 blocks (42.1%), 0 events -2026-02-04T19:11:26.787607Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56440/133889 blocks (42.2%), 0 events -2026-02-04T19:11:27.040969Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56450/133889 blocks (42.2%), 0 events -2026-02-04T19:11:27.281862Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56460/133889 blocks (42.2%), 0 events -2026-02-04T19:11:27.385340Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56470/133889 blocks (42.2%), 0 events -2026-02-04T19:11:27.646019Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56480/133889 blocks (42.2%), 0 events -2026-02-04T19:11:27.804275Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56490/133889 blocks (42.2%), 0 events -2026-02-04T19:11:28.055350Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56500/133889 blocks (42.2%), 0 events -2026-02-04T19:11:28.187096Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56510/133889 blocks (42.2%), 0 events -2026-02-04T19:11:28.399956Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56520/133889 blocks (42.2%), 0 events -2026-02-04T19:11:28.620624Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56530/133889 blocks (42.2%), 0 events -2026-02-04T19:11:28.851462Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56540/133889 blocks (42.2%), 0 events -2026-02-04T19:11:28.988883Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56550/133889 blocks (42.2%), 0 events -2026-02-04T19:11:29.226381Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56560/133889 blocks (42.2%), 0 events -2026-02-04T19:11:29.431505Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56570/133889 blocks (42.3%), 0 events -2026-02-04T19:11:29.629692Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56580/133889 blocks (42.3%), 0 events -2026-02-04T19:11:29.908236Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56590/133889 blocks (42.3%), 0 events -2026-02-04T19:11:29.982441Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56600/133889 blocks (42.3%), 0 events -2026-02-04T19:11:30.175232Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56610/133889 blocks (42.3%), 0 events -2026-02-04T19:11:30.424652Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56620/133889 blocks (42.3%), 0 events -2026-02-04T19:11:30.619657Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56630/133889 blocks (42.3%), 0 events -2026-02-04T19:11:30.808038Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56640/133889 blocks (42.3%), 0 events -2026-02-04T19:11:31.016639Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56650/133889 blocks (42.3%), 0 events -2026-02-04T19:11:31.232556Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56660/133889 blocks (42.3%), 0 events -2026-02-04T19:11:31.472063Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56670/133889 blocks (42.3%), 0 events -2026-02-04T19:11:31.581295Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56680/133889 blocks (42.3%), 0 events -2026-02-04T19:11:31.776618Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56690/133889 blocks (42.3%), 0 events -2026-02-04T19:11:32.029371Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56700/133889 blocks (42.3%), 0 events -2026-02-04T19:11:32.185510Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56710/133889 blocks (42.4%), 0 events -2026-02-04T19:11:32.518238Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56720/133889 blocks (42.4%), 0 events -2026-02-04T19:11:32.553500Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56730/133889 blocks (42.4%), 0 events -2026-02-04T19:11:32.802823Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56740/133889 blocks (42.4%), 0 events -2026-02-04T19:11:33.045581Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56750/133889 blocks (42.4%), 0 events -2026-02-04T19:11:33.206129Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56760/133889 blocks (42.4%), 0 events -2026-02-04T19:11:33.536888Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56770/133889 blocks (42.4%), 0 events -2026-02-04T19:11:33.576933Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56780/133889 blocks (42.4%), 0 events -2026-02-04T19:11:33.801758Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56790/133889 blocks (42.4%), 0 events -2026-02-04T19:11:34.095979Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56800/133889 blocks (42.4%), 0 events -2026-02-04T19:11:34.203253Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56810/133889 blocks (42.4%), 0 events -2026-02-04T19:11:34.458421Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56820/133889 blocks (42.4%), 0 events -2026-02-04T19:11:34.618915Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56830/133889 blocks (42.4%), 0 events -2026-02-04T19:11:34.781284Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56840/133889 blocks (42.5%), 0 events -2026-02-04T19:11:35.144825Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56850/133889 blocks (42.5%), 0 events -2026-02-04T19:11:35.181616Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56860/133889 blocks (42.5%), 0 events -2026-02-04T19:11:35.373184Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56870/133889 blocks (42.5%), 0 events -2026-02-04T19:11:35.665698Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56880/133889 blocks (42.5%), 0 events -2026-02-04T19:11:35.835203Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56890/133889 blocks (42.5%), 0 events -2026-02-04T19:11:35.964994Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56900/133889 blocks (42.5%), 0 events -2026-02-04T19:11:36.219089Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56910/133889 blocks (42.5%), 0 events -2026-02-04T19:11:36.424904Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56920/133889 blocks (42.5%), 0 events -2026-02-04T19:11:36.714293Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56930/133889 blocks (42.5%), 0 events -2026-02-04T19:11:36.799273Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56940/133889 blocks (42.5%), 0 events -2026-02-04T19:11:36.988236Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56950/133889 blocks (42.5%), 0 events -2026-02-04T19:11:37.240213Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56960/133889 blocks (42.5%), 0 events -2026-02-04T19:11:37.389587Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56970/133889 blocks (42.5%), 0 events -2026-02-04T19:11:37.581374Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56980/133889 blocks (42.6%), 0 events -2026-02-04T19:11:37.839604Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 56990/133889 blocks (42.6%), 0 events -2026-02-04T19:11:38.029115Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57000/133889 blocks (42.6%), 0 events -2026-02-04T19:11:38.286755Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57010/133889 blocks (42.6%), 0 events -2026-02-04T19:11:38.368158Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57020/133889 blocks (42.6%), 0 events -2026-02-04T19:11:38.622678Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57030/133889 blocks (42.6%), 0 events -2026-02-04T19:11:38.807113Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57040/133889 blocks (42.6%), 0 events -2026-02-04T19:11:38.991837Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57050/133889 blocks (42.6%), 0 events -2026-02-04T19:11:39.185324Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57060/133889 blocks (42.6%), 0 events -2026-02-04T19:11:39.473200Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57070/133889 blocks (42.6%), 0 events -2026-02-04T19:11:39.649673Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57080/133889 blocks (42.6%), 0 events -2026-02-04T19:11:39.861225Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57090/133889 blocks (42.6%), 0 events -2026-02-04T19:11:40.058176Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57100/133889 blocks (42.6%), 0 events -2026-02-04T19:11:40.226658Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57110/133889 blocks (42.7%), 0 events -2026-02-04T19:11:40.388164Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57120/133889 blocks (42.7%), 0 events -2026-02-04T19:11:40.588039Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57130/133889 blocks (42.7%), 0 events -2026-02-04T19:11:40.919323Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57140/133889 blocks (42.7%), 0 events -2026-02-04T19:11:40.956991Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57150/133889 blocks (42.7%), 0 events -2026-02-04T19:11:41.168907Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57160/133889 blocks (42.7%), 0 events -2026-02-04T19:11:41.433099Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57170/133889 blocks (42.7%), 0 events -2026-02-04T19:11:41.651027Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57180/133889 blocks (42.7%), 0 events -2026-02-04T19:11:41.765724Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57190/133889 blocks (42.7%), 0 events -2026-02-04T19:11:41.995216Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57200/133889 blocks (42.7%), 0 events -2026-02-04T19:11:42.205610Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57210/133889 blocks (42.7%), 0 events -2026-02-04T19:11:42.449355Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57220/133889 blocks (42.7%), 0 events -2026-02-04T19:11:42.619218Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57230/133889 blocks (42.7%), 0 events -2026-02-04T19:11:42.857675Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57240/133889 blocks (42.8%), 0 events -2026-02-04T19:11:43.000935Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57250/133889 blocks (42.8%), 0 events -2026-02-04T19:11:43.215273Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57260/133889 blocks (42.8%), 0 events -2026-02-04T19:11:43.381456Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57270/133889 blocks (42.8%), 0 events -2026-02-04T19:11:43.605156Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57280/133889 blocks (42.8%), 0 events -2026-02-04T19:11:43.774406Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57290/133889 blocks (42.8%), 0 events -2026-02-04T19:11:44.055871Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57300/133889 blocks (42.8%), 0 events -2026-02-04T19:11:44.182911Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57310/133889 blocks (42.8%), 0 events -2026-02-04T19:11:44.546560Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57320/133889 blocks (42.8%), 0 events -2026-02-04T19:11:44.589183Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57330/133889 blocks (42.8%), 0 events -2026-02-04T19:11:44.818424Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57340/133889 blocks (42.8%), 0 events -2026-02-04T19:11:45.216575Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57350/133889 blocks (42.8%), 0 events -2026-02-04T19:11:45.261448Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57360/133889 blocks (42.8%), 0 events -2026-02-04T19:11:45.378037Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57370/133889 blocks (42.8%), 0 events -2026-02-04T19:11:45.651674Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57380/133889 blocks (42.9%), 0 events -2026-02-04T19:11:45.772281Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57390/133889 blocks (42.9%), 0 events -2026-02-04T19:11:45.979687Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57400/133889 blocks (42.9%), 0 events -2026-02-04T19:11:46.175606Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57410/133889 blocks (42.9%), 0 events -2026-02-04T19:11:46.396157Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57420/133889 blocks (42.9%), 0 events -2026-02-04T19:11:46.678742Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57430/133889 blocks (42.9%), 0 events -2026-02-04T19:11:46.810493Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57440/133889 blocks (42.9%), 0 events -2026-02-04T19:11:47.020867Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57450/133889 blocks (42.9%), 0 events -2026-02-04T19:11:47.210656Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57460/133889 blocks (42.9%), 0 events -2026-02-04T19:11:47.463710Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57470/133889 blocks (42.9%), 0 events -2026-02-04T19:11:47.724192Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57480/133889 blocks (42.9%), 0 events -2026-02-04T19:11:47.761137Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57490/133889 blocks (42.9%), 0 events -2026-02-04T19:11:47.977611Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57500/133889 blocks (42.9%), 0 events -2026-02-04T19:11:48.251096Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57510/133889 blocks (43.0%), 0 events -2026-02-04T19:11:48.410202Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57520/133889 blocks (43.0%), 0 events -2026-02-04T19:11:48.581993Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57530/133889 blocks (43.0%), 0 events -2026-02-04T19:11:48.861321Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57540/133889 blocks (43.0%), 0 events -2026-02-04T19:11:49.007902Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57550/133889 blocks (43.0%), 0 events -2026-02-04T19:11:49.266436Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57560/133889 blocks (43.0%), 0 events -2026-02-04T19:11:49.446879Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57570/133889 blocks (43.0%), 0 events -2026-02-04T19:11:49.584359Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57580/133889 blocks (43.0%), 0 events -2026-02-04T19:11:49.828166Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57590/133889 blocks (43.0%), 0 events -2026-02-04T19:11:50.022711Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57600/133889 blocks (43.0%), 0 events -2026-02-04T19:11:50.311338Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57610/133889 blocks (43.0%), 0 events -2026-02-04T19:11:50.442281Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57620/133889 blocks (43.0%), 0 events -2026-02-04T19:11:50.623545Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57630/133889 blocks (43.0%), 0 events -2026-02-04T19:11:50.870482Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57640/133889 blocks (43.1%), 0 events -2026-02-04T19:11:51.058374Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57650/133889 blocks (43.1%), 0 events -2026-02-04T19:11:51.163483Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57660/133889 blocks (43.1%), 0 events -2026-02-04T19:11:51.429554Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57670/133889 blocks (43.1%), 0 events -2026-02-04T19:11:51.618569Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57680/133889 blocks (43.1%), 0 events -2026-02-04T19:11:51.772774Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57690/133889 blocks (43.1%), 0 events -2026-02-04T19:11:51.976020Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57700/133889 blocks (43.1%), 0 events -2026-02-04T19:11:52.182935Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57710/133889 blocks (43.1%), 0 events -2026-02-04T19:11:52.446999Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57720/133889 blocks (43.1%), 0 events -2026-02-04T19:11:52.650780Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57730/133889 blocks (43.1%), 0 events -2026-02-04T19:11:52.823836Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57740/133889 blocks (43.1%), 0 events -2026-02-04T19:11:53.036868Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57750/133889 blocks (43.1%), 0 events -2026-02-04T19:11:53.271278Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57760/133889 blocks (43.1%), 0 events -2026-02-04T19:11:53.458762Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57770/133889 blocks (43.1%), 0 events -2026-02-04T19:11:53.600156Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57780/133889 blocks (43.2%), 0 events -2026-02-04T19:11:53.854108Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57790/133889 blocks (43.2%), 0 events -2026-02-04T19:11:54.071621Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57800/133889 blocks (43.2%), 0 events -2026-02-04T19:11:54.292294Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57810/133889 blocks (43.2%), 0 events -2026-02-04T19:11:54.403024Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57820/133889 blocks (43.2%), 0 events -2026-02-04T19:11:54.627381Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57830/133889 blocks (43.2%), 0 events -2026-02-04T19:11:54.845642Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57840/133889 blocks (43.2%), 0 events -2026-02-04T19:11:55.063049Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57850/133889 blocks (43.2%), 0 events -2026-02-04T19:11:55.227649Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57860/133889 blocks (43.2%), 0 events -2026-02-04T19:11:55.395532Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57870/133889 blocks (43.2%), 0 events -2026-02-04T19:11:55.629013Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57880/133889 blocks (43.2%), 0 events -2026-02-04T19:11:55.832799Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57890/133889 blocks (43.2%), 0 events -2026-02-04T19:11:56.079395Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57900/133889 blocks (43.2%), 0 events -2026-02-04T19:11:56.229913Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57910/133889 blocks (43.3%), 0 events -2026-02-04T19:11:56.391798Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57920/133889 blocks (43.3%), 0 events -2026-02-04T19:11:56.650014Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57930/133889 blocks (43.3%), 0 events -2026-02-04T19:11:56.846444Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57940/133889 blocks (43.3%), 0 events -2026-02-04T19:11:57.129645Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57950/133889 blocks (43.3%), 0 events -2026-02-04T19:11:57.173039Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57960/133889 blocks (43.3%), 0 events -2026-02-04T19:11:57.386191Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57970/133889 blocks (43.3%), 0 events -2026-02-04T19:11:57.686250Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57980/133889 blocks (43.3%), 0 events -2026-02-04T19:11:57.814629Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 57990/133889 blocks (43.3%), 0 events -2026-02-04T19:11:57.973440Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58000/133889 blocks (43.3%), 0 events -2026-02-04T19:11:58.236668Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58010/133889 blocks (43.3%), 0 events -2026-02-04T19:11:58.463427Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58020/133889 blocks (43.3%), 0 events -2026-02-04T19:11:58.699495Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58030/133889 blocks (43.3%), 0 events -2026-02-04T19:11:58.846187Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58040/133889 blocks (43.3%), 0 events -2026-02-04T19:11:59.018391Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58050/133889 blocks (43.4%), 0 events -2026-02-04T19:11:59.260256Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58060/133889 blocks (43.4%), 0 events -2026-02-04T19:11:59.437593Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58070/133889 blocks (43.4%), 0 events -2026-02-04T19:11:59.578255Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58080/133889 blocks (43.4%), 0 events -2026-02-04T19:11:59.805987Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58090/133889 blocks (43.4%), 0 events -2026-02-04T19:12:00.054838Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58100/133889 blocks (43.4%), 0 events -2026-02-04T19:12:00.183282Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58110/133889 blocks (43.4%), 0 events -2026-02-04T19:12:00.390715Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58120/133889 blocks (43.4%), 0 events -2026-02-04T19:12:00.651469Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58130/133889 blocks (43.4%), 0 events -2026-02-04T19:12:00.829003Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58140/133889 blocks (43.4%), 0 events -2026-02-04T19:12:00.999476Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58150/133889 blocks (43.4%), 0 events -2026-02-04T19:12:01.183755Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58160/133889 blocks (43.4%), 0 events -2026-02-04T19:12:01.439456Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58170/133889 blocks (43.4%), 0 events -2026-02-04T19:12:01.608592Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58180/133889 blocks (43.5%), 0 events -2026-02-04T19:12:01.880591Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58190/133889 blocks (43.5%), 0 events -2026-02-04T19:12:02.000809Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58200/133889 blocks (43.5%), 0 events -2026-02-04T19:12:02.226940Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58210/133889 blocks (43.5%), 0 events -2026-02-04T19:12:02.434071Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58220/133889 blocks (43.5%), 0 events -2026-02-04T19:12:02.641288Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58230/133889 blocks (43.5%), 0 events -2026-02-04T19:12:02.893455Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58240/133889 blocks (43.5%), 0 events -2026-02-04T19:12:03.000761Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58250/133889 blocks (43.5%), 0 events -2026-02-04T19:12:03.217657Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58260/133889 blocks (43.5%), 0 events -2026-02-04T19:12:03.459533Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58270/133889 blocks (43.5%), 0 events -2026-02-04T19:12:03.607073Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58280/133889 blocks (43.5%), 0 events -2026-02-04T19:12:03.797440Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58290/133889 blocks (43.5%), 0 events -2026-02-04T19:12:04.064560Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58300/133889 blocks (43.5%), 0 events -2026-02-04T19:12:04.260103Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58310/133889 blocks (43.6%), 0 events -2026-02-04T19:12:04.468452Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58320/133889 blocks (43.6%), 0 events -2026-02-04T19:12:04.637567Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58330/133889 blocks (43.6%), 0 events -2026-02-04T19:12:04.850541Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58340/133889 blocks (43.6%), 0 events -2026-02-04T19:12:05.036877Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58350/133889 blocks (43.6%), 0 events -2026-02-04T19:12:05.209170Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58360/133889 blocks (43.6%), 0 events -2026-02-04T19:12:05.383216Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58370/133889 blocks (43.6%), 0 events -2026-02-04T19:12:05.660410Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58380/133889 blocks (43.6%), 0 events -2026-02-04T19:12:05.828035Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58390/133889 blocks (43.6%), 0 events -2026-02-04T19:12:06.072435Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58400/133889 blocks (43.6%), 0 events -2026-02-04T19:12:06.167229Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58410/133889 blocks (43.6%), 0 events -2026-02-04T19:12:06.425642Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58420/133889 blocks (43.6%), 0 events -2026-02-04T19:12:06.600745Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58430/133889 blocks (43.6%), 0 events -2026-02-04T19:12:06.827506Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58440/133889 blocks (43.6%), 0 events -2026-02-04T19:12:07.090125Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58450/133889 blocks (43.7%), 0 events -2026-02-04T19:12:07.208577Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58460/133889 blocks (43.7%), 0 events -2026-02-04T19:12:07.376677Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58470/133889 blocks (43.7%), 0 events -2026-02-04T19:12:07.649903Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58480/133889 blocks (43.7%), 0 events -2026-02-04T19:12:07.775057Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58490/133889 blocks (43.7%), 0 events -2026-02-04T19:12:08.139256Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58500/133889 blocks (43.7%), 0 events -2026-02-04T19:12:08.180570Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58510/133889 blocks (43.7%), 0 events -2026-02-04T19:12:08.398088Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58520/133889 blocks (43.7%), 0 events -2026-02-04T19:12:08.693416Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58530/133889 blocks (43.7%), 0 events -2026-02-04T19:12:08.825147Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58540/133889 blocks (43.7%), 0 events -2026-02-04T19:12:09.024776Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58550/133889 blocks (43.7%), 0 events -2026-02-04T19:12:09.284747Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58560/133889 blocks (43.7%), 0 events -2026-02-04T19:12:09.409201Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58570/133889 blocks (43.7%), 0 events -2026-02-04T19:12:09.711649Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58580/133889 blocks (43.8%), 0 events -2026-02-04T19:12:09.791260Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58590/133889 blocks (43.8%), 0 events -2026-02-04T19:12:09.963245Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58600/133889 blocks (43.8%), 0 events -2026-02-04T19:12:10.268010Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58610/133889 blocks (43.8%), 0 events -2026-02-04T19:12:10.400627Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58620/133889 blocks (43.8%), 0 events -2026-02-04T19:12:10.602764Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58630/133889 blocks (43.8%), 0 events -2026-02-04T19:12:10.839302Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58640/133889 blocks (43.8%), 0 events -2026-02-04T19:12:11.049635Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58650/133889 blocks (43.8%), 0 events -2026-02-04T19:12:11.284507Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58660/133889 blocks (43.8%), 0 events -2026-02-04T19:12:11.445493Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58670/133889 blocks (43.8%), 0 events -2026-02-04T19:12:11.571993Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58680/133889 blocks (43.8%), 0 events -2026-02-04T19:12:11.851506Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58690/133889 blocks (43.8%), 0 events -2026-02-04T19:12:12.052405Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58700/133889 blocks (43.8%), 0 events -2026-02-04T19:12:12.199430Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58710/133889 blocks (43.8%), 0 events -2026-02-04T19:12:12.425516Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58720/133889 blocks (43.9%), 0 events -2026-02-04T19:12:12.572464Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58730/133889 blocks (43.9%), 0 events -2026-02-04T19:12:12.892387Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58740/133889 blocks (43.9%), 0 events -2026-02-04T19:12:12.972531Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58750/133889 blocks (43.9%), 0 events -2026-02-04T19:12:13.196338Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58760/133889 blocks (43.9%), 0 events -2026-02-04T19:12:13.418833Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58770/133889 blocks (43.9%), 0 events -2026-02-04T19:12:13.587103Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58780/133889 blocks (43.9%), 0 events -2026-02-04T19:12:13.775375Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58790/133889 blocks (43.9%), 0 events -2026-02-04T19:12:14.003707Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58800/133889 blocks (43.9%), 0 events -2026-02-04T19:12:14.192543Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58810/133889 blocks (43.9%), 0 events -2026-02-04T19:12:14.460841Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58820/133889 blocks (43.9%), 0 events -2026-02-04T19:12:14.599700Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58830/133889 blocks (43.9%), 0 events -2026-02-04T19:12:14.850009Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58840/133889 blocks (43.9%), 0 events -2026-02-04T19:12:14.988011Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58850/133889 blocks (44.0%), 0 events -2026-02-04T19:12:15.218712Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58860/133889 blocks (44.0%), 0 events -2026-02-04T19:12:15.514682Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58870/133889 blocks (44.0%), 0 events -2026-02-04T19:12:15.676438Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58880/133889 blocks (44.0%), 0 events -2026-02-04T19:12:15.824576Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58890/133889 blocks (44.0%), 0 events -2026-02-04T19:12:16.036816Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58900/133889 blocks (44.0%), 0 events -2026-02-04T19:12:16.230777Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58910/133889 blocks (44.0%), 0 events -2026-02-04T19:12:16.402413Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58920/133889 blocks (44.0%), 0 events -2026-02-04T19:12:16.590399Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58930/133889 blocks (44.0%), 0 events -2026-02-04T19:12:16.825352Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58940/133889 blocks (44.0%), 0 events -2026-02-04T19:12:17.085581Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58950/133889 blocks (44.0%), 0 events -2026-02-04T19:12:17.259316Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58960/133889 blocks (44.0%), 0 events -2026-02-04T19:12:17.384211Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58970/133889 blocks (44.0%), 0 events -2026-02-04T19:12:17.648917Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58980/133889 blocks (44.1%), 0 events -2026-02-04T19:12:17.845369Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 58990/133889 blocks (44.1%), 0 events -2026-02-04T19:12:18.099185Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59000/133889 blocks (44.1%), 0 events -2026-02-04T19:12:18.236774Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59010/133889 blocks (44.1%), 0 events -2026-02-04T19:12:18.426017Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59020/133889 blocks (44.1%), 0 events -2026-02-04T19:12:18.653819Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59030/133889 blocks (44.1%), 0 events -2026-02-04T19:12:18.860809Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59040/133889 blocks (44.1%), 0 events -2026-02-04T19:12:19.148152Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59050/133889 blocks (44.1%), 0 events -2026-02-04T19:12:19.184549Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59060/133889 blocks (44.1%), 0 events -2026-02-04T19:12:19.459339Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59070/133889 blocks (44.1%), 0 events -2026-02-04T19:12:19.672122Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59080/133889 blocks (44.1%), 0 events -2026-02-04T19:12:19.868252Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59090/133889 blocks (44.1%), 0 events -2026-02-04T19:12:20.043369Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59100/133889 blocks (44.1%), 0 events -2026-02-04T19:12:20.229039Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59110/133889 blocks (44.1%), 0 events -2026-02-04T19:12:20.432710Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59120/133889 blocks (44.2%), 0 events -2026-02-04T19:12:20.618473Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59130/133889 blocks (44.2%), 0 events -2026-02-04T19:12:20.768634Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59140/133889 blocks (44.2%), 0 events -2026-02-04T19:12:20.993915Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59150/133889 blocks (44.2%), 0 events -2026-02-04T19:12:21.244770Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59160/133889 blocks (44.2%), 0 events -2026-02-04T19:12:21.482580Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59170/133889 blocks (44.2%), 0 events -2026-02-04T19:12:21.637244Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59180/133889 blocks (44.2%), 0 events -2026-02-04T19:12:21.820357Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59190/133889 blocks (44.2%), 0 events -2026-02-04T19:12:22.015054Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59200/133889 blocks (44.2%), 0 events -2026-02-04T19:12:22.196363Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59210/133889 blocks (44.2%), 0 events -2026-02-04T19:12:22.392823Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59220/133889 blocks (44.2%), 0 events -2026-02-04T19:12:22.661132Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59230/133889 blocks (44.2%), 0 events -2026-02-04T19:12:22.853648Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59240/133889 blocks (44.2%), 0 events -2026-02-04T19:12:22.976262Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59250/133889 blocks (44.3%), 0 events -2026-02-04T19:12:23.341635Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59260/133889 blocks (44.3%), 0 events -2026-02-04T19:12:23.379123Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59270/133889 blocks (44.3%), 0 events -2026-02-04T19:12:23.640664Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59280/133889 blocks (44.3%), 0 events -2026-02-04T19:12:23.866011Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59290/133889 blocks (44.3%), 0 events -2026-02-04T19:12:23.997686Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59300/133889 blocks (44.3%), 0 events -2026-02-04T19:12:24.209875Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59310/133889 blocks (44.3%), 0 events -2026-02-04T19:12:24.442666Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59320/133889 blocks (44.3%), 0 events -2026-02-04T19:12:24.592970Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59330/133889 blocks (44.3%), 0 events -2026-02-04T19:12:24.815348Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59340/133889 blocks (44.3%), 0 events -2026-02-04T19:12:24.974428Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59350/133889 blocks (44.3%), 0 events -2026-02-04T19:12:25.223433Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59360/133889 blocks (44.3%), 0 events -2026-02-04T19:12:25.485460Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59370/133889 blocks (44.3%), 0 events -2026-02-04T19:12:25.644385Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59380/133889 blocks (44.3%), 0 events -2026-02-04T19:12:25.850326Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59390/133889 blocks (44.4%), 0 events -2026-02-04T19:12:26.016750Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59400/133889 blocks (44.4%), 0 events -2026-02-04T19:12:26.235626Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59410/133889 blocks (44.4%), 0 events -2026-02-04T19:12:26.487000Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59420/133889 blocks (44.4%), 0 events -2026-02-04T19:12:26.620031Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59430/133889 blocks (44.4%), 0 events -2026-02-04T19:12:26.855666Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59440/133889 blocks (44.4%), 0 events -2026-02-04T19:12:27.056271Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59450/133889 blocks (44.4%), 0 events -2026-02-04T19:12:27.255080Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59460/133889 blocks (44.4%), 0 events -2026-02-04T19:12:27.436271Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59470/133889 blocks (44.4%), 0 events -2026-02-04T19:12:27.653481Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59480/133889 blocks (44.4%), 0 events -2026-02-04T19:12:27.812096Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59490/133889 blocks (44.4%), 0 events -2026-02-04T19:12:27.962767Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59500/133889 blocks (44.4%), 0 events -2026-02-04T19:12:28.227796Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59510/133889 blocks (44.4%), 0 events -2026-02-04T19:12:28.432450Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59520/133889 blocks (44.5%), 0 events -2026-02-04T19:12:28.634309Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59530/133889 blocks (44.5%), 0 events -2026-02-04T19:12:28.833062Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59540/133889 blocks (44.5%), 0 events -2026-02-04T19:12:28.995375Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59550/133889 blocks (44.5%), 0 events -2026-02-04T19:12:29.205279Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59560/133889 blocks (44.5%), 0 events -2026-02-04T19:12:29.379753Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59570/133889 blocks (44.5%), 0 events -2026-02-04T19:12:29.669231Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59580/133889 blocks (44.5%), 0 events -2026-02-04T19:12:29.774604Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59590/133889 blocks (44.5%), 0 events -2026-02-04T19:12:29.969749Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59600/133889 blocks (44.5%), 0 events -2026-02-04T19:12:30.199724Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59610/133889 blocks (44.5%), 0 events -2026-02-04T19:12:30.440214Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59620/133889 blocks (44.5%), 0 events -2026-02-04T19:12:30.713005Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59630/133889 blocks (44.5%), 0 events -2026-02-04T19:12:30.824033Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59640/133889 blocks (44.5%), 0 events -2026-02-04T19:12:31.036686Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59650/133889 blocks (44.6%), 0 events -2026-02-04T19:12:31.237900Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59660/133889 blocks (44.6%), 0 events -2026-02-04T19:12:31.437043Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59670/133889 blocks (44.6%), 0 events -2026-02-04T19:12:31.569518Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59680/133889 blocks (44.6%), 0 events -2026-02-04T19:12:31.759553Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59690/133889 blocks (44.6%), 0 events -2026-02-04T19:12:32.055759Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59700/133889 blocks (44.6%), 0 events -2026-02-04T19:12:32.288284Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59710/133889 blocks (44.6%), 0 events -2026-02-04T19:12:32.357935Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59720/133889 blocks (44.6%), 0 events -2026-02-04T19:12:32.661434Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59730/133889 blocks (44.6%), 0 events -2026-02-04T19:12:32.807800Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59740/133889 blocks (44.6%), 0 events -2026-02-04T19:12:33.027301Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59750/133889 blocks (44.6%), 0 events -2026-02-04T19:12:33.302687Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59760/133889 blocks (44.6%), 0 events -2026-02-04T19:12:33.415326Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59770/133889 blocks (44.6%), 0 events -2026-02-04T19:12:33.679906Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59780/133889 blocks (44.6%), 0 events -2026-02-04T19:12:33.860056Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59790/133889 blocks (44.7%), 0 events -2026-02-04T19:12:34.054087Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59800/133889 blocks (44.7%), 0 events -2026-02-04T19:12:34.247221Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59810/133889 blocks (44.7%), 0 events -2026-02-04T19:12:34.466295Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59820/133889 blocks (44.7%), 0 events -2026-02-04T19:12:34.566972Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59830/133889 blocks (44.7%), 0 events -2026-02-04T19:12:34.875811Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59840/133889 blocks (44.7%), 0 events -2026-02-04T19:12:34.990416Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59850/133889 blocks (44.7%), 0 events -2026-02-04T19:12:35.224228Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59860/133889 blocks (44.7%), 0 events -2026-02-04T19:12:35.431715Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59870/133889 blocks (44.7%), 0 events -2026-02-04T19:12:35.613705Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59880/133889 blocks (44.7%), 0 events -2026-02-04T19:12:35.924689Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59890/133889 blocks (44.7%), 0 events -2026-02-04T19:12:35.967537Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59900/133889 blocks (44.7%), 0 events -2026-02-04T19:12:36.263112Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59910/133889 blocks (44.7%), 0 events -2026-02-04T19:12:36.482753Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59920/133889 blocks (44.8%), 0 events -2026-02-04T19:12:36.588472Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59930/133889 blocks (44.8%), 0 events -2026-02-04T19:12:36.850572Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59940/133889 blocks (44.8%), 0 events -2026-02-04T19:12:37.051420Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59950/133889 blocks (44.8%), 0 events -2026-02-04T19:12:37.265341Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59960/133889 blocks (44.8%), 0 events -2026-02-04T19:12:37.497185Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59970/133889 blocks (44.8%), 0 events -2026-02-04T19:12:37.660275Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59980/133889 blocks (44.8%), 0 events -2026-02-04T19:12:37.796310Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 59990/133889 blocks (44.8%), 0 events -2026-02-04T19:12:38.055697Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60000/133889 blocks (44.8%), 0 events -2026-02-04T19:12:38.211374Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60010/133889 blocks (44.8%), 0 events -2026-02-04T19:12:38.454530Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60020/133889 blocks (44.8%), 0 events -2026-02-04T19:12:38.658209Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60030/133889 blocks (44.8%), 0 events -2026-02-04T19:12:38.775843Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60040/133889 blocks (44.8%), 0 events -2026-02-04T19:12:39.109445Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60050/133889 blocks (44.9%), 0 events -2026-02-04T19:12:39.178754Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60060/133889 blocks (44.9%), 0 events -2026-02-04T19:12:39.420544Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60070/133889 blocks (44.9%), 0 events -2026-02-04T19:12:39.630332Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60080/133889 blocks (44.9%), 0 events -2026-02-04T19:12:39.855813Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60090/133889 blocks (44.9%), 0 events -2026-02-04T19:12:40.006464Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60100/133889 blocks (44.9%), 0 events -2026-02-04T19:12:40.257345Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60110/133889 blocks (44.9%), 0 events -2026-02-04T19:12:40.360688Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60120/133889 blocks (44.9%), 0 events -2026-02-04T19:12:40.689406Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60130/133889 blocks (44.9%), 0 events -2026-02-04T19:12:40.848511Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60140/133889 blocks (44.9%), 0 events -2026-02-04T19:12:40.989686Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60150/133889 blocks (44.9%), 0 events -2026-02-04T19:12:41.253464Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60160/133889 blocks (44.9%), 0 events -2026-02-04T19:12:41.363830Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60170/133889 blocks (44.9%), 0 events -2026-02-04T19:12:41.726140Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60180/133889 blocks (44.9%), 0 events -2026-02-04T19:12:41.774694Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60190/133889 blocks (45.0%), 0 events -2026-02-04T19:12:42.022846Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60200/133889 blocks (45.0%), 0 events -2026-02-04T19:12:42.269061Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60210/133889 blocks (45.0%), 0 events -2026-02-04T19:12:42.449096Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60220/133889 blocks (45.0%), 0 events -2026-02-04T19:12:42.584306Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60230/133889 blocks (45.0%), 0 events -2026-02-04T19:12:42.771792Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60240/133889 blocks (45.0%), 0 events -2026-02-04T19:12:43.040397Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60250/133889 blocks (45.0%), 0 events -2026-02-04T19:12:43.264178Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60260/133889 blocks (45.0%), 0 events -2026-02-04T19:12:43.357929Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60270/133889 blocks (45.0%), 0 events -2026-02-04T19:12:43.597113Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60280/133889 blocks (45.0%), 0 events -2026-02-04T19:12:43.825931Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60290/133889 blocks (45.0%), 0 events -2026-02-04T19:12:43.963327Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60300/133889 blocks (45.0%), 0 events -2026-02-04T19:12:44.312870Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60310/133889 blocks (45.0%), 0 events -2026-02-04T19:12:44.359067Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60320/133889 blocks (45.1%), 0 events -2026-02-04T19:12:44.609273Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60330/133889 blocks (45.1%), 0 events -2026-02-04T19:12:44.867165Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60340/133889 blocks (45.1%), 0 events -2026-02-04T19:12:45.026249Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60350/133889 blocks (45.1%), 0 events -2026-02-04T19:12:45.196836Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60360/133889 blocks (45.1%), 0 events -2026-02-04T19:12:45.418493Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60370/133889 blocks (45.1%), 0 events -2026-02-04T19:12:45.655479Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60380/133889 blocks (45.1%), 0 events -2026-02-04T19:12:45.783326Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60390/133889 blocks (45.1%), 0 events -2026-02-04T19:12:46.052089Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60400/133889 blocks (45.1%), 0 events -2026-02-04T19:12:46.206035Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60410/133889 blocks (45.1%), 0 events -2026-02-04T19:12:46.444756Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60420/133889 blocks (45.1%), 0 events -2026-02-04T19:12:46.577583Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60430/133889 blocks (45.1%), 0 events -2026-02-04T19:12:46.817133Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60440/133889 blocks (45.1%), 0 events -2026-02-04T19:12:46.980696Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60450/133889 blocks (45.1%), 0 events -2026-02-04T19:12:47.225193Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60460/133889 blocks (45.2%), 0 events -2026-02-04T19:12:47.495321Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60470/133889 blocks (45.2%), 0 events -2026-02-04T19:12:47.658596Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60480/133889 blocks (45.2%), 0 events -2026-02-04T19:12:47.814794Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60490/133889 blocks (45.2%), 0 events -2026-02-04T19:12:48.016543Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60500/133889 blocks (45.2%), 0 events -2026-02-04T19:12:48.216801Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60510/133889 blocks (45.2%), 0 events -2026-02-04T19:12:48.506122Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60520/133889 blocks (45.2%), 0 events -2026-02-04T19:12:48.568629Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60530/133889 blocks (45.2%), 0 events -2026-02-04T19:12:48.864693Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60540/133889 blocks (45.2%), 0 events -2026-02-04T19:12:49.028631Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60550/133889 blocks (45.2%), 0 events -2026-02-04T19:12:49.222033Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60560/133889 blocks (45.2%), 0 events -2026-02-04T19:12:49.398526Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60570/133889 blocks (45.2%), 0 events -2026-02-04T19:12:49.597757Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60580/133889 blocks (45.2%), 0 events -2026-02-04T19:12:49.846908Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60590/133889 blocks (45.3%), 0 events -2026-02-04T19:12:50.077245Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60600/133889 blocks (45.3%), 0 events -2026-02-04T19:12:50.195434Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60610/133889 blocks (45.3%), 0 events -2026-02-04T19:12:50.441165Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60620/133889 blocks (45.3%), 0 events -2026-02-04T19:12:50.637016Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60630/133889 blocks (45.3%), 0 events -2026-02-04T19:12:50.836718Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60640/133889 blocks (45.3%), 0 events -2026-02-04T19:12:51.026431Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60650/133889 blocks (45.3%), 0 events -2026-02-04T19:12:51.239787Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60660/133889 blocks (45.3%), 0 events -2026-02-04T19:12:51.377369Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60670/133889 blocks (45.3%), 0 events -2026-02-04T19:12:51.688205Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60680/133889 blocks (45.3%), 0 events -2026-02-04T19:12:51.863040Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60690/133889 blocks (45.3%), 0 events -2026-02-04T19:12:52.054475Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60700/133889 blocks (45.3%), 0 events -2026-02-04T19:12:52.230143Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60710/133889 blocks (45.3%), 0 events -2026-02-04T19:12:52.413089Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60720/133889 blocks (45.4%), 0 events -2026-02-04T19:12:52.598726Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60730/133889 blocks (45.4%), 0 events -2026-02-04T19:12:52.815745Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60740/133889 blocks (45.4%), 0 events -2026-02-04T19:12:52.981554Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60750/133889 blocks (45.4%), 0 events -2026-02-04T19:12:53.261997Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60760/133889 blocks (45.4%), 0 events -2026-02-04T19:12:53.385640Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60770/133889 blocks (45.4%), 0 events -2026-02-04T19:12:53.632289Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60780/133889 blocks (45.4%), 0 events -2026-02-04T19:12:53.816744Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60790/133889 blocks (45.4%), 0 events -2026-02-04T19:12:54.022403Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60800/133889 blocks (45.4%), 0 events -2026-02-04T19:12:54.305964Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60810/133889 blocks (45.4%), 0 events -2026-02-04T19:12:54.461557Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60820/133889 blocks (45.4%), 0 events -2026-02-04T19:12:54.627927Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60830/133889 blocks (45.4%), 0 events -2026-02-04T19:12:54.832766Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60840/133889 blocks (45.4%), 0 events -2026-02-04T19:12:55.014511Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60850/133889 blocks (45.4%), 0 events -2026-02-04T19:12:55.196495Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60860/133889 blocks (45.5%), 0 events -2026-02-04T19:12:55.372981Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60870/133889 blocks (45.5%), 0 events -2026-02-04T19:12:55.664660Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60880/133889 blocks (45.5%), 0 events -2026-02-04T19:12:55.845717Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60890/133889 blocks (45.5%), 0 events -2026-02-04T19:12:56.061313Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60900/133889 blocks (45.5%), 0 events -2026-02-04T19:12:56.239615Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60910/133889 blocks (45.5%), 0 events -2026-02-04T19:12:56.404396Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60920/133889 blocks (45.5%), 0 events -2026-02-04T19:12:56.597759Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60930/133889 blocks (45.5%), 0 events -2026-02-04T19:12:56.895137Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60940/133889 blocks (45.5%), 0 events -2026-02-04T19:12:57.011165Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60950/133889 blocks (45.5%), 0 events -2026-02-04T19:12:57.195636Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60960/133889 blocks (45.5%), 0 events -2026-02-04T19:12:57.451847Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60970/133889 blocks (45.5%), 0 events -2026-02-04T19:12:57.651088Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60980/133889 blocks (45.5%), 0 events -2026-02-04T19:12:57.940352Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 60990/133889 blocks (45.6%), 0 events -2026-02-04T19:12:57.983426Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61000/133889 blocks (45.6%), 0 events -2026-02-04T19:12:58.200403Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61010/133889 blocks (45.6%), 0 events -2026-02-04T19:12:58.467327Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61020/133889 blocks (45.6%), 0 events -2026-02-04T19:12:58.630078Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61030/133889 blocks (45.6%), 0 events -2026-02-04T19:12:58.858740Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61040/133889 blocks (45.6%), 0 events -2026-02-04T19:12:59.026328Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61050/133889 blocks (45.6%), 0 events -2026-02-04T19:12:59.199342Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61060/133889 blocks (45.6%), 0 events -2026-02-04T19:12:59.421903Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61070/133889 blocks (45.6%), 0 events -2026-02-04T19:12:59.644410Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61080/133889 blocks (45.6%), 0 events -2026-02-04T19:12:59.846198Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61090/133889 blocks (45.6%), 0 events -2026-02-04T19:13:00.081351Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61100/133889 blocks (45.6%), 0 events -2026-02-04T19:13:00.231281Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61110/133889 blocks (45.6%), 0 events -2026-02-04T19:13:00.442778Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61120/133889 blocks (45.6%), 0 events -2026-02-04T19:13:00.642292Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61130/133889 blocks (45.7%), 0 events -2026-02-04T19:13:00.788871Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61140/133889 blocks (45.7%), 0 events -2026-02-04T19:13:01.089385Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61150/133889 blocks (45.7%), 0 events -2026-02-04T19:13:01.234562Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61160/133889 blocks (45.7%), 0 events -2026-02-04T19:13:01.417140Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61170/133889 blocks (45.7%), 0 events -2026-02-04T19:13:01.658784Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61180/133889 blocks (45.7%), 0 events -2026-02-04T19:13:01.828386Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61190/133889 blocks (45.7%), 0 events -2026-02-04T19:13:02.036611Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61200/133889 blocks (45.7%), 0 events -2026-02-04T19:13:02.173832Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61210/133889 blocks (45.7%), 0 events -2026-02-04T19:13:02.459421Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61220/133889 blocks (45.7%), 0 events -2026-02-04T19:13:02.697947Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61230/133889 blocks (45.7%), 0 events -2026-02-04T19:13:02.796143Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61240/133889 blocks (45.7%), 0 events -2026-02-04T19:13:03.028455Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61250/133889 blocks (45.7%), 0 events -2026-02-04T19:13:03.221001Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61260/133889 blocks (45.8%), 0 events -2026-02-04T19:13:03.399811Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61270/133889 blocks (45.8%), 0 events -2026-02-04T19:13:03.739730Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61280/133889 blocks (45.8%), 0 events -2026-02-04T19:13:03.782824Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61290/133889 blocks (45.8%), 0 events -2026-02-04T19:13:04.031043Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61300/133889 blocks (45.8%), 0 events -2026-02-04T19:13:04.265620Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61310/133889 blocks (45.8%), 0 events -2026-02-04T19:13:04.375789Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61320/133889 blocks (45.8%), 0 events -2026-02-04T19:13:04.643239Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61330/133889 blocks (45.8%), 0 events -2026-02-04T19:13:04.837822Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61340/133889 blocks (45.8%), 0 events -2026-02-04T19:13:05.047702Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61350/133889 blocks (45.8%), 0 events -2026-02-04T19:13:05.175033Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61360/133889 blocks (45.8%), 0 events -2026-02-04T19:13:05.451195Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61370/133889 blocks (45.8%), 0 events -2026-02-04T19:13:05.591004Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61380/133889 blocks (45.8%), 0 events -2026-02-04T19:13:05.871162Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61390/133889 blocks (45.9%), 0 events -2026-02-04T19:13:06.040486Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61400/133889 blocks (45.9%), 0 events -2026-02-04T19:13:06.197263Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61410/133889 blocks (45.9%), 0 events -2026-02-04T19:13:06.415201Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61420/133889 blocks (45.9%), 0 events -2026-02-04T19:13:06.628001Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61430/133889 blocks (45.9%), 0 events -2026-02-04T19:13:06.855895Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61440/133889 blocks (45.9%), 0 events -2026-02-04T19:13:06.989760Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61450/133889 blocks (45.9%), 0 events -2026-02-04T19:13:07.255661Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61460/133889 blocks (45.9%), 0 events -2026-02-04T19:13:07.416623Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61470/133889 blocks (45.9%), 0 events -2026-02-04T19:13:07.564855Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61480/133889 blocks (45.9%), 0 events -2026-02-04T19:13:07.903751Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61490/133889 blocks (45.9%), 0 events -2026-02-04T19:13:08.029142Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61500/133889 blocks (45.9%), 0 events -2026-02-04T19:13:08.187085Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61510/133889 blocks (45.9%), 0 events -2026-02-04T19:13:08.459261Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61520/133889 blocks (45.9%), 0 events -2026-02-04T19:13:08.656920Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61530/133889 blocks (46.0%), 0 events -2026-02-04T19:13:08.770205Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61540/133889 blocks (46.0%), 0 events -2026-02-04T19:13:09.023046Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61550/133889 blocks (46.0%), 0 events -2026-02-04T19:13:09.185866Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61560/133889 blocks (46.0%), 0 events -2026-02-04T19:13:09.508977Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61570/133889 blocks (46.0%), 0 events -2026-02-04T19:13:09.608092Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61580/133889 blocks (46.0%), 0 events -2026-02-04T19:13:09.848941Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61590/133889 blocks (46.0%), 0 events -2026-02-04T19:13:10.035731Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61600/133889 blocks (46.0%), 0 events -2026-02-04T19:13:10.179858Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61610/133889 blocks (46.0%), 0 events -2026-02-04T19:13:10.525243Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61620/133889 blocks (46.0%), 0 events -2026-02-04T19:13:10.560549Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61630/133889 blocks (46.0%), 0 events -2026-02-04T19:13:10.827502Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61640/133889 blocks (46.0%), 0 events -2026-02-04T19:13:11.084298Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61650/133889 blocks (46.0%), 0 events -2026-02-04T19:13:11.179697Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61660/133889 blocks (46.1%), 0 events -2026-02-04T19:13:11.409861Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61670/133889 blocks (46.1%), 0 events -2026-02-04T19:13:11.628124Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61680/133889 blocks (46.1%), 0 events -2026-02-04T19:13:11.804444Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61690/133889 blocks (46.1%), 0 events -2026-02-04T19:13:11.957377Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61700/133889 blocks (46.1%), 0 events -2026-02-04T19:13:12.230316Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61710/133889 blocks (46.1%), 0 events -2026-02-04T19:13:12.378567Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61720/133889 blocks (46.1%), 0 events -2026-02-04T19:13:12.751666Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61730/133889 blocks (46.1%), 0 events -2026-02-04T19:13:12.787692Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61740/133889 blocks (46.1%), 0 events -2026-02-04T19:13:12.949663Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61750/133889 blocks (46.1%), 0 events -2026-02-04T19:13:13.231129Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61760/133889 blocks (46.1%), 0 events -2026-02-04T19:13:13.443704Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61770/133889 blocks (46.1%), 0 events -2026-02-04T19:13:13.671646Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61780/133889 blocks (46.1%), 0 events -2026-02-04T19:13:13.812310Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61790/133889 blocks (46.1%), 0 events -2026-02-04T19:13:14.055252Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61800/133889 blocks (46.2%), 0 events -2026-02-04T19:13:14.232193Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61810/133889 blocks (46.2%), 0 events -2026-02-04T19:13:14.409014Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61820/133889 blocks (46.2%), 0 events -2026-02-04T19:13:14.592048Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61830/133889 blocks (46.2%), 0 events -2026-02-04T19:13:14.766114Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61840/133889 blocks (46.2%), 0 events -2026-02-04T19:13:15.030235Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61850/133889 blocks (46.2%), 0 events -2026-02-04T19:13:15.296345Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61860/133889 blocks (46.2%), 0 events -2026-02-04T19:13:15.365065Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61870/133889 blocks (46.2%), 0 events -2026-02-04T19:13:15.638299Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61880/133889 blocks (46.2%), 0 events -2026-02-04T19:13:15.800214Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61890/133889 blocks (46.2%), 0 events -2026-02-04T19:13:16.031804Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61900/133889 blocks (46.2%), 0 events -2026-02-04T19:13:16.291822Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61910/133889 blocks (46.2%), 0 events -2026-02-04T19:13:16.449631Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61920/133889 blocks (46.2%), 0 events -2026-02-04T19:13:16.602853Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61930/133889 blocks (46.3%), 0 events -2026-02-04T19:13:16.846033Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61940/133889 blocks (46.3%), 0 events -2026-02-04T19:13:17.049824Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61950/133889 blocks (46.3%), 0 events -2026-02-04T19:13:17.220185Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61960/133889 blocks (46.3%), 0 events -2026-02-04T19:13:17.417056Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61970/133889 blocks (46.3%), 0 events -2026-02-04T19:13:17.590528Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61980/133889 blocks (46.3%), 0 events -2026-02-04T19:13:17.864770Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 61990/133889 blocks (46.3%), 0 events -2026-02-04T19:13:18.011614Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62000/133889 blocks (46.3%), 0 events -2026-02-04T19:13:18.274165Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62010/133889 blocks (46.3%), 0 events -2026-02-04T19:13:18.425159Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62020/133889 blocks (46.3%), 0 events -2026-02-04T19:13:18.576715Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62030/133889 blocks (46.3%), 0 events -2026-02-04T19:13:18.914154Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62040/133889 blocks (46.3%), 0 events -2026-02-04T19:13:18.991710Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62050/133889 blocks (46.3%), 0 events -2026-02-04T19:13:19.214144Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62060/133889 blocks (46.4%), 0 events -2026-02-04T19:13:19.470410Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62070/133889 blocks (46.4%), 0 events -2026-02-04T19:13:19.614680Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62080/133889 blocks (46.4%), 0 events -2026-02-04T19:13:19.793974Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62090/133889 blocks (46.4%), 0 events -2026-02-04T19:13:20.046268Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62100/133889 blocks (46.4%), 0 events -2026-02-04T19:13:20.266687Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62110/133889 blocks (46.4%), 0 events -2026-02-04T19:13:20.521946Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62120/133889 blocks (46.4%), 0 events -2026-02-04T19:13:20.560139Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62130/133889 blocks (46.4%), 0 events -2026-02-04T19:13:20.803320Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62140/133889 blocks (46.4%), 0 events -2026-02-04T19:13:21.043800Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62150/133889 blocks (46.4%), 0 events -2026-02-04T19:13:21.253511Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62160/133889 blocks (46.4%), 0 events -2026-02-04T19:13:21.532598Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62170/133889 blocks (46.4%), 0 events -2026-02-04T19:13:21.568003Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62180/133889 blocks (46.4%), 0 events -2026-02-04T19:13:21.825596Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62190/133889 blocks (46.4%), 0 events -2026-02-04T19:13:22.089763Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62200/133889 blocks (46.5%), 0 events -2026-02-04T19:13:22.166356Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62210/133889 blocks (46.5%), 0 events -2026-02-04T19:13:22.455861Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62220/133889 blocks (46.5%), 0 events -2026-02-04T19:13:22.620407Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62230/133889 blocks (46.5%), 0 events -2026-02-04T19:13:22.775431Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62240/133889 blocks (46.5%), 0 events -2026-02-04T19:13:22.979914Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62250/133889 blocks (46.5%), 0 events -2026-02-04T19:13:23.244733Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62260/133889 blocks (46.5%), 0 events -2026-02-04T19:13:23.376739Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62270/133889 blocks (46.5%), 0 events -2026-02-04T19:13:23.666487Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62280/133889 blocks (46.5%), 0 events -2026-02-04T19:13:23.844215Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62290/133889 blocks (46.5%), 0 events -2026-02-04T19:13:24.044554Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62300/133889 blocks (46.5%), 0 events -2026-02-04T19:13:24.207058Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62310/133889 blocks (46.5%), 0 events -2026-02-04T19:13:24.424517Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62320/133889 blocks (46.5%), 0 events -2026-02-04T19:13:24.680486Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62330/133889 blocks (46.6%), 0 events -2026-02-04T19:13:24.833132Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62340/133889 blocks (46.6%), 0 events -2026-02-04T19:13:25.024688Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62350/133889 blocks (46.6%), 0 events -2026-02-04T19:13:25.239662Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62360/133889 blocks (46.6%), 0 events -2026-02-04T19:13:25.427943Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62370/133889 blocks (46.6%), 0 events -2026-02-04T19:13:25.608342Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62380/133889 blocks (46.6%), 0 events -2026-02-04T19:13:25.793771Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62390/133889 blocks (46.6%), 0 events -2026-02-04T19:13:26.002379Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62400/133889 blocks (46.6%), 0 events -2026-02-04T19:13:26.251418Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62410/133889 blocks (46.6%), 0 events -2026-02-04T19:13:26.401140Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62420/133889 blocks (46.6%), 0 events -2026-02-04T19:13:26.585030Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62430/133889 blocks (46.6%), 0 events -2026-02-04T19:13:26.839225Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62440/133889 blocks (46.6%), 0 events -2026-02-04T19:13:27.016888Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62450/133889 blocks (46.6%), 0 events -2026-02-04T19:13:27.185074Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62460/133889 blocks (46.7%), 0 events -2026-02-04T19:13:27.442338Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62470/133889 blocks (46.7%), 0 events -2026-02-04T19:13:27.605833Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62480/133889 blocks (46.7%), 0 events -2026-02-04T19:13:27.856356Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62490/133889 blocks (46.7%), 0 events -2026-02-04T19:13:27.971384Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62500/133889 blocks (46.7%), 0 events -2026-02-04T19:13:28.200765Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62510/133889 blocks (46.7%), 0 events -2026-02-04T19:13:28.444977Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62520/133889 blocks (46.7%), 0 events -2026-02-04T19:13:28.658972Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62530/133889 blocks (46.7%), 0 events -2026-02-04T19:13:28.908291Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62540/133889 blocks (46.7%), 0 events -2026-02-04T19:13:28.979303Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62550/133889 blocks (46.7%), 0 events -2026-02-04T19:13:29.237079Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62560/133889 blocks (46.7%), 0 events -2026-02-04T19:13:29.430949Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62570/133889 blocks (46.7%), 0 events -2026-02-04T19:13:29.800263Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62580/133889 blocks (46.7%), 0 events -2026-02-04T19:13:29.921984Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62590/133889 blocks (46.7%), 0 events -2026-02-04T19:13:29.965873Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62600/133889 blocks (46.8%), 0 events -2026-02-04T19:13:30.227103Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62610/133889 blocks (46.8%), 0 events -2026-02-04T19:13:30.481641Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62620/133889 blocks (46.8%), 0 events -2026-02-04T19:13:30.648607Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62630/133889 blocks (46.8%), 0 events -2026-02-04T19:13:30.777777Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62640/133889 blocks (46.8%), 0 events -2026-02-04T19:13:31.007862Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62650/133889 blocks (46.8%), 0 events -2026-02-04T19:13:31.246257Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62660/133889 blocks (46.8%), 0 events -2026-02-04T19:13:31.537248Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62670/133889 blocks (46.8%), 0 events -2026-02-04T19:13:31.582538Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62680/133889 blocks (46.8%), 0 events -2026-02-04T19:13:31.771018Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62690/133889 blocks (46.8%), 0 events -2026-02-04T19:13:32.056092Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62700/133889 blocks (46.8%), 0 events -2026-02-04T19:13:32.201948Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62710/133889 blocks (46.8%), 0 events -2026-02-04T19:13:32.542648Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62720/133889 blocks (46.8%), 0 events -2026-02-04T19:13:32.578767Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62730/133889 blocks (46.9%), 0 events -2026-02-04T19:13:32.777355Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62740/133889 blocks (46.9%), 0 events -2026-02-04T19:13:33.102851Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62750/133889 blocks (46.9%), 0 events -2026-02-04T19:13:33.219629Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62760/133889 blocks (46.9%), 0 events -2026-02-04T19:13:33.398477Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62770/133889 blocks (46.9%), 0 events -2026-02-04T19:13:33.624521Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62780/133889 blocks (46.9%), 0 events -2026-02-04T19:13:33.762127Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62790/133889 blocks (46.9%), 0 events -2026-02-04T19:13:34.000217Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62800/133889 blocks (46.9%), 0 events -2026-02-04T19:13:34.229841Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62810/133889 blocks (46.9%), 0 events -2026-02-04T19:13:34.451525Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62820/133889 blocks (46.9%), 0 events -2026-02-04T19:13:34.671753Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62830/133889 blocks (46.9%), 0 events -2026-02-04T19:13:34.832783Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62840/133889 blocks (46.9%), 0 events -2026-02-04T19:13:35.001572Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62850/133889 blocks (46.9%), 0 events -2026-02-04T19:13:35.232824Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62860/133889 blocks (46.9%), 0 events -2026-02-04T19:13:35.449892Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62870/133889 blocks (47.0%), 0 events -2026-02-04T19:13:35.584659Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62880/133889 blocks (47.0%), 0 events -2026-02-04T19:13:35.843320Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62890/133889 blocks (47.0%), 0 events -2026-02-04T19:13:36.056713Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62900/133889 blocks (47.0%), 0 events -2026-02-04T19:13:36.246189Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62910/133889 blocks (47.0%), 0 events -2026-02-04T19:13:36.387933Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62920/133889 blocks (47.0%), 0 events -2026-02-04T19:13:36.584554Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62930/133889 blocks (47.0%), 0 events -2026-02-04T19:13:36.780059Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62940/133889 blocks (47.0%), 0 events -2026-02-04T19:13:36.993020Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62950/133889 blocks (47.0%), 0 events -2026-02-04T19:13:37.296951Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62960/133889 blocks (47.0%), 0 events -2026-02-04T19:13:37.453533Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62970/133889 blocks (47.0%), 0 events -2026-02-04T19:13:37.617683Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62980/133889 blocks (47.0%), 0 events -2026-02-04T19:13:37.822124Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 62990/133889 blocks (47.0%), 0 events -2026-02-04T19:13:37.970653Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63000/133889 blocks (47.1%), 0 events -2026-02-04T19:13:38.190873Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63010/133889 blocks (47.1%), 0 events -2026-02-04T19:13:38.432131Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63020/133889 blocks (47.1%), 0 events -2026-02-04T19:13:38.642757Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63030/133889 blocks (47.1%), 0 events -2026-02-04T19:13:38.870615Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63040/133889 blocks (47.1%), 0 events -2026-02-04T19:13:39.000866Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63050/133889 blocks (47.1%), 0 events -2026-02-04T19:13:39.360551Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63060/133889 blocks (47.1%), 0 events -2026-02-04T19:13:39.401440Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63070/133889 blocks (47.1%), 0 events -2026-02-04T19:13:39.617893Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63080/133889 blocks (47.1%), 0 events -2026-02-04T19:13:39.780293Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63090/133889 blocks (47.1%), 0 events -2026-02-04T19:13:39.994918Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63100/133889 blocks (47.1%), 0 events -2026-02-04T19:13:40.226779Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63110/133889 blocks (47.1%), 0 events -2026-02-04T19:13:40.441305Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63120/133889 blocks (47.1%), 0 events -2026-02-04T19:13:40.640233Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63130/133889 blocks (47.2%), 0 events -2026-02-04T19:13:41.125062Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63140/133889 blocks (47.2%), 0 events -2026-02-04T19:13:41.164239Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63150/133889 blocks (47.2%), 0 events -2026-02-04T19:13:41.206644Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63160/133889 blocks (47.2%), 0 events -2026-02-04T19:13:41.492319Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63170/133889 blocks (47.2%), 0 events -2026-02-04T19:13:41.637241Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63180/133889 blocks (47.2%), 0 events -2026-02-04T19:13:41.781514Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63190/133889 blocks (47.2%), 0 events -2026-02-04T19:13:42.062298Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63200/133889 blocks (47.2%), 0 events -2026-02-04T19:13:42.174927Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63210/133889 blocks (47.2%), 0 events -2026-02-04T19:13:42.504456Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63220/133889 blocks (47.2%), 0 events -2026-02-04T19:13:42.567466Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63230/133889 blocks (47.2%), 0 events -2026-02-04T19:13:42.842113Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63240/133889 blocks (47.2%), 0 events -2026-02-04T19:13:43.026933Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63250/133889 blocks (47.2%), 0 events -2026-02-04T19:13:43.216455Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63260/133889 blocks (47.2%), 0 events -2026-02-04T19:13:43.440305Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63270/133889 blocks (47.3%), 0 events -2026-02-04T19:13:43.619145Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63280/133889 blocks (47.3%), 0 events -2026-02-04T19:13:43.820305Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63290/133889 blocks (47.3%), 0 events -2026-02-04T19:13:44.076387Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63300/133889 blocks (47.3%), 0 events -2026-02-04T19:13:44.223967Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63310/133889 blocks (47.3%), 0 events -2026-02-04T19:13:44.424417Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63320/133889 blocks (47.3%), 0 events -2026-02-04T19:13:44.634283Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63330/133889 blocks (47.3%), 0 events -2026-02-04T19:13:44.839330Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63340/133889 blocks (47.3%), 0 events -2026-02-04T19:13:45.025525Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63350/133889 blocks (47.3%), 0 events -2026-02-04T19:13:45.245819Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63360/133889 blocks (47.3%), 0 events -2026-02-04T19:13:45.454502Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63370/133889 blocks (47.3%), 0 events -2026-02-04T19:13:45.685815Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63380/133889 blocks (47.3%), 0 events -2026-02-04T19:13:45.797311Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63390/133889 blocks (47.3%), 0 events -2026-02-04T19:13:45.989137Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63400/133889 blocks (47.4%), 0 events -2026-02-04T19:13:46.240814Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63410/133889 blocks (47.4%), 0 events -2026-02-04T19:13:46.457225Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63420/133889 blocks (47.4%), 0 events -2026-02-04T19:13:46.580751Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63430/133889 blocks (47.4%), 0 events -2026-02-04T19:13:46.795595Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63440/133889 blocks (47.4%), 0 events -2026-02-04T19:13:47.010433Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63450/133889 blocks (47.4%), 0 events -2026-02-04T19:13:47.260263Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63460/133889 blocks (47.4%), 0 events -2026-02-04T19:13:47.452593Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63470/133889 blocks (47.4%), 0 events -2026-02-04T19:13:47.652417Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63480/133889 blocks (47.4%), 0 events -2026-02-04T19:13:47.836465Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63490/133889 blocks (47.4%), 0 events -2026-02-04T19:13:48.042341Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63500/133889 blocks (47.4%), 0 events -2026-02-04T19:13:48.270119Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63510/133889 blocks (47.4%), 0 events -2026-02-04T19:13:48.434033Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63520/133889 blocks (47.4%), 0 events -2026-02-04T19:13:48.579425Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63530/133889 blocks (47.4%), 0 events -2026-02-04T19:13:48.826592Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63540/133889 blocks (47.5%), 0 events -2026-02-04T19:13:48.984395Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63550/133889 blocks (47.5%), 0 events -2026-02-04T19:13:49.179270Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63560/133889 blocks (47.5%), 0 events -2026-02-04T19:13:49.442507Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63570/133889 blocks (47.5%), 0 events -2026-02-04T19:13:49.623335Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63580/133889 blocks (47.5%), 0 events -2026-02-04T19:13:49.872951Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63590/133889 blocks (47.5%), 0 events -2026-02-04T19:13:50.008925Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63600/133889 blocks (47.5%), 0 events -2026-02-04T19:13:50.216104Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63610/133889 blocks (47.5%), 0 events -2026-02-04T19:13:50.404571Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63620/133889 blocks (47.5%), 0 events -2026-02-04T19:13:50.577064Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63630/133889 blocks (47.5%), 0 events -2026-02-04T19:13:50.893685Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63640/133889 blocks (47.5%), 0 events -2026-02-04T19:13:50.963502Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63650/133889 blocks (47.5%), 0 events -2026-02-04T19:13:51.203612Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63660/133889 blocks (47.5%), 0 events -2026-02-04T19:13:51.450335Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63670/133889 blocks (47.6%), 0 events -2026-02-04T19:13:51.646506Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63680/133889 blocks (47.6%), 0 events -2026-02-04T19:13:51.941583Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63690/133889 blocks (47.6%), 0 events -2026-02-04T19:13:51.979935Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63700/133889 blocks (47.6%), 0 events -2026-02-04T19:13:52.176369Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63710/133889 blocks (47.6%), 0 events -2026-02-04T19:13:52.496318Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63720/133889 blocks (47.6%), 0 events -2026-02-04T19:13:52.692582Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63730/133889 blocks (47.6%), 0 events -2026-02-04T19:13:52.818603Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63740/133889 blocks (47.6%), 0 events -2026-02-04T19:13:53.022008Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63750/133889 blocks (47.6%), 0 events -2026-02-04T19:13:53.249138Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63760/133889 blocks (47.6%), 0 events -2026-02-04T19:13:53.544954Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63770/133889 blocks (47.6%), 0 events -2026-02-04T19:13:53.582955Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63780/133889 blocks (47.6%), 0 events -2026-02-04T19:13:53.811434Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63790/133889 blocks (47.6%), 0 events -2026-02-04T19:13:54.078070Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63800/133889 blocks (47.7%), 0 events -2026-02-04T19:13:54.269689Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63810/133889 blocks (47.7%), 0 events -2026-02-04T19:13:54.384652Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63820/133889 blocks (47.7%), 0 events -2026-02-04T19:13:54.592191Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63830/133889 blocks (47.7%), 0 events -2026-02-04T19:13:54.820199Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63840/133889 blocks (47.7%), 0 events -2026-02-04T19:13:54.975216Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63850/133889 blocks (47.7%), 0 events -2026-02-04T19:13:55.285016Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63860/133889 blocks (47.7%), 0 events -2026-02-04T19:13:55.396911Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63870/133889 blocks (47.7%), 0 events -2026-02-04T19:13:55.643395Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63880/133889 blocks (47.7%), 0 events -2026-02-04T19:13:55.842601Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63890/133889 blocks (47.7%), 0 events -2026-02-04T19:13:56.134746Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63900/133889 blocks (47.7%), 0 events -2026-02-04T19:13:56.175718Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63910/133889 blocks (47.7%), 0 events -2026-02-04T19:13:56.456221Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63920/133889 blocks (47.7%), 0 events -2026-02-04T19:13:56.572260Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63930/133889 blocks (47.7%), 0 events -2026-02-04T19:13:56.887371Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63940/133889 blocks (47.8%), 0 events -2026-02-04T19:13:57.181894Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63950/133889 blocks (47.8%), 0 events -2026-02-04T19:13:57.224295Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63960/133889 blocks (47.8%), 0 events -2026-02-04T19:13:57.416518Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63970/133889 blocks (47.8%), 0 events -2026-02-04T19:13:57.620503Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63980/133889 blocks (47.8%), 0 events -2026-02-04T19:13:57.790098Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 63990/133889 blocks (47.8%), 0 events -2026-02-04T19:13:58.011957Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64000/133889 blocks (47.8%), 0 events -2026-02-04T19:13:58.265401Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64010/133889 blocks (47.8%), 0 events -2026-02-04T19:13:58.430023Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64020/133889 blocks (47.8%), 0 events -2026-02-04T19:13:58.757014Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64030/133889 blocks (47.8%), 0 events -2026-02-04T19:13:58.800964Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64040/133889 blocks (47.8%), 0 events -2026-02-04T19:13:58.986812Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64050/133889 blocks (47.8%), 0 events -2026-02-04T19:13:59.180628Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64060/133889 blocks (47.8%), 0 events -2026-02-04T19:13:59.478637Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64070/133889 blocks (47.9%), 0 events -2026-02-04T19:13:59.579918Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64080/133889 blocks (47.9%), 0 events -2026-02-04T19:13:59.842223Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64090/133889 blocks (47.9%), 0 events -2026-02-04T19:14:00.058933Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64100/133889 blocks (47.9%), 0 events -2026-02-04T19:14:00.187663Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64110/133889 blocks (47.9%), 0 events -2026-02-04T19:14:00.391528Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64120/133889 blocks (47.9%), 0 events -2026-02-04T19:14:00.666123Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64130/133889 blocks (47.9%), 0 events -2026-02-04T19:14:00.887686Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64140/133889 blocks (47.9%), 0 events -2026-02-04T19:14:01.019030Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64150/133889 blocks (47.9%), 0 events -2026-02-04T19:14:01.218976Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64160/133889 blocks (47.9%), 0 events -2026-02-04T19:14:01.444601Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64170/133889 blocks (47.9%), 0 events -2026-02-04T19:14:01.575135Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64180/133889 blocks (47.9%), 0 events -2026-02-04T19:14:01.903814Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64190/133889 blocks (47.9%), 0 events -2026-02-04T19:14:02.060400Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64200/133889 blocks (47.9%), 0 events -2026-02-04T19:14:02.219357Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64210/133889 blocks (48.0%), 0 events -2026-02-04T19:14:02.459303Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64220/133889 blocks (48.0%), 0 events -2026-02-04T19:14:02.636293Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64230/133889 blocks (48.0%), 0 events -2026-02-04T19:14:02.778818Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64240/133889 blocks (48.0%), 0 events -2026-02-04T19:14:02.985475Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64250/133889 blocks (48.0%), 0 events -2026-02-04T19:14:03.260858Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64260/133889 blocks (48.0%), 0 events -2026-02-04T19:14:03.475362Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64270/133889 blocks (48.0%), 0 events -2026-02-04T19:14:03.673312Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64280/133889 blocks (48.0%), 0 events -2026-02-04T19:14:03.776192Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64290/133889 blocks (48.0%), 0 events -2026-02-04T19:14:04.031466Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64300/133889 blocks (48.0%), 0 events -2026-02-04T19:14:04.173519Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64310/133889 blocks (48.0%), 0 events -2026-02-04T19:14:04.397732Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64320/133889 blocks (48.0%), 0 events -2026-02-04T19:14:04.624337Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64330/133889 blocks (48.0%), 0 events -2026-02-04T19:14:04.841707Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64340/133889 blocks (48.1%), 0 events -2026-02-04T19:14:05.084338Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64350/133889 blocks (48.1%), 0 events -2026-02-04T19:14:05.184276Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64360/133889 blocks (48.1%), 0 events -2026-02-04T19:14:05.431382Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64370/133889 blocks (48.1%), 0 events -2026-02-04T19:14:05.613388Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64380/133889 blocks (48.1%), 0 events -2026-02-04T19:14:05.809134Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64390/133889 blocks (48.1%), 0 events -2026-02-04T19:14:05.965987Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64400/133889 blocks (48.1%), 0 events -2026-02-04T19:14:06.197803Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64410/133889 blocks (48.1%), 0 events -2026-02-04T19:14:06.458480Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64420/133889 blocks (48.1%), 0 events -2026-02-04T19:14:06.650461Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64430/133889 blocks (48.1%), 0 events -2026-02-04T19:14:06.859817Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64440/133889 blocks (48.1%), 0 events -2026-02-04T19:14:07.146317Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64450/133889 blocks (48.1%), 0 events -2026-02-04T19:14:07.185741Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64460/133889 blocks (48.1%), 0 events -2026-02-04T19:14:07.423816Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64470/133889 blocks (48.2%), 0 events -2026-02-04T19:14:07.668985Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64480/133889 blocks (48.2%), 0 events -2026-02-04T19:14:07.877524Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64490/133889 blocks (48.2%), 0 events -2026-02-04T19:14:08.047382Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64500/133889 blocks (48.2%), 0 events -2026-02-04T19:14:08.224126Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64510/133889 blocks (48.2%), 0 events -2026-02-04T19:14:08.394480Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64520/133889 blocks (48.2%), 0 events -2026-02-04T19:14:08.718335Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64530/133889 blocks (48.2%), 0 events -2026-02-04T19:14:08.755216Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64540/133889 blocks (48.2%), 0 events -2026-02-04T19:14:09.061842Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64550/133889 blocks (48.2%), 0 events -2026-02-04T19:14:09.242876Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64560/133889 blocks (48.2%), 0 events -2026-02-04T19:14:09.395067Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64570/133889 blocks (48.2%), 0 events -2026-02-04T19:14:09.608697Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64580/133889 blocks (48.2%), 0 events -2026-02-04T19:14:09.836265Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64590/133889 blocks (48.2%), 0 events -2026-02-04T19:14:10.043822Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64600/133889 blocks (48.2%), 0 events -2026-02-04T19:14:10.328592Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64610/133889 blocks (48.3%), 0 events -2026-02-04T19:14:10.365623Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64620/133889 blocks (48.3%), 0 events -2026-02-04T19:14:10.587156Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64630/133889 blocks (48.3%), 0 events -2026-02-04T19:14:10.862533Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64640/133889 blocks (48.3%), 0 events -2026-02-04T19:14:11.028178Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64650/133889 blocks (48.3%), 0 events -2026-02-04T19:14:11.339129Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64660/133889 blocks (48.3%), 0 events -2026-02-04T19:14:11.402759Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64670/133889 blocks (48.3%), 0 events -2026-02-04T19:14:11.627840Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64680/133889 blocks (48.3%), 0 events -2026-02-04T19:14:11.895971Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64690/133889 blocks (48.3%), 0 events -2026-02-04T19:14:12.037807Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64700/133889 blocks (48.3%), 0 events -2026-02-04T19:14:12.207216Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64710/133889 blocks (48.3%), 0 events -2026-02-04T19:14:12.423204Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64720/133889 blocks (48.3%), 0 events -2026-02-04T19:14:12.564976Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64730/133889 blocks (48.3%), 0 events -2026-02-04T19:14:12.791296Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64740/133889 blocks (48.4%), 0 events -2026-02-04T19:14:12.976828Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64750/133889 blocks (48.4%), 0 events -2026-02-04T19:14:13.198365Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64760/133889 blocks (48.4%), 0 events -2026-02-04T19:14:13.470284Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64770/133889 blocks (48.4%), 0 events -2026-02-04T19:14:13.634896Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64780/133889 blocks (48.4%), 0 events -2026-02-04T19:14:13.791022Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64790/133889 blocks (48.4%), 0 events -2026-02-04T19:14:13.995781Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64800/133889 blocks (48.4%), 0 events -2026-02-04T19:14:14.248621Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64810/133889 blocks (48.4%), 0 events -2026-02-04T19:14:14.763549Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64820/133889 blocks (48.4%), 0 events -2026-02-04T19:14:14.806235Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64830/133889 blocks (48.4%), 0 events -2026-02-04T19:14:14.846299Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64840/133889 blocks (48.4%), 0 events -2026-02-04T19:14:15.040251Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64850/133889 blocks (48.4%), 0 events -2026-02-04T19:14:15.166840Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64860/133889 blocks (48.4%), 0 events -2026-02-04T19:14:15.532094Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64870/133889 blocks (48.5%), 0 events -2026-02-04T19:14:15.569929Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64880/133889 blocks (48.5%), 0 events -2026-02-04T19:14:15.811779Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64890/133889 blocks (48.5%), 0 events -2026-02-04T19:14:16.058124Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64900/133889 blocks (48.5%), 0 events -2026-02-04T19:14:16.225729Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64910/133889 blocks (48.5%), 0 events -2026-02-04T19:14:16.421966Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64920/133889 blocks (48.5%), 0 events -2026-02-04T19:14:16.652746Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64930/133889 blocks (48.5%), 0 events -2026-02-04T19:14:16.835863Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64940/133889 blocks (48.5%), 0 events -2026-02-04T19:14:17.107462Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64950/133889 blocks (48.5%), 0 events -2026-02-04T19:14:17.231398Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64960/133889 blocks (48.5%), 0 events -2026-02-04T19:14:17.450431Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64970/133889 blocks (48.5%), 0 events -2026-02-04T19:14:17.676421Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64980/133889 blocks (48.5%), 0 events -2026-02-04T19:14:17.882406Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 64990/133889 blocks (48.5%), 0 events -2026-02-04T19:14:17.986202Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65000/133889 blocks (48.5%), 0 events -2026-02-04T19:14:18.205305Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65010/133889 blocks (48.6%), 0 events -2026-02-04T19:14:18.426890Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65020/133889 blocks (48.6%), 0 events -2026-02-04T19:14:18.583341Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65030/133889 blocks (48.6%), 0 events -2026-02-04T19:14:18.847698Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65040/133889 blocks (48.6%), 0 events -2026-02-04T19:14:19.009631Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65050/133889 blocks (48.6%), 0 events -2026-02-04T19:14:19.245785Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65060/133889 blocks (48.6%), 0 events -2026-02-04T19:14:19.418675Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65070/133889 blocks (48.6%), 0 events -2026-02-04T19:14:19.595089Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65080/133889 blocks (48.6%), 0 events -2026-02-04T19:14:19.846143Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65090/133889 blocks (48.6%), 0 events -2026-02-04T19:14:20.055995Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65100/133889 blocks (48.6%), 0 events -2026-02-04T19:14:20.253888Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65110/133889 blocks (48.6%), 0 events -2026-02-04T19:14:20.442177Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65120/133889 blocks (48.6%), 0 events -2026-02-04T19:14:20.652792Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65130/133889 blocks (48.6%), 0 events -2026-02-04T19:14:20.854754Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65140/133889 blocks (48.7%), 0 events -2026-02-04T19:14:21.003900Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65150/133889 blocks (48.7%), 0 events -2026-02-04T19:14:21.330626Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65160/133889 blocks (48.7%), 0 events -2026-02-04T19:14:21.373599Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65170/133889 blocks (48.7%), 0 events -2026-02-04T19:14:21.635226Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65180/133889 blocks (48.7%), 0 events -2026-02-04T19:14:21.863016Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65190/133889 blocks (48.7%), 0 events -2026-02-04T19:14:22.061259Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65200/133889 blocks (48.7%), 0 events -2026-02-04T19:14:22.255489Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65210/133889 blocks (48.7%), 0 events -2026-02-04T19:14:22.422786Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65220/133889 blocks (48.7%), 0 events -2026-02-04T19:14:22.645344Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65230/133889 blocks (48.7%), 0 events -2026-02-04T19:14:22.909192Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65240/133889 blocks (48.7%), 0 events -2026-02-04T19:14:22.961869Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65250/133889 blocks (48.7%), 0 events -2026-02-04T19:14:23.173138Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65260/133889 blocks (48.7%), 0 events -2026-02-04T19:14:23.448431Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65270/133889 blocks (48.7%), 0 events -2026-02-04T19:14:23.602426Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65280/133889 blocks (48.8%), 0 events -2026-02-04T19:14:23.765606Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65290/133889 blocks (48.8%), 0 events -2026-02-04T19:14:24.024408Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65300/133889 blocks (48.8%), 0 events -2026-02-04T19:14:24.245863Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65310/133889 blocks (48.8%), 0 events -2026-02-04T19:14:24.445855Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65320/133889 blocks (48.8%), 0 events -2026-02-04T19:14:24.591733Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65330/133889 blocks (48.8%), 0 events -2026-02-04T19:14:24.856078Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65340/133889 blocks (48.8%), 0 events -2026-02-04T19:14:25.040339Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65350/133889 blocks (48.8%), 0 events -2026-02-04T19:14:25.169134Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65360/133889 blocks (48.8%), 0 events -2026-02-04T19:14:25.535120Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65370/133889 blocks (48.8%), 0 events -2026-02-04T19:14:25.581403Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65380/133889 blocks (48.8%), 0 events -2026-02-04T19:14:25.798519Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65390/133889 blocks (48.8%), 0 events -2026-02-04T19:14:26.283819Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65400/133889 blocks (48.8%), 0 events -2026-02-04T19:14:26.324524Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65410/133889 blocks (48.9%), 0 events -2026-02-04T19:14:26.364761Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65420/133889 blocks (48.9%), 0 events -2026-02-04T19:14:26.648562Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65430/133889 blocks (48.9%), 0 events -2026-02-04T19:14:26.844475Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65440/133889 blocks (48.9%), 0 events -2026-02-04T19:14:27.067612Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65450/133889 blocks (48.9%), 0 events -2026-02-04T19:14:27.246693Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65460/133889 blocks (48.9%), 0 events -2026-02-04T19:14:27.384516Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65470/133889 blocks (48.9%), 0 events -2026-02-04T19:14:27.641955Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65480/133889 blocks (48.9%), 0 events -2026-02-04T19:14:27.839175Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65490/133889 blocks (48.9%), 0 events -2026-02-04T19:14:28.004915Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65500/133889 blocks (48.9%), 0 events -2026-02-04T19:14:28.245787Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65510/133889 blocks (48.9%), 0 events -2026-02-04T19:14:28.385936Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65520/133889 blocks (48.9%), 0 events -2026-02-04T19:14:28.640699Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65530/133889 blocks (48.9%), 0 events -2026-02-04T19:14:28.857058Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65540/133889 blocks (49.0%), 0 events -2026-02-04T19:14:29.039394Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65550/133889 blocks (49.0%), 0 events -2026-02-04T19:14:29.195327Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65560/133889 blocks (49.0%), 0 events -2026-02-04T19:14:29.416411Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65570/133889 blocks (49.0%), 0 events -2026-02-04T19:14:29.586956Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65580/133889 blocks (49.0%), 0 events -2026-02-04T19:14:29.805354Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65590/133889 blocks (49.0%), 0 events -2026-02-04T19:14:30.010618Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65600/133889 blocks (49.0%), 0 events -2026-02-04T19:14:30.244925Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65610/133889 blocks (49.0%), 0 events -2026-02-04T19:14:30.443138Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65620/133889 blocks (49.0%), 0 events -2026-02-04T19:14:30.634166Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65630/133889 blocks (49.0%), 0 events -2026-02-04T19:14:30.772573Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65640/133889 blocks (49.0%), 0 events -2026-02-04T19:14:31.012079Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65650/133889 blocks (49.0%), 0 events -2026-02-04T19:14:31.297054Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65660/133889 blocks (49.0%), 0 events -2026-02-04T19:14:31.381237Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65670/133889 blocks (49.0%), 0 events -2026-02-04T19:14:31.677399Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65680/133889 blocks (49.1%), 0 events -2026-02-04T19:14:31.825029Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65690/133889 blocks (49.1%), 0 events -2026-02-04T19:14:31.977791Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65700/133889 blocks (49.1%), 0 events -2026-02-04T19:14:32.198477Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65710/133889 blocks (49.1%), 0 events -2026-02-04T19:14:32.376960Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65720/133889 blocks (49.1%), 0 events -2026-02-04T19:14:32.649817Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65730/133889 blocks (49.1%), 0 events -2026-02-04T19:14:32.867373Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65740/133889 blocks (49.1%), 0 events -2026-02-04T19:14:33.058471Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65750/133889 blocks (49.1%), 0 events -2026-02-04T19:14:33.242141Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65760/133889 blocks (49.1%), 0 events -2026-02-04T19:14:33.405148Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65770/133889 blocks (49.1%), 0 events -2026-02-04T19:14:33.651186Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65780/133889 blocks (49.1%), 0 events -2026-02-04T19:14:33.921370Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65790/133889 blocks (49.1%), 0 events -2026-02-04T19:14:33.985272Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65800/133889 blocks (49.1%), 0 events -2026-02-04T19:14:34.200302Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65810/133889 blocks (49.2%), 0 events -2026-02-04T19:14:34.461714Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65820/133889 blocks (49.2%), 0 events -2026-02-04T19:14:34.594020Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65830/133889 blocks (49.2%), 0 events -2026-02-04T19:14:34.777962Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65840/133889 blocks (49.2%), 0 events -2026-02-04T19:14:35.036756Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65850/133889 blocks (49.2%), 0 events -2026-02-04T19:14:35.182515Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65860/133889 blocks (49.2%), 0 events -2026-02-04T19:14:35.456217Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65870/133889 blocks (49.2%), 0 events -2026-02-04T19:14:35.565773Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65880/133889 blocks (49.2%), 0 events -2026-02-04T19:14:35.782829Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65890/133889 blocks (49.2%), 0 events -2026-02-04T19:14:36.047832Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65900/133889 blocks (49.2%), 0 events -2026-02-04T19:14:36.208121Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65910/133889 blocks (49.2%), 0 events -2026-02-04T19:14:36.539789Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65920/133889 blocks (49.2%), 0 events -2026-02-04T19:14:36.580793Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65930/133889 blocks (49.2%), 0 events -2026-02-04T19:14:36.853314Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65940/133889 blocks (49.2%), 0 events -2026-02-04T19:14:37.060440Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65950/133889 blocks (49.3%), 0 events -2026-02-04T19:14:37.205544Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65960/133889 blocks (49.3%), 0 events -2026-02-04T19:14:37.408555Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65970/133889 blocks (49.3%), 0 events -2026-02-04T19:14:37.594981Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65980/133889 blocks (49.3%), 0 events -2026-02-04T19:14:37.846171Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 65990/133889 blocks (49.3%), 0 events -2026-02-04T19:14:38.074879Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66000/133889 blocks (49.3%), 0 events -2026-02-04T19:14:38.165554Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66010/133889 blocks (49.3%), 0 events -2026-02-04T19:14:38.382551Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66020/133889 blocks (49.3%), 0 events -2026-02-04T19:14:38.637212Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66030/133889 blocks (49.3%), 0 events -2026-02-04T19:14:38.768709Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66040/133889 blocks (49.3%), 0 events -2026-02-04T19:14:39.002128Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66050/133889 blocks (49.3%), 0 events -2026-02-04T19:14:39.194016Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66060/133889 blocks (49.3%), 0 events -2026-02-04T19:14:39.490246Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66070/133889 blocks (49.3%), 0 events -2026-02-04T19:14:39.687426Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66080/133889 blocks (49.4%), 0 events -2026-02-04T19:14:39.825827Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66090/133889 blocks (49.4%), 0 events -2026-02-04T19:14:40.002155Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66100/133889 blocks (49.4%), 0 events -2026-02-04T19:14:40.276796Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66110/133889 blocks (49.4%), 0 events -2026-02-04T19:14:40.396839Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66120/133889 blocks (49.4%), 0 events -2026-02-04T19:14:40.584209Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66130/133889 blocks (49.4%), 0 events -2026-02-04T19:14:40.773631Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66140/133889 blocks (49.4%), 0 events -2026-02-04T19:14:41.030359Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66150/133889 blocks (49.4%), 0 events -2026-02-04T19:14:41.307769Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66160/133889 blocks (49.4%), 0 events -2026-02-04T19:14:41.378024Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66170/133889 blocks (49.4%), 0 events -2026-02-04T19:14:41.623263Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66180/133889 blocks (49.4%), 0 events -2026-02-04T19:14:41.802696Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66190/133889 blocks (49.4%), 0 events -2026-02-04T19:14:42.033431Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66200/133889 blocks (49.4%), 0 events -2026-02-04T19:14:42.302948Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66210/133889 blocks (49.5%), 0 events -2026-02-04T19:14:42.412396Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66220/133889 blocks (49.5%), 0 events -2026-02-04T19:14:42.614811Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66230/133889 blocks (49.5%), 0 events -2026-02-04T19:14:42.831295Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66240/133889 blocks (49.5%), 0 events -2026-02-04T19:14:43.052617Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66250/133889 blocks (49.5%), 0 events -2026-02-04T19:14:43.320831Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66260/133889 blocks (49.5%), 0 events -2026-02-04T19:14:43.363021Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66270/133889 blocks (49.5%), 0 events -2026-02-04T19:14:43.639066Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66280/133889 blocks (49.5%), 0 events -2026-02-04T19:14:43.887941Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66290/133889 blocks (49.5%), 0 events -2026-02-04T19:14:44.040102Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66300/133889 blocks (49.5%), 0 events -2026-02-04T19:14:44.254047Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66310/133889 blocks (49.5%), 0 events -2026-02-04T19:14:44.416806Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66320/133889 blocks (49.5%), 0 events -2026-02-04T19:14:44.593649Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66330/133889 blocks (49.5%), 0 events -2026-02-04T19:14:44.895222Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66340/133889 blocks (49.5%), 0 events -2026-02-04T19:14:44.984326Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66350/133889 blocks (49.6%), 0 events -2026-02-04T19:14:45.205799Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66360/133889 blocks (49.6%), 0 events -2026-02-04T19:14:45.447551Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66370/133889 blocks (49.6%), 0 events -2026-02-04T19:14:45.649877Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66380/133889 blocks (49.6%), 0 events -2026-02-04T19:14:45.851092Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66390/133889 blocks (49.6%), 0 events -2026-02-04T19:14:45.981955Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66400/133889 blocks (49.6%), 0 events -2026-02-04T19:14:46.207492Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66410/133889 blocks (49.6%), 0 events -2026-02-04T19:14:46.467704Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66420/133889 blocks (49.6%), 0 events -2026-02-04T19:14:46.662417Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66430/133889 blocks (49.6%), 0 events -2026-02-04T19:14:46.848813Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66440/133889 blocks (49.6%), 0 events -2026-02-04T19:14:47.018271Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66450/133889 blocks (49.6%), 0 events -2026-02-04T19:14:47.237615Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66460/133889 blocks (49.6%), 0 events -2026-02-04T19:14:47.397418Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66470/133889 blocks (49.6%), 0 events -2026-02-04T19:14:47.708800Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66480/133889 blocks (49.7%), 0 events -2026-02-04T19:14:47.817092Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66490/133889 blocks (49.7%), 0 events -2026-02-04T19:14:48.069893Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66500/133889 blocks (49.7%), 0 events -2026-02-04T19:14:48.233232Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66510/133889 blocks (49.7%), 0 events -2026-02-04T19:14:48.410860Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66520/133889 blocks (49.7%), 0 events -2026-02-04T19:14:48.645879Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66530/133889 blocks (49.7%), 0 events -2026-02-04T19:14:48.851686Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66540/133889 blocks (49.7%), 0 events -2026-02-04T19:14:49.087170Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66550/133889 blocks (49.7%), 0 events -2026-02-04T19:14:49.200737Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66560/133889 blocks (49.7%), 0 events -2026-02-04T19:14:49.435274Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66570/133889 blocks (49.7%), 0 events -2026-02-04T19:14:49.643845Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66580/133889 blocks (49.7%), 0 events -2026-02-04T19:14:49.837556Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66590/133889 blocks (49.7%), 0 events -2026-02-04T19:14:50.030346Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66600/133889 blocks (49.7%), 0 events -2026-02-04T19:14:50.329847Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66610/133889 blocks (49.7%), 0 events -2026-02-04T19:14:50.367081Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66620/133889 blocks (49.8%), 0 events -2026-02-04T19:14:50.658330Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66630/133889 blocks (49.8%), 0 events -2026-02-04T19:14:50.887456Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66640/133889 blocks (49.8%), 0 events -2026-02-04T19:14:51.002934Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66650/133889 blocks (49.8%), 0 events -2026-02-04T19:14:51.214196Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66660/133889 blocks (49.8%), 0 events -2026-02-04T19:14:51.415842Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66670/133889 blocks (49.8%), 0 events -2026-02-04T19:14:51.593731Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66680/133889 blocks (49.8%), 0 events -2026-02-04T19:14:51.827525Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66690/133889 blocks (49.8%), 0 events -2026-02-04T19:14:51.969875Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66700/133889 blocks (49.8%), 0 events -2026-02-04T19:14:52.263106Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66710/133889 blocks (49.8%), 0 events -2026-02-04T19:14:52.426536Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66720/133889 blocks (49.8%), 0 events -2026-02-04T19:14:52.627761Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66730/133889 blocks (49.8%), 0 events -2026-02-04T19:14:52.839513Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66740/133889 blocks (49.8%), 0 events -2026-02-04T19:14:53.281805Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66750/133889 blocks (49.9%), 0 events -2026-02-04T19:14:53.320256Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66760/133889 blocks (49.9%), 0 events -2026-02-04T19:14:53.360451Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66770/133889 blocks (49.9%), 0 events -2026-02-04T19:14:53.657475Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66780/133889 blocks (49.9%), 0 events -2026-02-04T19:14:53.839616Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66790/133889 blocks (49.9%), 0 events -2026-02-04T19:14:54.037319Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66800/133889 blocks (49.9%), 0 events -2026-02-04T19:14:54.217761Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66810/133889 blocks (49.9%), 0 events -2026-02-04T19:14:54.420140Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66820/133889 blocks (49.9%), 0 events -2026-02-04T19:14:54.581253Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66830/133889 blocks (49.9%), 0 events -2026-02-04T19:14:54.854130Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66840/133889 blocks (49.9%), 0 events -2026-02-04T19:14:55.049671Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66850/133889 blocks (49.9%), 0 events -2026-02-04T19:14:55.227020Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66860/133889 blocks (49.9%), 0 events -2026-02-04T19:14:55.443186Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66870/133889 blocks (49.9%), 0 events -2026-02-04T19:14:55.632225Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66880/133889 blocks (50.0%), 0 events -2026-02-04T19:14:55.931832Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66890/133889 blocks (50.0%), 0 events -2026-02-04T19:14:55.970183Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66900/133889 blocks (50.0%), 0 events -2026-02-04T19:14:56.190345Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66910/133889 blocks (50.0%), 0 events -2026-02-04T19:14:56.456380Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66920/133889 blocks (50.0%), 0 events -2026-02-04T19:14:56.653895Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66930/133889 blocks (50.0%), 0 events -2026-02-04T19:14:56.788783Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66940/133889 blocks (50.0%), 0 events -2026-02-04T19:14:57.042803Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66950/133889 blocks (50.0%), 0 events -2026-02-04T19:14:57.243669Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66960/133889 blocks (50.0%), 0 events -2026-02-04T19:14:57.506730Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66970/133889 blocks (50.0%), 0 events -2026-02-04T19:14:57.623442Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66980/133889 blocks (50.0%), 0 events -2026-02-04T19:14:57.857364Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 66990/133889 blocks (50.0%), 0 events -2026-02-04T19:14:58.031833Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67000/133889 blocks (50.0%), 0 events -2026-02-04T19:14:58.192554Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67010/133889 blocks (50.0%), 0 events -2026-02-04T19:14:58.383470Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67020/133889 blocks (50.1%), 0 events -2026-02-04T19:14:58.638149Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67030/133889 blocks (50.1%), 0 events -2026-02-04T19:14:58.786159Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67040/133889 blocks (50.1%), 0 events -2026-02-04T19:14:59.081392Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67050/133889 blocks (50.1%), 0 events -2026-02-04T19:14:59.198438Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67060/133889 blocks (50.1%), 0 events -2026-02-04T19:14:59.453147Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67070/133889 blocks (50.1%), 0 events -2026-02-04T19:14:59.611519Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67080/133889 blocks (50.1%), 0 events -2026-02-04T19:14:59.825210Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67090/133889 blocks (50.1%), 0 events -2026-02-04T19:15:00.095242Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67100/133889 blocks (50.1%), 0 events -2026-02-04T19:15:00.217517Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67110/133889 blocks (50.1%), 0 events -2026-02-04T19:15:00.400750Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67120/133889 blocks (50.1%), 0 events -2026-02-04T19:15:00.662880Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67130/133889 blocks (50.1%), 0 events -2026-02-04T19:15:00.848398Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67140/133889 blocks (50.1%), 0 events -2026-02-04T19:15:01.144304Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67150/133889 blocks (50.2%), 0 events -2026-02-04T19:15:01.193595Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67160/133889 blocks (50.2%), 0 events -2026-02-04T19:15:01.454774Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67170/133889 blocks (50.2%), 0 events -2026-02-04T19:15:01.574560Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67180/133889 blocks (50.2%), 0 events -2026-02-04T19:15:01.822438Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67190/133889 blocks (50.2%), 0 events -2026-02-04T19:15:02.030363Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67200/133889 blocks (50.2%), 0 events -2026-02-04T19:15:02.262565Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67210/133889 blocks (50.2%), 0 events -2026-02-04T19:15:02.422294Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67220/133889 blocks (50.2%), 0 events -2026-02-04T19:15:02.565920Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67230/133889 blocks (50.2%), 0 events -2026-02-04T19:15:02.912516Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67240/133889 blocks (50.2%), 0 events -2026-02-04T19:15:02.995158Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67250/133889 blocks (50.2%), 0 events -2026-02-04T19:15:03.239415Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67260/133889 blocks (50.2%), 0 events -2026-02-04T19:15:03.481965Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67270/133889 blocks (50.2%), 0 events -2026-02-04T19:15:03.628701Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67280/133889 blocks (50.3%), 0 events -2026-02-04T19:15:03.799088Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67290/133889 blocks (50.3%), 0 events -2026-02-04T19:15:04.044996Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67300/133889 blocks (50.3%), 0 events -2026-02-04T19:15:04.172756Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67310/133889 blocks (50.3%), 0 events -2026-02-04T19:15:04.376520Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67320/133889 blocks (50.3%), 0 events -2026-02-04T19:15:04.603374Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67330/133889 blocks (50.3%), 0 events -2026-02-04T19:15:04.846923Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67340/133889 blocks (50.3%), 0 events -2026-02-04T19:15:04.989136Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67350/133889 blocks (50.3%), 0 events -2026-02-04T19:15:05.224684Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67360/133889 blocks (50.3%), 0 events -2026-02-04T19:15:05.430104Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67370/133889 blocks (50.3%), 0 events -2026-02-04T19:15:05.615021Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67380/133889 blocks (50.3%), 0 events -2026-02-04T19:15:05.897395Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67390/133889 blocks (50.3%), 0 events -2026-02-04T19:15:06.018362Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67400/133889 blocks (50.3%), 0 events -2026-02-04T19:15:06.254240Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67410/133889 blocks (50.3%), 0 events -2026-02-04T19:15:06.423657Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67420/133889 blocks (50.4%), 0 events -2026-02-04T19:15:06.636426Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67430/133889 blocks (50.4%), 0 events -2026-02-04T19:15:06.945581Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67440/133889 blocks (50.4%), 0 events -2026-02-04T19:15:06.984915Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67450/133889 blocks (50.4%), 0 events -2026-02-04T19:15:07.258306Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67460/133889 blocks (50.4%), 0 events -2026-02-04T19:15:07.465694Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67470/133889 blocks (50.4%), 0 events -2026-02-04T19:15:07.667714Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67480/133889 blocks (50.4%), 0 events -2026-02-04T19:15:07.822550Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67490/133889 blocks (50.4%), 0 events -2026-02-04T19:15:07.996833Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67500/133889 blocks (50.4%), 0 events -2026-02-04T19:15:08.244188Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67510/133889 blocks (50.4%), 0 events -2026-02-04T19:15:08.516811Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67520/133889 blocks (50.4%), 0 events -2026-02-04T19:15:08.558107Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67530/133889 blocks (50.4%), 0 events -2026-02-04T19:15:08.858642Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67540/133889 blocks (50.4%), 0 events -2026-02-04T19:15:09.063665Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67550/133889 blocks (50.5%), 0 events -2026-02-04T19:15:09.235038Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67560/133889 blocks (50.5%), 0 events -2026-02-04T19:15:09.417798Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67570/133889 blocks (50.5%), 0 events -2026-02-04T19:15:09.649029Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67580/133889 blocks (50.5%), 0 events -2026-02-04T19:15:09.765426Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67590/133889 blocks (50.5%), 0 events -2026-02-04T19:15:10.094001Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67600/133889 blocks (50.5%), 0 events -2026-02-04T19:15:10.216282Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67610/133889 blocks (50.5%), 0 events -2026-02-04T19:15:10.437903Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67620/133889 blocks (50.5%), 0 events -2026-02-04T19:15:10.614255Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67630/133889 blocks (50.5%), 0 events -2026-02-04T19:15:10.826991Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67640/133889 blocks (50.5%), 0 events -2026-02-04T19:15:10.981234Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67650/133889 blocks (50.5%), 0 events -2026-02-04T19:15:11.212047Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67660/133889 blocks (50.5%), 0 events -2026-02-04T19:15:11.381963Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67670/133889 blocks (50.5%), 0 events -2026-02-04T19:15:11.672614Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67680/133889 blocks (50.5%), 0 events -2026-02-04T19:15:11.842961Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67690/133889 blocks (50.6%), 0 events -2026-02-04T19:15:11.983439Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67700/133889 blocks (50.6%), 0 events -2026-02-04T19:15:12.241285Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67710/133889 blocks (50.6%), 0 events -2026-02-04T19:15:12.440786Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67720/133889 blocks (50.6%), 0 events -2026-02-04T19:15:12.677865Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67730/133889 blocks (50.6%), 0 events -2026-02-04T19:15:12.799873Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67740/133889 blocks (50.6%), 0 events -2026-02-04T19:15:12.994497Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67750/133889 blocks (50.6%), 0 events -2026-02-04T19:15:13.237163Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67760/133889 blocks (50.6%), 0 events -2026-02-04T19:15:13.380864Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67770/133889 blocks (50.6%), 0 events -2026-02-04T19:15:13.727230Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67780/133889 blocks (50.6%), 0 events -2026-02-04T19:15:13.770267Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67790/133889 blocks (50.6%), 0 events -2026-02-04T19:15:13.968111Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67800/133889 blocks (50.6%), 0 events -2026-02-04T19:15:14.284053Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67810/133889 blocks (50.6%), 0 events -2026-02-04T19:15:14.415012Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67820/133889 blocks (50.7%), 0 events -2026-02-04T19:15:14.629816Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67830/133889 blocks (50.7%), 0 events -2026-02-04T19:15:14.842336Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67840/133889 blocks (50.7%), 0 events -2026-02-04T19:15:14.986010Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67850/133889 blocks (50.7%), 0 events -2026-02-04T19:15:15.300544Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67860/133889 blocks (50.7%), 0 events -2026-02-04T19:15:15.433566Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67870/133889 blocks (50.7%), 0 events -2026-02-04T19:15:15.635854Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67880/133889 blocks (50.7%), 0 events -2026-02-04T19:15:15.859131Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67890/133889 blocks (50.7%), 0 events -2026-02-04T19:15:15.979922Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67900/133889 blocks (50.7%), 0 events -2026-02-04T19:15:16.215422Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67910/133889 blocks (50.7%), 0 events -2026-02-04T19:15:16.384197Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67920/133889 blocks (50.7%), 0 events -2026-02-04T19:15:16.582145Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67930/133889 blocks (50.7%), 0 events -2026-02-04T19:15:16.904544Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67940/133889 blocks (50.7%), 0 events -2026-02-04T19:15:16.971033Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67950/133889 blocks (50.8%), 0 events -2026-02-04T19:15:17.263469Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67960/133889 blocks (50.8%), 0 events -2026-02-04T19:15:17.465542Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67970/133889 blocks (50.8%), 0 events -2026-02-04T19:15:17.655331Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67980/133889 blocks (50.8%), 0 events -2026-02-04T19:15:17.820963Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 67990/133889 blocks (50.8%), 0 events -2026-02-04T19:15:18.067311Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68000/133889 blocks (50.8%), 0 events -2026-02-04T19:15:18.279393Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68010/133889 blocks (50.8%), 0 events -2026-02-04T19:15:18.473253Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68020/133889 blocks (50.8%), 0 events -2026-02-04T19:15:18.656774Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68030/133889 blocks (50.8%), 0 events -2026-02-04T19:15:18.809108Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68040/133889 blocks (50.8%), 0 events -2026-02-04T19:15:19.018879Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68050/133889 blocks (50.8%), 0 events -2026-02-04T19:15:19.225996Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68060/133889 blocks (50.8%), 0 events -2026-02-04T19:15:19.530660Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68070/133889 blocks (50.8%), 0 events -2026-02-04T19:15:19.565690Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68080/133889 blocks (50.8%), 0 events -2026-02-04T19:15:19.848067Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68090/133889 blocks (50.9%), 0 events -2026-02-04T19:15:20.050328Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68100/133889 blocks (50.9%), 0 events -2026-02-04T19:15:20.226089Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68110/133889 blocks (50.9%), 0 events -2026-02-04T19:15:20.391945Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68120/133889 blocks (50.9%), 0 events -2026-02-04T19:15:20.613439Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68130/133889 blocks (50.9%), 0 events -2026-02-04T19:15:20.769055Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68140/133889 blocks (50.9%), 0 events -2026-02-04T19:15:21.064822Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68150/133889 blocks (50.9%), 0 events -2026-02-04T19:15:21.228041Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68160/133889 blocks (50.9%), 0 events -2026-02-04T19:15:21.401683Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68170/133889 blocks (50.9%), 0 events -2026-02-04T19:15:21.626167Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68180/133889 blocks (50.9%), 0 events -2026-02-04T19:15:21.835608Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68190/133889 blocks (50.9%), 0 events -2026-02-04T19:15:22.112827Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68200/133889 blocks (50.9%), 0 events -2026-02-04T19:15:22.192860Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68210/133889 blocks (50.9%), 0 events -2026-02-04T19:15:22.433331Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68220/133889 blocks (51.0%), 0 events -2026-02-04T19:15:22.674827Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68230/133889 blocks (51.0%), 0 events -2026-02-04T19:15:22.770399Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68240/133889 blocks (51.0%), 0 events -2026-02-04T19:15:23.054608Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68250/133889 blocks (51.0%), 0 events -2026-02-04T19:15:23.196974Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68260/133889 blocks (51.0%), 0 events -2026-02-04T19:15:23.432749Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68270/133889 blocks (51.0%), 0 events -2026-02-04T19:15:23.574768Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68280/133889 blocks (51.0%), 0 events -2026-02-04T19:15:23.806743Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68290/133889 blocks (51.0%), 0 events -2026-02-04T19:15:24.003244Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68300/133889 blocks (51.0%), 0 events -2026-02-04T19:15:24.260643Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68310/133889 blocks (51.0%), 0 events -2026-02-04T19:15:24.452031Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68320/133889 blocks (51.0%), 0 events -2026-02-04T19:15:24.558485Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68330/133889 blocks (51.0%), 0 events -2026-02-04T19:15:24.778676Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68340/133889 blocks (51.0%), 0 events -2026-02-04T19:15:24.997481Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68350/133889 blocks (51.0%), 0 events -2026-02-04T19:15:25.295606Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68360/133889 blocks (51.1%), 0 events -2026-02-04T19:15:25.500521Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68370/133889 blocks (51.1%), 0 events -2026-02-04T19:15:25.644698Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68380/133889 blocks (51.1%), 0 events -2026-02-04T19:15:25.820910Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68390/133889 blocks (51.1%), 0 events -2026-02-04T19:15:26.021164Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68400/133889 blocks (51.1%), 0 events -2026-02-04T19:15:26.208770Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68410/133889 blocks (51.1%), 0 events -2026-02-04T19:15:26.504037Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68420/133889 blocks (51.1%), 0 events -2026-02-04T19:15:26.653793Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68430/133889 blocks (51.1%), 0 events -2026-02-04T19:15:26.869403Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68440/133889 blocks (51.1%), 0 events -2026-02-04T19:15:27.075861Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68450/133889 blocks (51.1%), 0 events -2026-02-04T19:15:27.224813Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68460/133889 blocks (51.1%), 0 events -2026-02-04T19:15:27.409431Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68470/133889 blocks (51.1%), 0 events -2026-02-04T19:15:27.652286Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68480/133889 blocks (51.1%), 0 events -2026-02-04T19:15:27.918093Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68490/133889 blocks (51.2%), 0 events -2026-02-04T19:15:27.960192Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68500/133889 blocks (51.2%), 0 events -2026-02-04T19:15:28.170469Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68510/133889 blocks (51.2%), 0 events -2026-02-04T19:15:28.443252Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68520/133889 blocks (51.2%), 0 events -2026-02-04T19:15:28.662807Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68530/133889 blocks (51.2%), 0 events -2026-02-04T19:15:28.770170Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68540/133889 blocks (51.2%), 0 events -2026-02-04T19:15:29.038881Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68550/133889 blocks (51.2%), 0 events -2026-02-04T19:15:29.162681Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68560/133889 blocks (51.2%), 0 events -2026-02-04T19:15:29.494253Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68570/133889 blocks (51.2%), 0 events -2026-02-04T19:15:29.601210Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68580/133889 blocks (51.2%), 0 events -2026-02-04T19:15:29.811660Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68590/133889 blocks (51.2%), 0 events -2026-02-04T19:15:30.036406Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68600/133889 blocks (51.2%), 0 events -2026-02-04T19:15:30.248965Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68610/133889 blocks (51.2%), 0 events -2026-02-04T19:15:30.537824Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68620/133889 blocks (51.3%), 0 events -2026-02-04T19:15:30.581786Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68630/133889 blocks (51.3%), 0 events -2026-02-04T19:15:30.870225Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68640/133889 blocks (51.3%), 0 events -2026-02-04T19:15:31.065637Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68650/133889 blocks (51.3%), 0 events -2026-02-04T19:15:31.232844Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68660/133889 blocks (51.3%), 0 events -2026-02-04T19:15:31.425406Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68670/133889 blocks (51.3%), 0 events -2026-02-04T19:15:31.588814Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68680/133889 blocks (51.3%), 0 events -2026-02-04T19:15:31.845212Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68690/133889 blocks (51.3%), 0 events -2026-02-04T19:15:32.122177Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68700/133889 blocks (51.3%), 0 events -2026-02-04T19:15:32.164807Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68710/133889 blocks (51.3%), 0 events -2026-02-04T19:15:32.393920Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68720/133889 blocks (51.3%), 0 events -2026-02-04T19:15:32.634539Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68730/133889 blocks (51.3%), 0 events -2026-02-04T19:15:32.767060Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68740/133889 blocks (51.3%), 0 events -2026-02-04T19:15:33.010086Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68750/133889 blocks (51.3%), 0 events -2026-02-04T19:15:33.215382Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68760/133889 blocks (51.4%), 0 events -2026-02-04T19:15:33.683467Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68770/133889 blocks (51.4%), 0 events -2026-02-04T19:15:33.728074Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68780/133889 blocks (51.4%), 0 events -2026-02-04T19:15:33.774225Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68790/133889 blocks (51.4%), 0 events -2026-02-04T19:15:33.975453Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68800/133889 blocks (51.4%), 0 events -2026-02-04T19:15:34.211191Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68810/133889 blocks (51.4%), 0 events -2026-02-04T19:15:34.432539Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68820/133889 blocks (51.4%), 0 events -2026-02-04T19:15:34.588339Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68830/133889 blocks (51.4%), 0 events -2026-02-04T19:15:34.795212Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68840/133889 blocks (51.4%), 0 events -2026-02-04T19:15:35.037768Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68850/133889 blocks (51.4%), 0 events -2026-02-04T19:15:35.264300Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68860/133889 blocks (51.4%), 0 events -2026-02-04T19:15:35.458598Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68870/133889 blocks (51.4%), 0 events -2026-02-04T19:15:35.599685Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68880/133889 blocks (51.4%), 0 events -2026-02-04T19:15:35.798911Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68890/133889 blocks (51.5%), 0 events -2026-02-04T19:15:36.052557Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68900/133889 blocks (51.5%), 0 events -2026-02-04T19:15:36.302103Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68910/133889 blocks (51.5%), 0 events -2026-02-04T19:15:36.422067Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68920/133889 blocks (51.5%), 0 events -2026-02-04T19:15:36.613960Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68930/133889 blocks (51.5%), 0 events -2026-02-04T19:15:36.849438Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68940/133889 blocks (51.5%), 0 events -2026-02-04T19:15:37.009388Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68950/133889 blocks (51.5%), 0 events -2026-02-04T19:15:37.318914Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68960/133889 blocks (51.5%), 0 events -2026-02-04T19:15:37.362424Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68970/133889 blocks (51.5%), 0 events -2026-02-04T19:15:37.593709Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68980/133889 blocks (51.5%), 0 events -2026-02-04T19:15:37.881105Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 68990/133889 blocks (51.5%), 0 events -2026-02-04T19:15:38.041265Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69000/133889 blocks (51.5%), 0 events -2026-02-04T19:15:38.185562Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69010/133889 blocks (51.5%), 0 events -2026-02-04T19:15:38.398089Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69020/133889 blocks (51.5%), 0 events -2026-02-04T19:15:38.644466Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69030/133889 blocks (51.6%), 0 events -2026-02-04T19:15:38.925038Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69040/133889 blocks (51.6%), 0 events -2026-02-04T19:15:38.967470Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69050/133889 blocks (51.6%), 0 events -2026-02-04T19:15:39.232145Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69060/133889 blocks (51.6%), 0 events -2026-02-04T19:15:39.448624Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69070/133889 blocks (51.6%), 0 events -2026-02-04T19:15:39.641354Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69080/133889 blocks (51.6%), 0 events -2026-02-04T19:15:39.941629Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69090/133889 blocks (51.6%), 0 events -2026-02-04T19:15:39.980767Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69100/133889 blocks (51.6%), 0 events -2026-02-04T19:15:40.249164Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69110/133889 blocks (51.6%), 0 events -2026-02-04T19:15:40.465617Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69120/133889 blocks (51.6%), 0 events -2026-02-04T19:15:40.635853Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69130/133889 blocks (51.6%), 0 events -2026-02-04T19:15:40.778353Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69140/133889 blocks (51.6%), 0 events -2026-02-04T19:15:41.031131Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69150/133889 blocks (51.6%), 0 events -2026-02-04T19:15:41.232443Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69160/133889 blocks (51.7%), 0 events -2026-02-04T19:15:41.376833Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69170/133889 blocks (51.7%), 0 events -2026-02-04T19:15:41.641908Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69180/133889 blocks (51.7%), 0 events -2026-02-04T19:15:41.780924Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69190/133889 blocks (51.7%), 0 events -2026-02-04T19:15:42.082534Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69200/133889 blocks (51.7%), 0 events -2026-02-04T19:15:42.232856Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69210/133889 blocks (51.7%), 0 events -2026-02-04T19:15:42.452060Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69220/133889 blocks (51.7%), 0 events -2026-02-04T19:15:42.598131Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69230/133889 blocks (51.7%), 0 events -2026-02-04T19:15:42.786847Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69240/133889 blocks (51.7%), 0 events -2026-02-04T19:15:43.124426Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69250/133889 blocks (51.7%), 0 events -2026-02-04T19:15:43.164203Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69260/133889 blocks (51.7%), 0 events -2026-02-04T19:15:43.409649Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69270/133889 blocks (51.7%), 0 events -2026-02-04T19:15:43.641950Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69280/133889 blocks (51.7%), 0 events -2026-02-04T19:15:43.790356Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69290/133889 blocks (51.8%), 0 events -2026-02-04T19:15:44.032245Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69300/133889 blocks (51.8%), 0 events -2026-02-04T19:15:44.249510Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69310/133889 blocks (51.8%), 0 events -2026-02-04T19:15:44.456278Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69320/133889 blocks (51.8%), 0 events -2026-02-04T19:15:44.691035Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69330/133889 blocks (51.8%), 0 events -2026-02-04T19:15:44.801357Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69340/133889 blocks (51.8%), 0 events -2026-02-04T19:15:44.994030Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69350/133889 blocks (51.8%), 0 events -2026-02-04T19:15:45.232464Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69360/133889 blocks (51.8%), 0 events -2026-02-04T19:15:45.387949Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69370/133889 blocks (51.8%), 0 events -2026-02-04T19:15:45.742485Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69380/133889 blocks (51.8%), 0 events -2026-02-04T19:15:45.783233Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69390/133889 blocks (51.8%), 0 events -2026-02-04T19:15:46.002064Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69400/133889 blocks (51.8%), 0 events -2026-02-04T19:15:46.264392Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69410/133889 blocks (51.8%), 0 events -2026-02-04T19:15:46.434809Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69420/133889 blocks (51.8%), 0 events -2026-02-04T19:15:46.642120Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69430/133889 blocks (51.9%), 0 events -2026-02-04T19:15:46.808868Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69440/133889 blocks (51.9%), 0 events -2026-02-04T19:15:46.966755Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69450/133889 blocks (51.9%), 0 events -2026-02-04T19:15:47.320689Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69460/133889 blocks (51.9%), 0 events -2026-02-04T19:15:47.362643Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69470/133889 blocks (51.9%), 0 events -2026-02-04T19:15:47.576222Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69480/133889 blocks (51.9%), 0 events -2026-02-04T19:15:47.850334Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69490/133889 blocks (51.9%), 0 events -2026-02-04T19:15:48.039346Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69500/133889 blocks (51.9%), 0 events -2026-02-04T19:15:48.328345Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69510/133889 blocks (51.9%), 0 events -2026-02-04T19:15:48.371514Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69520/133889 blocks (51.9%), 0 events -2026-02-04T19:15:48.564462Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69530/133889 blocks (51.9%), 0 events -2026-02-04T19:15:48.883482Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69540/133889 blocks (51.9%), 0 events -2026-02-04T19:15:49.087151Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69550/133889 blocks (51.9%), 0 events -2026-02-04T19:15:49.220419Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69560/133889 blocks (52.0%), 0 events -2026-02-04T19:15:49.427931Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69570/133889 blocks (52.0%), 0 events -2026-02-04T19:15:49.611922Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69580/133889 blocks (52.0%), 0 events -2026-02-04T19:15:49.796322Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69590/133889 blocks (52.0%), 0 events -2026-02-04T19:15:50.096172Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69600/133889 blocks (52.0%), 0 events -2026-02-04T19:15:50.242644Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69610/133889 blocks (52.0%), 0 events -2026-02-04T19:15:50.463784Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69620/133889 blocks (52.0%), 0 events -2026-02-04T19:15:50.652492Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69630/133889 blocks (52.0%), 0 events -2026-02-04T19:15:50.791571Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69640/133889 blocks (52.0%), 0 events -2026-02-04T19:15:51.034577Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69650/133889 blocks (52.0%), 0 events -2026-02-04T19:15:51.182666Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69660/133889 blocks (52.0%), 0 events -2026-02-04T19:15:51.518907Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69670/133889 blocks (52.0%), 0 events -2026-02-04T19:15:51.559329Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69680/133889 blocks (52.0%), 0 events -2026-02-04T19:15:51.828084Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69690/133889 blocks (52.1%), 0 events -2026-02-04T19:15:52.036148Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69700/133889 blocks (52.1%), 0 events -2026-02-04T19:15:52.168790Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69710/133889 blocks (52.1%), 0 events -2026-02-04T19:15:52.422306Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69720/133889 blocks (52.1%), 0 events -2026-02-04T19:15:52.600248Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69730/133889 blocks (52.1%), 0 events -2026-02-04T19:15:52.833308Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69740/133889 blocks (52.1%), 0 events -2026-02-04T19:15:53.080975Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69750/133889 blocks (52.1%), 0 events -2026-02-04T19:15:53.193541Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69760/133889 blocks (52.1%), 0 events -2026-02-04T19:15:53.418792Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69770/133889 blocks (52.1%), 0 events -2026-02-04T19:15:53.617756Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69780/133889 blocks (52.1%), 0 events -2026-02-04T19:15:53.822218Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69790/133889 blocks (52.1%), 0 events -2026-02-04T19:15:54.130525Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69800/133889 blocks (52.1%), 0 events -2026-02-04T19:15:54.175432Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69810/133889 blocks (52.1%), 0 events -2026-02-04T19:15:54.437907Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69820/133889 blocks (52.1%), 0 events -2026-02-04T19:15:54.654226Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69830/133889 blocks (52.2%), 0 events -2026-02-04T19:15:54.846422Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69840/133889 blocks (52.2%), 0 events -2026-02-04T19:15:55.031317Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69850/133889 blocks (52.2%), 0 events -2026-02-04T19:15:55.222991Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69860/133889 blocks (52.2%), 0 events -2026-02-04T19:15:55.380674Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69870/133889 blocks (52.2%), 0 events -2026-02-04T19:15:55.666088Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69880/133889 blocks (52.2%), 0 events -2026-02-04T19:15:55.843515Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69890/133889 blocks (52.2%), 0 events -2026-02-04T19:15:55.980770Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69900/133889 blocks (52.2%), 0 events -2026-02-04T19:15:56.245981Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69910/133889 blocks (52.2%), 0 events -2026-02-04T19:15:56.432653Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69920/133889 blocks (52.2%), 0 events -2026-02-04T19:15:56.565853Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69930/133889 blocks (52.2%), 0 events -2026-02-04T19:15:56.801519Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69940/133889 blocks (52.2%), 0 events -2026-02-04T19:15:56.994826Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69950/133889 blocks (52.2%), 0 events -2026-02-04T19:15:57.270271Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69960/133889 blocks (52.3%), 0 events -2026-02-04T19:15:57.406487Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69970/133889 blocks (52.3%), 0 events -2026-02-04T19:15:57.575964Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69980/133889 blocks (52.3%), 0 events -2026-02-04T19:15:57.825169Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 69990/133889 blocks (52.3%), 0 events -2026-02-04T19:15:58.031362Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70000/133889 blocks (52.3%), 0 events -2026-02-04T19:15:58.288361Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70010/133889 blocks (52.3%), 0 events -2026-02-04T19:15:58.388761Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70020/133889 blocks (52.3%), 0 events -2026-02-04T19:15:58.659025Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70030/133889 blocks (52.3%), 0 events -2026-02-04T19:15:58.846910Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70040/133889 blocks (52.3%), 0 events -2026-02-04T19:15:59.052226Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70050/133889 blocks (52.3%), 0 events -2026-02-04T19:15:59.245454Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70060/133889 blocks (52.3%), 0 events -2026-02-04T19:15:59.400847Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70070/133889 blocks (52.3%), 0 events -2026-02-04T19:15:59.653192Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70080/133889 blocks (52.3%), 0 events -2026-02-04T19:15:59.862826Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70090/133889 blocks (52.3%), 0 events -2026-02-04T19:16:00.018046Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70100/133889 blocks (52.4%), 0 events -2026-02-04T19:16:00.171473Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70110/133889 blocks (52.4%), 0 events -2026-02-04T19:16:00.441641Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70120/133889 blocks (52.4%), 0 events -2026-02-04T19:16:00.620514Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70130/133889 blocks (52.4%), 0 events -2026-02-04T19:16:00.795626Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70140/133889 blocks (52.4%), 0 events -2026-02-04T19:16:01.013534Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70150/133889 blocks (52.4%), 0 events -2026-02-04T19:16:01.191893Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70160/133889 blocks (52.4%), 0 events -2026-02-04T19:16:01.470508Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70170/133889 blocks (52.4%), 0 events -2026-02-04T19:16:01.618882Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70180/133889 blocks (52.4%), 0 events -2026-02-04T19:16:01.824014Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70190/133889 blocks (52.4%), 0 events -2026-02-04T19:16:01.996098Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70200/133889 blocks (52.4%), 0 events -2026-02-04T19:16:02.245202Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70210/133889 blocks (52.4%), 0 events -2026-02-04T19:16:02.483790Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70220/133889 blocks (52.4%), 0 events -2026-02-04T19:16:02.650786Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70230/133889 blocks (52.5%), 0 events -2026-02-04T19:16:02.819209Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70240/133889 blocks (52.5%), 0 events -2026-02-04T19:16:03.053227Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70250/133889 blocks (52.5%), 0 events -2026-02-04T19:16:03.234264Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70260/133889 blocks (52.5%), 0 events -2026-02-04T19:16:03.434550Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70270/133889 blocks (52.5%), 0 events -2026-02-04T19:16:03.567241Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70280/133889 blocks (52.5%), 0 events -2026-02-04T19:16:03.760032Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70290/133889 blocks (52.5%), 0 events -2026-02-04T19:16:04.056086Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70300/133889 blocks (52.5%), 0 events -2026-02-04T19:16:04.257463Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70310/133889 blocks (52.5%), 0 events -2026-02-04T19:16:04.391770Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70320/133889 blocks (52.5%), 0 events -2026-02-04T19:16:04.640408Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70330/133889 blocks (52.5%), 0 events -2026-02-04T19:16:04.835006Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70340/133889 blocks (52.5%), 0 events -2026-02-04T19:16:05.103114Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70350/133889 blocks (52.5%), 0 events -2026-02-04T19:16:05.233472Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70360/133889 blocks (52.6%), 0 events -2026-02-04T19:16:05.450583Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70370/133889 blocks (52.6%), 0 events -2026-02-04T19:16:05.664590Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70380/133889 blocks (52.6%), 0 events -2026-02-04T19:16:05.821167Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70390/133889 blocks (52.6%), 0 events -2026-02-04T19:16:05.967025Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70400/133889 blocks (52.6%), 0 events -2026-02-04T19:16:06.234845Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70410/133889 blocks (52.6%), 0 events -2026-02-04T19:16:06.454467Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70420/133889 blocks (52.6%), 0 events -2026-02-04T19:16:06.679466Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70430/133889 blocks (52.6%), 0 events -2026-02-04T19:16:06.822922Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70440/133889 blocks (52.6%), 0 events -2026-02-04T19:16:06.970517Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70450/133889 blocks (52.6%), 0 events -2026-02-04T19:16:07.236148Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70460/133889 blocks (52.6%), 0 events -2026-02-04T19:16:07.429030Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70470/133889 blocks (52.6%), 0 events -2026-02-04T19:16:07.725901Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70480/133889 blocks (52.6%), 0 events -2026-02-04T19:16:07.767613Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70490/133889 blocks (52.6%), 0 events -2026-02-04T19:16:07.974747Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70500/133889 blocks (52.7%), 0 events -2026-02-04T19:16:08.280459Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70510/133889 blocks (52.7%), 0 events -2026-02-04T19:16:08.446064Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70520/133889 blocks (52.7%), 0 events -2026-02-04T19:16:08.608640Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70530/133889 blocks (52.7%), 0 events -2026-02-04T19:16:08.805683Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70540/133889 blocks (52.7%), 0 events -2026-02-04T19:16:09.035124Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70550/133889 blocks (52.7%), 0 events -2026-02-04T19:16:09.331977Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70560/133889 blocks (52.7%), 0 events -2026-02-04T19:16:09.369762Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70570/133889 blocks (52.7%), 0 events -2026-02-04T19:16:09.571103Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70580/133889 blocks (52.7%), 0 events -2026-02-04T19:16:09.866223Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70590/133889 blocks (52.7%), 0 events -2026-02-04T19:16:10.060454Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70600/133889 blocks (52.7%), 0 events -2026-02-04T19:16:10.200821Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70610/133889 blocks (52.7%), 0 events -2026-02-04T19:16:10.435412Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70620/133889 blocks (52.7%), 0 events -2026-02-04T19:16:10.642468Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70630/133889 blocks (52.8%), 0 events -2026-02-04T19:16:10.872118Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70640/133889 blocks (52.8%), 0 events -2026-02-04T19:16:10.961673Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70650/133889 blocks (52.8%), 0 events -2026-02-04T19:16:11.258045Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70660/133889 blocks (52.8%), 0 events -2026-02-04T19:16:11.442412Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70670/133889 blocks (52.8%), 0 events -2026-02-04T19:16:11.612022Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70680/133889 blocks (52.8%), 0 events -2026-02-04T19:16:11.920958Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70690/133889 blocks (52.8%), 0 events -2026-02-04T19:16:11.956051Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70700/133889 blocks (52.8%), 0 events -2026-02-04T19:16:12.221228Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70710/133889 blocks (52.8%), 0 events -2026-02-04T19:16:12.473535Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70720/133889 blocks (52.8%), 0 events -2026-02-04T19:16:12.679906Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70730/133889 blocks (52.8%), 0 events -2026-02-04T19:16:12.771535Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70740/133889 blocks (52.8%), 0 events -2026-02-04T19:16:13.039655Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70750/133889 blocks (52.8%), 0 events -2026-02-04T19:16:13.228748Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70760/133889 blocks (52.8%), 0 events -2026-02-04T19:16:13.494080Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70770/133889 blocks (52.9%), 0 events -2026-02-04T19:16:13.695299Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70780/133889 blocks (52.9%), 0 events -2026-02-04T19:16:13.813646Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70790/133889 blocks (52.9%), 0 events -2026-02-04T19:16:14.050494Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70800/133889 blocks (52.9%), 0 events -2026-02-04T19:16:14.244703Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70810/133889 blocks (52.9%), 0 events -2026-02-04T19:16:14.376076Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70820/133889 blocks (52.9%), 0 events -2026-02-04T19:16:14.639002Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70830/133889 blocks (52.9%), 0 events -2026-02-04T19:16:14.784878Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70840/133889 blocks (52.9%), 0 events -2026-02-04T19:16:15.064493Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70850/133889 blocks (52.9%), 0 events -2026-02-04T19:16:15.301066Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70860/133889 blocks (52.9%), 0 events -2026-02-04T19:16:15.421732Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70870/133889 blocks (52.9%), 0 events -2026-02-04T19:16:15.637155Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70880/133889 blocks (52.9%), 0 events -2026-02-04T19:16:15.856967Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70890/133889 blocks (52.9%), 0 events -2026-02-04T19:16:16.114409Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70900/133889 blocks (53.0%), 0 events -2026-02-04T19:16:16.219216Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70910/133889 blocks (53.0%), 0 events -2026-02-04T19:16:16.435834Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70920/133889 blocks (53.0%), 0 events -2026-02-04T19:16:16.674772Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70930/133889 blocks (53.0%), 0 events -2026-02-04T19:16:16.870768Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70940/133889 blocks (53.0%), 0 events -2026-02-04T19:16:17.003604Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70950/133889 blocks (53.0%), 0 events -2026-02-04T19:16:17.195462Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70960/133889 blocks (53.0%), 0 events -2026-02-04T19:16:17.456155Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70970/133889 blocks (53.0%), 0 events -2026-02-04T19:16:17.718687Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70980/133889 blocks (53.0%), 0 events -2026-02-04T19:16:17.762970Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 70990/133889 blocks (53.0%), 0 events -2026-02-04T19:16:18.023103Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71000/133889 blocks (53.0%), 0 events -2026-02-04T19:16:18.241033Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71010/133889 blocks (53.0%), 0 events -2026-02-04T19:16:18.400387Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71020/133889 blocks (53.0%), 0 events -2026-02-04T19:16:18.629435Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71030/133889 blocks (53.1%), 0 events -2026-02-04T19:16:18.824851Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71040/133889 blocks (53.1%), 0 events -2026-02-04T19:16:19.006225Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71050/133889 blocks (53.1%), 0 events -2026-02-04T19:16:19.305253Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71060/133889 blocks (53.1%), 0 events -2026-02-04T19:16:19.421541Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71070/133889 blocks (53.1%), 0 events -2026-02-04T19:16:19.622833Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71080/133889 blocks (53.1%), 0 events -2026-02-04T19:16:19.846714Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71090/133889 blocks (53.1%), 0 events -2026-02-04T19:16:20.037925Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71100/133889 blocks (53.1%), 0 events -2026-02-04T19:16:20.205595Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71110/133889 blocks (53.1%), 0 events -2026-02-04T19:16:20.438302Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71120/133889 blocks (53.1%), 0 events -2026-02-04T19:16:20.598831Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71130/133889 blocks (53.1%), 0 events -2026-02-04T19:16:20.873143Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71140/133889 blocks (53.1%), 0 events -2026-02-04T19:16:21.022668Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71150/133889 blocks (53.1%), 0 events -2026-02-04T19:16:21.170657Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71160/133889 blocks (53.1%), 0 events -2026-02-04T19:16:21.386759Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71170/133889 blocks (53.2%), 0 events -2026-02-04T19:16:21.642696Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71180/133889 blocks (53.2%), 0 events -2026-02-04T19:16:21.881299Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71190/133889 blocks (53.2%), 0 events -2026-02-04T19:16:22.032944Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71200/133889 blocks (53.2%), 0 events -2026-02-04T19:16:22.205195Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71210/133889 blocks (53.2%), 0 events -2026-02-04T19:16:22.444398Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71220/133889 blocks (53.2%), 0 events -2026-02-04T19:16:22.614884Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71230/133889 blocks (53.2%), 0 events -2026-02-04T19:16:22.811291Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71240/133889 blocks (53.2%), 0 events -2026-02-04T19:16:23.030594Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71250/133889 blocks (53.2%), 0 events -2026-02-04T19:16:23.215739Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71260/133889 blocks (53.2%), 0 events -2026-02-04T19:16:23.452433Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71270/133889 blocks (53.2%), 0 events -2026-02-04T19:16:23.616255Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71280/133889 blocks (53.2%), 0 events -2026-02-04T19:16:23.776889Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71290/133889 blocks (53.2%), 0 events -2026-02-04T19:16:24.012618Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71300/133889 blocks (53.3%), 0 events -2026-02-04T19:16:24.183840Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71310/133889 blocks (53.3%), 0 events -2026-02-04T19:16:24.504767Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71320/133889 blocks (53.3%), 0 events -2026-02-04T19:16:24.595294Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71330/133889 blocks (53.3%), 0 events -2026-02-04T19:16:24.781301Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71340/133889 blocks (53.3%), 0 events -2026-02-04T19:16:25.024474Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71350/133889 blocks (53.3%), 0 events -2026-02-04T19:16:25.260481Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71360/133889 blocks (53.3%), 0 events -2026-02-04T19:16:25.397974Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71370/133889 blocks (53.3%), 0 events -2026-02-04T19:16:25.638336Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71380/133889 blocks (53.3%), 0 events -2026-02-04T19:16:25.835218Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71390/133889 blocks (53.3%), 0 events -2026-02-04T19:16:26.074253Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71400/133889 blocks (53.3%), 0 events -2026-02-04T19:16:26.242051Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71410/133889 blocks (53.3%), 0 events -2026-02-04T19:16:26.367028Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71420/133889 blocks (53.3%), 0 events -2026-02-04T19:16:26.641093Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71430/133889 blocks (53.3%), 0 events -2026-02-04T19:16:26.777831Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71440/133889 blocks (53.4%), 0 events -2026-02-04T19:16:26.979104Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71450/133889 blocks (53.4%), 0 events -2026-02-04T19:16:27.318038Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71460/133889 blocks (53.4%), 0 events -2026-02-04T19:16:27.357866Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71470/133889 blocks (53.4%), 0 events -2026-02-04T19:16:27.680009Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71480/133889 blocks (53.4%), 0 events -2026-02-04T19:16:27.874761Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71490/133889 blocks (53.4%), 0 events -2026-02-04T19:16:27.966685Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71500/133889 blocks (53.4%), 0 events -2026-02-04T19:16:28.423388Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71510/133889 blocks (53.4%), 0 events -2026-02-04T19:16:28.458554Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71520/133889 blocks (53.4%), 0 events -2026-02-04T19:16:28.728335Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71530/133889 blocks (53.4%), 0 events -2026-02-04T19:16:28.763950Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71540/133889 blocks (53.4%), 0 events -2026-02-04T19:16:29.036907Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71550/133889 blocks (53.4%), 0 events -2026-02-04T19:16:29.260557Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71560/133889 blocks (53.4%), 0 events -2026-02-04T19:16:29.427035Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71570/133889 blocks (53.5%), 0 events -2026-02-04T19:16:29.562679Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71580/133889 blocks (53.5%), 0 events -2026-02-04T19:16:29.804563Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71590/133889 blocks (53.5%), 0 events -2026-02-04T19:16:29.961205Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71600/133889 blocks (53.5%), 0 events -2026-02-04T19:16:30.271078Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71610/133889 blocks (53.5%), 0 events -2026-02-04T19:16:30.455169Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71620/133889 blocks (53.5%), 0 events -2026-02-04T19:16:30.571266Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71630/133889 blocks (53.5%), 0 events -2026-02-04T19:16:30.829022Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71640/133889 blocks (53.5%), 0 events -2026-02-04T19:16:31.039406Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71650/133889 blocks (53.5%), 0 events -2026-02-04T19:16:31.318759Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71660/133889 blocks (53.5%), 0 events -2026-02-04T19:16:31.619865Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71670/133889 blocks (53.5%), 0 events -2026-02-04T19:16:31.662855Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71680/133889 blocks (53.5%), 0 events -2026-02-04T19:16:31.842139Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71690/133889 blocks (53.5%), 0 events -2026-02-04T19:16:31.968120Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71700/133889 blocks (53.6%), 0 events -2026-02-04T19:16:32.261118Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71710/133889 blocks (53.6%), 0 events -2026-02-04T19:16:32.396546Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71720/133889 blocks (53.6%), 0 events -2026-02-04T19:16:32.592903Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71730/133889 blocks (53.6%), 0 events -2026-02-04T19:16:32.781343Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71740/133889 blocks (53.6%), 0 events -2026-02-04T19:16:33.065405Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71750/133889 blocks (53.6%), 0 events -2026-02-04T19:16:33.194685Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71760/133889 blocks (53.6%), 0 events -2026-02-04T19:16:33.447687Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71770/133889 blocks (53.6%), 0 events -2026-02-04T19:16:33.608170Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71780/133889 blocks (53.6%), 0 events -2026-02-04T19:16:33.832383Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71790/133889 blocks (53.6%), 0 events -2026-02-04T19:16:34.013223Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71800/133889 blocks (53.6%), 0 events -2026-02-04T19:16:34.199052Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71810/133889 blocks (53.6%), 0 events -2026-02-04T19:16:34.464892Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71820/133889 blocks (53.6%), 0 events -2026-02-04T19:16:34.570313Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71830/133889 blocks (53.6%), 0 events -2026-02-04T19:16:34.842218Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71840/133889 blocks (53.7%), 0 events -2026-02-04T19:16:35.025409Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71850/133889 blocks (53.7%), 0 events -2026-02-04T19:16:35.234314Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71860/133889 blocks (53.7%), 0 events -2026-02-04T19:16:35.368606Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71870/133889 blocks (53.7%), 0 events -2026-02-04T19:16:35.564829Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71880/133889 blocks (53.7%), 0 events -2026-02-04T19:16:35.786276Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71890/133889 blocks (53.7%), 0 events -2026-02-04T19:16:36.076546Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71900/133889 blocks (53.7%), 0 events -2026-02-04T19:16:36.169881Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71910/133889 blocks (53.7%), 0 events -2026-02-04T19:16:36.443042Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71920/133889 blocks (53.7%), 0 events -2026-02-04T19:16:36.659667Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71930/133889 blocks (53.7%), 0 events -2026-02-04T19:16:36.818803Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71940/133889 blocks (53.7%), 0 events -2026-02-04T19:16:37.087248Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71950/133889 blocks (53.7%), 0 events -2026-02-04T19:16:37.165871Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71960/133889 blocks (53.7%), 0 events -2026-02-04T19:16:37.388858Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71970/133889 blocks (53.8%), 0 events -2026-02-04T19:16:37.644471Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71980/133889 blocks (53.8%), 0 events -2026-02-04T19:16:37.848885Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 71990/133889 blocks (53.8%), 0 events -2026-02-04T19:16:38.025493Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72000/133889 blocks (53.8%), 0 events -2026-02-04T19:16:38.189935Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72010/133889 blocks (53.8%), 0 events -2026-02-04T19:16:38.359376Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72020/133889 blocks (53.8%), 0 events -2026-02-04T19:16:38.658257Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72030/133889 blocks (53.8%), 0 events -2026-02-04T19:16:38.788494Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72040/133889 blocks (53.8%), 0 events -2026-02-04T19:16:38.995970Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72050/133889 blocks (53.8%), 0 events -2026-02-04T19:16:39.226405Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72060/133889 blocks (53.8%), 0 events -2026-02-04T19:16:39.395760Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72070/133889 blocks (53.8%), 0 events -2026-02-04T19:16:39.561436Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72080/133889 blocks (53.8%), 0 events -2026-02-04T19:16:39.835088Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72090/133889 blocks (53.8%), 0 events -2026-02-04T19:16:39.965563Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72100/133889 blocks (53.9%), 0 events -2026-02-04T19:16:40.269151Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72110/133889 blocks (53.9%), 0 events -2026-02-04T19:16:40.447111Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72120/133889 blocks (53.9%), 0 events -2026-02-04T19:16:40.646721Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72130/133889 blocks (53.9%), 0 events -2026-02-04T19:16:40.820605Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72140/133889 blocks (53.9%), 0 events -2026-02-04T19:16:41.010223Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72150/133889 blocks (53.9%), 0 events -2026-02-04T19:16:41.279775Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72160/133889 blocks (53.9%), 0 events -2026-02-04T19:16:41.415308Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72170/133889 blocks (53.9%), 0 events -2026-02-04T19:16:41.570088Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72180/133889 blocks (53.9%), 0 events -2026-02-04T19:16:41.842212Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72190/133889 blocks (53.9%), 0 events -2026-02-04T19:16:42.041972Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72200/133889 blocks (53.9%), 0 events -2026-02-04T19:16:42.221384Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72210/133889 blocks (53.9%), 0 events -2026-02-04T19:16:42.411086Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72220/133889 blocks (53.9%), 0 events -2026-02-04T19:16:42.655778Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72230/133889 blocks (53.9%), 0 events -2026-02-04T19:16:42.755381Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72240/133889 blocks (54.0%), 0 events -2026-02-04T19:16:43.058076Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72250/133889 blocks (54.0%), 0 events -2026-02-04T19:16:43.153312Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72260/133889 blocks (54.0%), 0 events -2026-02-04T19:16:43.423761Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72270/133889 blocks (54.0%), 0 events -2026-02-04T19:16:43.613245Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72280/133889 blocks (54.0%), 0 events -2026-02-04T19:16:43.900636Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72290/133889 blocks (54.0%), 0 events -2026-02-04T19:16:44.053294Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72300/133889 blocks (54.0%), 0 events -2026-02-04T19:16:44.223159Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72310/133889 blocks (54.0%), 0 events -2026-02-04T19:16:44.461555Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72320/133889 blocks (54.0%), 0 events -2026-02-04T19:16:44.630620Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72330/133889 blocks (54.0%), 0 events -2026-02-04T19:16:44.766249Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72340/133889 blocks (54.0%), 0 events -2026-02-04T19:16:44.992273Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72350/133889 blocks (54.0%), 0 events -2026-02-04T19:16:45.172483Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72360/133889 blocks (54.0%), 0 events -2026-02-04T19:16:45.504956Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72370/133889 blocks (54.1%), 0 events -2026-02-04T19:16:45.607475Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72380/133889 blocks (54.1%), 0 events -2026-02-04T19:16:45.847471Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72390/133889 blocks (54.1%), 0 events -2026-02-04T19:16:46.040606Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72400/133889 blocks (54.1%), 0 events -2026-02-04T19:16:46.215914Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72410/133889 blocks (54.1%), 0 events -2026-02-04T19:16:46.360451Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72420/133889 blocks (54.1%), 0 events -2026-02-04T19:16:46.656333Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72430/133889 blocks (54.1%), 0 events -2026-02-04T19:16:46.761153Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72440/133889 blocks (54.1%), 0 events -2026-02-04T19:16:47.076959Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72450/133889 blocks (54.1%), 0 events -2026-02-04T19:16:47.166117Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72460/133889 blocks (54.1%), 0 events -2026-02-04T19:16:47.385937Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72470/133889 blocks (54.1%), 0 events -2026-02-04T19:16:47.615086Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72480/133889 blocks (54.1%), 0 events -2026-02-04T19:16:47.844350Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72490/133889 blocks (54.1%), 0 events -2026-02-04T19:16:47.958258Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72500/133889 blocks (54.1%), 0 events -2026-02-04T19:16:48.217731Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72510/133889 blocks (54.2%), 0 events -2026-02-04T19:16:48.412229Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72520/133889 blocks (54.2%), 0 events -2026-02-04T19:16:48.618812Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72530/133889 blocks (54.2%), 0 events -2026-02-04T19:16:48.773590Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72540/133889 blocks (54.2%), 0 events -2026-02-04T19:16:49.141287Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72550/133889 blocks (54.2%), 0 events -2026-02-04T19:16:49.177354Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72560/133889 blocks (54.2%), 0 events -2026-02-04T19:16:49.378216Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72570/133889 blocks (54.2%), 0 events -2026-02-04T19:16:49.667904Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72580/133889 blocks (54.2%), 0 events -2026-02-04T19:16:49.767741Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72590/133889 blocks (54.2%), 0 events -2026-02-04T19:16:50.011077Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72600/133889 blocks (54.2%), 0 events -2026-02-04T19:16:50.227160Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72610/133889 blocks (54.2%), 0 events -2026-02-04T19:16:50.398876Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72620/133889 blocks (54.2%), 0 events -2026-02-04T19:16:50.751239Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72630/133889 blocks (54.2%), 0 events -2026-02-04T19:16:50.790520Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72640/133889 blocks (54.3%), 0 events -2026-02-04T19:16:51.032735Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72650/133889 blocks (54.3%), 0 events -2026-02-04T19:16:51.274652Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72660/133889 blocks (54.3%), 0 events -2026-02-04T19:16:51.365233Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72670/133889 blocks (54.3%), 0 events -2026-02-04T19:16:51.618532Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72680/133889 blocks (54.3%), 0 events -2026-02-04T19:16:51.810669Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72690/133889 blocks (54.3%), 0 events -2026-02-04T19:16:52.028666Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72700/133889 blocks (54.3%), 0 events -2026-02-04T19:16:52.289390Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72710/133889 blocks (54.3%), 0 events -2026-02-04T19:16:52.457277Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72720/133889 blocks (54.3%), 0 events -2026-02-04T19:16:52.660098Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72730/133889 blocks (54.3%), 0 events -2026-02-04T19:16:52.843324Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72740/133889 blocks (54.3%), 0 events -2026-02-04T19:16:52.963402Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72750/133889 blocks (54.3%), 0 events -2026-02-04T19:16:53.197860Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72760/133889 blocks (54.3%), 0 events -2026-02-04T19:16:53.371407Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72770/133889 blocks (54.4%), 0 events -2026-02-04T19:16:53.669654Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72780/133889 blocks (54.4%), 0 events -2026-02-04T19:16:53.895388Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72790/133889 blocks (54.4%), 0 events -2026-02-04T19:16:53.987283Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72800/133889 blocks (54.4%), 0 events -2026-02-04T19:16:54.217096Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72810/133889 blocks (54.4%), 0 events -2026-02-04T19:16:54.417866Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72820/133889 blocks (54.4%), 0 events -2026-02-04T19:16:54.645447Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72830/133889 blocks (54.4%), 0 events -2026-02-04T19:16:54.820919Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72840/133889 blocks (54.4%), 0 events -2026-02-04T19:16:55.055309Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72850/133889 blocks (54.4%), 0 events -2026-02-04T19:16:55.229809Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72860/133889 blocks (54.4%), 0 events -2026-02-04T19:16:55.464535Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72870/133889 blocks (54.4%), 0 events -2026-02-04T19:16:55.573768Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72880/133889 blocks (54.4%), 0 events -2026-02-04T19:16:55.819971Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72890/133889 blocks (54.4%), 0 events -2026-02-04T19:16:56.055724Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72900/133889 blocks (54.4%), 0 events -2026-02-04T19:16:56.226418Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72910/133889 blocks (54.5%), 0 events -2026-02-04T19:16:56.515634Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72920/133889 blocks (54.5%), 0 events -2026-02-04T19:16:56.554824Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72930/133889 blocks (54.5%), 0 events -2026-02-04T19:16:56.842153Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72940/133889 blocks (54.5%), 0 events -2026-02-04T19:16:57.036940Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72950/133889 blocks (54.5%), 0 events -2026-02-04T19:16:57.225399Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72960/133889 blocks (54.5%), 0 events -2026-02-04T19:16:57.368321Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72970/133889 blocks (54.5%), 0 events -2026-02-04T19:16:57.600410Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72980/133889 blocks (54.5%), 0 events -2026-02-04T19:16:57.779622Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 72990/133889 blocks (54.5%), 0 events -2026-02-04T19:16:58.095297Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73000/133889 blocks (54.5%), 0 events -2026-02-04T19:16:58.228903Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73010/133889 blocks (54.5%), 0 events -2026-02-04T19:16:58.414645Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73020/133889 blocks (54.5%), 0 events -2026-02-04T19:16:58.611498Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73030/133889 blocks (54.5%), 0 events -2026-02-04T19:16:58.845968Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73040/133889 blocks (54.6%), 0 events -2026-02-04T19:16:59.010569Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73050/133889 blocks (54.6%), 0 events -2026-02-04T19:16:59.164377Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73060/133889 blocks (54.6%), 0 events -2026-02-04T19:16:59.445205Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73070/133889 blocks (54.6%), 0 events -2026-02-04T19:16:59.664312Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73080/133889 blocks (54.6%), 0 events -2026-02-04T19:16:59.828324Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73090/133889 blocks (54.6%), 0 events -2026-02-04T19:16:59.978478Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73100/133889 blocks (54.6%), 0 events -2026-02-04T19:17:00.210685Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73110/133889 blocks (54.6%), 0 events -2026-02-04T19:17:00.454432Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73120/133889 blocks (54.6%), 0 events -2026-02-04T19:17:00.677081Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73130/133889 blocks (54.6%), 0 events -2026-02-04T19:17:00.842956Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73140/133889 blocks (54.6%), 0 events -2026-02-04T19:17:00.986806Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73150/133889 blocks (54.6%), 0 events -2026-02-04T19:17:01.234194Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73160/133889 blocks (54.6%), 0 events -2026-02-04T19:17:01.419691Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73170/133889 blocks (54.6%), 0 events -2026-02-04T19:17:01.727191Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73180/133889 blocks (54.7%), 0 events -2026-02-04T19:17:01.770857Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73190/133889 blocks (54.7%), 0 events -2026-02-04T19:17:02.003722Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73200/133889 blocks (54.7%), 0 events -2026-02-04T19:17:02.286409Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73210/133889 blocks (54.7%), 0 events -2026-02-04T19:17:02.434360Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73220/133889 blocks (54.7%), 0 events -2026-02-04T19:17:02.610499Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73230/133889 blocks (54.7%), 0 events -2026-02-04T19:17:02.809965Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73240/133889 blocks (54.7%), 0 events -2026-02-04T19:17:02.984334Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73250/133889 blocks (54.7%), 0 events -2026-02-04T19:17:03.295939Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73260/133889 blocks (54.7%), 0 events -2026-02-04T19:17:03.435243Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73270/133889 blocks (54.7%), 0 events -2026-02-04T19:17:03.579069Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73280/133889 blocks (54.7%), 0 events -2026-02-04T19:17:03.857961Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73290/133889 blocks (54.7%), 0 events -2026-02-04T19:17:03.996958Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73300/133889 blocks (54.7%), 0 events -2026-02-04T19:17:04.222216Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73310/133889 blocks (54.8%), 0 events -2026-02-04T19:17:04.452444Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73320/133889 blocks (54.8%), 0 events -2026-02-04T19:17:04.642369Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73330/133889 blocks (54.8%), 0 events -2026-02-04T19:17:04.871248Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73340/133889 blocks (54.8%), 0 events -2026-02-04T19:17:05.046979Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73350/133889 blocks (54.8%), 0 events -2026-02-04T19:17:05.179802Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73360/133889 blocks (54.8%), 0 events -2026-02-04T19:17:05.455413Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73370/133889 blocks (54.8%), 0 events -2026-02-04T19:17:05.627330Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73380/133889 blocks (54.8%), 0 events -2026-02-04T19:17:05.795712Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73390/133889 blocks (54.8%), 0 events -2026-02-04T19:17:06.009528Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73400/133889 blocks (54.8%), 0 events -2026-02-04T19:17:06.200120Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73410/133889 blocks (54.8%), 0 events -2026-02-04T19:17:06.478901Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73420/133889 blocks (54.8%), 0 events -2026-02-04T19:17:06.622248Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73430/133889 blocks (54.8%), 0 events -2026-02-04T19:17:06.796307Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73440/133889 blocks (54.9%), 0 events -2026-02-04T19:17:07.055658Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73450/133889 blocks (54.9%), 0 events -2026-02-04T19:17:07.173076Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73460/133889 blocks (54.9%), 0 events -2026-02-04T19:17:07.395715Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73470/133889 blocks (54.9%), 0 events -2026-02-04T19:17:07.628190Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73480/133889 blocks (54.9%), 0 events -2026-02-04T19:17:07.768166Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73490/133889 blocks (54.9%), 0 events -2026-02-04T19:17:08.048550Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73500/133889 blocks (54.9%), 0 events -2026-02-04T19:17:08.171030Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73510/133889 blocks (54.9%), 0 events -2026-02-04T19:17:08.431191Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73520/133889 blocks (54.9%), 0 events -2026-02-04T19:17:08.614847Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73530/133889 blocks (54.9%), 0 events -2026-02-04T19:17:08.819344Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73540/133889 blocks (54.9%), 0 events -2026-02-04T19:17:09.098461Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73550/133889 blocks (54.9%), 0 events -2026-02-04T19:17:09.253260Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73560/133889 blocks (54.9%), 0 events -2026-02-04T19:17:09.448548Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73570/133889 blocks (54.9%), 0 events -2026-02-04T19:17:09.635882Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73580/133889 blocks (55.0%), 0 events -2026-02-04T19:17:09.808018Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73590/133889 blocks (55.0%), 0 events -2026-02-04T19:17:09.975703Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73600/133889 blocks (55.0%), 0 events -2026-02-04T19:17:10.221412Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73610/133889 blocks (55.0%), 0 events -2026-02-04T19:17:10.393502Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73620/133889 blocks (55.0%), 0 events -2026-02-04T19:17:10.686215Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73630/133889 blocks (55.0%), 0 events -2026-02-04T19:17:10.796674Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73640/133889 blocks (55.0%), 0 events -2026-02-04T19:17:11.028929Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73650/133889 blocks (55.0%), 0 events -2026-02-04T19:17:11.192517Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73660/133889 blocks (55.0%), 0 events -2026-02-04T19:17:11.447010Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73670/133889 blocks (55.0%), 0 events -2026-02-04T19:17:11.685326Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73680/133889 blocks (55.0%), 0 events -2026-02-04T19:17:11.829634Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73690/133889 blocks (55.0%), 0 events -2026-02-04T19:17:11.990430Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73700/133889 blocks (55.0%), 0 events -2026-02-04T19:17:12.260297Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73710/133889 blocks (55.1%), 0 events -2026-02-04T19:17:12.419513Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73720/133889 blocks (55.1%), 0 events -2026-02-04T19:17:12.605526Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73730/133889 blocks (55.1%), 0 events -2026-02-04T19:17:12.826475Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73740/133889 blocks (55.1%), 0 events -2026-02-04T19:17:13.002038Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73750/133889 blocks (55.1%), 0 events -2026-02-04T19:17:13.313371Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73760/133889 blocks (55.1%), 0 events -2026-02-04T19:17:13.366324Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73770/133889 blocks (55.1%), 0 events -2026-02-04T19:17:13.597287Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73780/133889 blocks (55.1%), 0 events -2026-02-04T19:17:13.815062Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73790/133889 blocks (55.1%), 0 events -2026-02-04T19:17:14.037088Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73800/133889 blocks (55.1%), 0 events -2026-02-04T19:17:14.175343Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73810/133889 blocks (55.1%), 0 events -2026-02-04T19:17:14.365197Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73820/133889 blocks (55.1%), 0 events -2026-02-04T19:17:14.573886Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73830/133889 blocks (55.1%), 0 events -2026-02-04T19:17:14.867862Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73840/133889 blocks (55.1%), 0 events -2026-02-04T19:17:15.039044Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73850/133889 blocks (55.2%), 0 events -2026-02-04T19:17:15.256239Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73860/133889 blocks (55.2%), 0 events -2026-02-04T19:17:15.397783Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73870/133889 blocks (55.2%), 0 events -2026-02-04T19:17:15.599497Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73880/133889 blocks (55.2%), 0 events -2026-02-04T19:17:15.787320Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73890/133889 blocks (55.2%), 0 events -2026-02-04T19:17:16.027761Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73900/133889 blocks (55.2%), 0 events -2026-02-04T19:17:16.174971Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73910/133889 blocks (55.2%), 0 events -2026-02-04T19:17:16.432083Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73920/133889 blocks (55.2%), 0 events -2026-02-04T19:17:16.605095Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73930/133889 blocks (55.2%), 0 events -2026-02-04T19:17:16.784657Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73940/133889 blocks (55.2%), 0 events -2026-02-04T19:17:16.989274Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73950/133889 blocks (55.2%), 0 events -2026-02-04T19:17:17.166913Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73960/133889 blocks (55.2%), 0 events -2026-02-04T19:17:17.484166Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73970/133889 blocks (55.2%), 0 events -2026-02-04T19:17:17.566208Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73980/133889 blocks (55.3%), 0 events -2026-02-04T19:17:17.823650Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 73990/133889 blocks (55.3%), 0 events -2026-02-04T19:17:18.032399Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74000/133889 blocks (55.3%), 0 events -2026-02-04T19:17:18.245846Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74010/133889 blocks (55.3%), 0 events -2026-02-04T19:17:18.404271Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74020/133889 blocks (55.3%), 0 events -2026-02-04T19:17:18.607344Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74030/133889 blocks (55.3%), 0 events -2026-02-04T19:17:18.822833Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74040/133889 blocks (55.3%), 0 events -2026-02-04T19:17:19.060441Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74050/133889 blocks (55.3%), 0 events -2026-02-04T19:17:19.208672Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74060/133889 blocks (55.3%), 0 events -2026-02-04T19:17:19.403647Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74070/133889 blocks (55.3%), 0 events -2026-02-04T19:17:19.590955Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74080/133889 blocks (55.3%), 0 events -2026-02-04T19:17:19.854030Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74090/133889 blocks (55.3%), 0 events -2026-02-04T19:17:20.075577Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74100/133889 blocks (55.3%), 0 events -2026-02-04T19:17:20.221897Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74110/133889 blocks (55.4%), 0 events -2026-02-04T19:17:20.389834Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74120/133889 blocks (55.4%), 0 events -2026-02-04T19:17:20.633077Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74130/133889 blocks (55.4%), 0 events -2026-02-04T19:17:20.856919Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74140/133889 blocks (55.4%), 0 events -2026-02-04T19:17:21.120840Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74150/133889 blocks (55.4%), 0 events -2026-02-04T19:17:21.161351Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74160/133889 blocks (55.4%), 0 events -2026-02-04T19:17:21.411441Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74170/133889 blocks (55.4%), 0 events -2026-02-04T19:17:21.680583Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74180/133889 blocks (55.4%), 0 events -2026-02-04T19:17:21.825995Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74190/133889 blocks (55.4%), 0 events -2026-02-04T19:17:22.064260Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74200/133889 blocks (55.4%), 0 events -2026-02-04T19:17:22.205325Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74210/133889 blocks (55.4%), 0 events -2026-02-04T19:17:22.411994Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74220/133889 blocks (55.4%), 0 events -2026-02-04T19:17:22.590544Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74230/133889 blocks (55.4%), 0 events -2026-02-04T19:17:22.803525Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74240/133889 blocks (55.4%), 0 events -2026-02-04T19:17:23.013405Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74250/133889 blocks (55.5%), 0 events -2026-02-04T19:17:23.252699Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74260/133889 blocks (55.5%), 0 events -2026-02-04T19:17:23.422129Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74270/133889 blocks (55.5%), 0 events -2026-02-04T19:17:23.601651Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74280/133889 blocks (55.5%), 0 events -2026-02-04T19:17:23.803698Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74290/133889 blocks (55.5%), 0 events -2026-02-04T19:17:24.047496Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74300/133889 blocks (55.5%), 0 events -2026-02-04T19:17:24.305501Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74310/133889 blocks (55.5%), 0 events -2026-02-04T19:17:24.434010Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74320/133889 blocks (55.5%), 0 events -2026-02-04T19:17:24.877829Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74330/133889 blocks (55.5%), 0 events -2026-02-04T19:17:24.916018Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74340/133889 blocks (55.5%), 0 events -2026-02-04T19:17:24.950028Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74350/133889 blocks (55.5%), 0 events -2026-02-04T19:17:25.316726Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74360/133889 blocks (55.5%), 0 events -2026-02-04T19:17:25.358326Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74370/133889 blocks (55.5%), 0 events -2026-02-04T19:17:25.560019Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74380/133889 blocks (55.6%), 0 events -2026-02-04T19:17:25.878992Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74390/133889 blocks (55.6%), 0 events -2026-02-04T19:17:26.024418Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74400/133889 blocks (55.6%), 0 events -2026-02-04T19:17:26.232490Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74410/133889 blocks (55.6%), 0 events -2026-02-04T19:17:26.405770Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74420/133889 blocks (55.6%), 0 events -2026-02-04T19:17:26.613478Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74430/133889 blocks (55.6%), 0 events -2026-02-04T19:17:26.789431Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74440/133889 blocks (55.6%), 0 events -2026-02-04T19:17:26.989894Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74450/133889 blocks (55.6%), 0 events -2026-02-04T19:17:27.213618Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74460/133889 blocks (55.6%), 0 events -2026-02-04T19:17:27.445417Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74470/133889 blocks (55.6%), 0 events -2026-02-04T19:17:27.626512Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74480/133889 blocks (55.6%), 0 events -2026-02-04T19:17:27.836500Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74490/133889 blocks (55.6%), 0 events -2026-02-04T19:17:28.027522Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74500/133889 blocks (55.6%), 0 events -2026-02-04T19:17:28.236360Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74510/133889 blocks (55.7%), 0 events -2026-02-04T19:17:28.501315Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74520/133889 blocks (55.7%), 0 events -2026-02-04T19:17:28.620483Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74530/133889 blocks (55.7%), 0 events -2026-02-04T19:17:28.854396Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74540/133889 blocks (55.7%), 0 events -2026-02-04T19:17:29.022843Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74550/133889 blocks (55.7%), 0 events -2026-02-04T19:17:29.257876Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74560/133889 blocks (55.7%), 0 events -2026-02-04T19:17:29.508922Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74570/133889 blocks (55.7%), 0 events -2026-02-04T19:17:29.591389Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74580/133889 blocks (55.7%), 0 events -2026-02-04T19:17:29.784616Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74590/133889 blocks (55.7%), 0 events -2026-02-04T19:17:30.068397Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74600/133889 blocks (55.7%), 0 events -2026-02-04T19:17:30.200027Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74610/133889 blocks (55.7%), 0 events -2026-02-04T19:17:30.558180Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74620/133889 blocks (55.7%), 0 events -2026-02-04T19:17:30.596067Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74630/133889 blocks (55.7%), 0 events -2026-02-04T19:17:30.770234Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74640/133889 blocks (55.7%), 0 events -2026-02-04T19:17:31.084525Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74650/133889 blocks (55.8%), 0 events -2026-02-04T19:17:31.230064Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74660/133889 blocks (55.8%), 0 events -2026-02-04T19:17:31.377724Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74670/133889 blocks (55.8%), 0 events -2026-02-04T19:17:31.647584Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74680/133889 blocks (55.8%), 0 events -2026-02-04T19:17:31.808344Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74690/133889 blocks (55.8%), 0 events -2026-02-04T19:17:31.994130Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74700/133889 blocks (55.8%), 0 events -2026-02-04T19:17:32.163370Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74710/133889 blocks (55.8%), 0 events -2026-02-04T19:17:32.444539Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74720/133889 blocks (55.8%), 0 events -2026-02-04T19:17:32.691585Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74730/133889 blocks (55.8%), 0 events -2026-02-04T19:17:32.821374Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74740/133889 blocks (55.8%), 0 events -2026-02-04T19:17:32.971224Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74750/133889 blocks (55.8%), 0 events -2026-02-04T19:17:33.217457Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74760/133889 blocks (55.8%), 0 events -2026-02-04T19:17:33.405312Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74770/133889 blocks (55.8%), 0 events -2026-02-04T19:17:33.703928Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74780/133889 blocks (55.9%), 0 events -2026-02-04T19:17:33.770379Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74790/133889 blocks (55.9%), 0 events -2026-02-04T19:17:33.989372Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74800/133889 blocks (55.9%), 0 events -2026-02-04T19:17:34.289239Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74810/133889 blocks (55.9%), 0 events -2026-02-04T19:17:34.409836Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74820/133889 blocks (55.9%), 0 events -2026-02-04T19:17:34.618202Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74830/133889 blocks (55.9%), 0 events -2026-02-04T19:17:34.806544Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74840/133889 blocks (55.9%), 0 events -2026-02-04T19:17:35.014454Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74850/133889 blocks (55.9%), 0 events -2026-02-04T19:17:35.276700Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74860/133889 blocks (55.9%), 0 events -2026-02-04T19:17:35.417992Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74870/133889 blocks (55.9%), 0 events -2026-02-04T19:17:35.601973Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74880/133889 blocks (55.9%), 0 events -2026-02-04T19:17:35.860000Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74890/133889 blocks (55.9%), 0 events -2026-02-04T19:17:36.009794Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74900/133889 blocks (55.9%), 0 events -2026-02-04T19:17:36.324967Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74910/133889 blocks (55.9%), 0 events -2026-02-04T19:17:36.378052Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74920/133889 blocks (56.0%), 0 events -2026-02-04T19:17:36.632470Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74930/133889 blocks (56.0%), 0 events -2026-02-04T19:17:36.897438Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74940/133889 blocks (56.0%), 0 events -2026-02-04T19:17:36.995738Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74950/133889 blocks (56.0%), 0 events -2026-02-04T19:17:37.234434Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74960/133889 blocks (56.0%), 0 events -2026-02-04T19:17:37.461031Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74970/133889 blocks (56.0%), 0 events -2026-02-04T19:17:37.633850Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74980/133889 blocks (56.0%), 0 events -2026-02-04T19:17:37.797307Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 74990/133889 blocks (56.0%), 0 events -2026-02-04T19:17:38.022369Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75000/133889 blocks (56.0%), 0 events -2026-02-04T19:17:38.167622Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75010/133889 blocks (56.0%), 0 events -2026-02-04T19:17:38.456457Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75020/133889 blocks (56.0%), 0 events -2026-02-04T19:17:38.584691Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75030/133889 blocks (56.0%), 0 events -2026-02-04T19:17:38.771832Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75040/133889 blocks (56.0%), 0 events -2026-02-04T19:17:38.980814Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75050/133889 blocks (56.1%), 0 events -2026-02-04T19:17:39.185104Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75060/133889 blocks (56.1%), 0 events -2026-02-04T19:17:39.365738Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75070/133889 blocks (56.1%), 0 events -2026-02-04T19:17:39.652994Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75080/133889 blocks (56.1%), 0 events -2026-02-04T19:17:39.848388Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75090/133889 blocks (56.1%), 0 events -2026-02-04T19:17:40.036512Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75100/133889 blocks (56.1%), 0 events -2026-02-04T19:17:40.186269Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75110/133889 blocks (56.1%), 0 events -2026-02-04T19:17:40.403765Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75120/133889 blocks (56.1%), 0 events -2026-02-04T19:17:40.659979Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75130/133889 blocks (56.1%), 0 events -2026-02-04T19:17:40.851069Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75140/133889 blocks (56.1%), 0 events -2026-02-04T19:17:41.045406Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75150/133889 blocks (56.1%), 0 events -2026-02-04T19:17:41.181622Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75160/133889 blocks (56.1%), 0 events -2026-02-04T19:17:41.366723Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75170/133889 blocks (56.1%), 0 events -2026-02-04T19:17:41.649081Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75180/133889 blocks (56.2%), 0 events -2026-02-04T19:17:41.849702Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75190/133889 blocks (56.2%), 0 events -2026-02-04T19:17:42.091885Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75200/133889 blocks (56.2%), 0 events -2026-02-04T19:17:42.157720Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75210/133889 blocks (56.2%), 0 events -2026-02-04T19:17:42.365763Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75220/133889 blocks (56.2%), 0 events -2026-02-04T19:17:42.649943Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75230/133889 blocks (56.2%), 0 events -2026-02-04T19:17:42.775603Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75240/133889 blocks (56.2%), 0 events -2026-02-04T19:17:42.979202Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75250/133889 blocks (56.2%), 0 events -2026-02-04T19:17:43.202029Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75260/133889 blocks (56.2%), 0 events -2026-02-04T19:17:43.453114Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75270/133889 blocks (56.2%), 0 events -2026-02-04T19:17:43.699863Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75280/133889 blocks (56.2%), 0 events -2026-02-04T19:17:43.760341Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75290/133889 blocks (56.2%), 0 events -2026-02-04T19:17:44.027390Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75300/133889 blocks (56.2%), 0 events -2026-02-04T19:17:44.222243Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75310/133889 blocks (56.2%), 0 events -2026-02-04T19:17:44.441599Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75320/133889 blocks (56.3%), 0 events -2026-02-04T19:17:44.585236Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75330/133889 blocks (56.3%), 0 events -2026-02-04T19:17:44.802186Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75340/133889 blocks (56.3%), 0 events -2026-02-04T19:17:45.008604Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75350/133889 blocks (56.3%), 0 events -2026-02-04T19:17:45.237105Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75360/133889 blocks (56.3%), 0 events -2026-02-04T19:17:45.441867Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75370/133889 blocks (56.3%), 0 events -2026-02-04T19:17:45.658595Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75380/133889 blocks (56.3%), 0 events -2026-02-04T19:17:45.792970Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75390/133889 blocks (56.3%), 0 events -2026-02-04T19:17:46.011953Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75400/133889 blocks (56.3%), 0 events -2026-02-04T19:17:46.320439Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75410/133889 blocks (56.3%), 0 events -2026-02-04T19:17:46.363556Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75420/133889 blocks (56.3%), 0 events -2026-02-04T19:17:46.574938Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75430/133889 blocks (56.3%), 0 events -2026-02-04T19:17:46.849142Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75440/133889 blocks (56.3%), 0 events -2026-02-04T19:17:46.987278Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75450/133889 blocks (56.4%), 0 events -2026-02-04T19:17:47.210640Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75460/133889 blocks (56.4%), 0 events -2026-02-04T19:17:47.440384Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75470/133889 blocks (56.4%), 0 events -2026-02-04T19:17:47.592776Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75480/133889 blocks (56.4%), 0 events -2026-02-04T19:17:47.861172Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75490/133889 blocks (56.4%), 0 events -2026-02-04T19:17:48.038555Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75500/133889 blocks (56.4%), 0 events -2026-02-04T19:17:48.251223Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75510/133889 blocks (56.4%), 0 events -2026-02-04T19:17:48.451008Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75520/133889 blocks (56.4%), 0 events -2026-02-04T19:17:48.601227Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75530/133889 blocks (56.4%), 0 events -2026-02-04T19:17:48.776749Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75540/133889 blocks (56.4%), 0 events -2026-02-04T19:17:48.989453Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75550/133889 blocks (56.4%), 0 events -2026-02-04T19:17:49.201868Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75560/133889 blocks (56.4%), 0 events -2026-02-04T19:17:49.468822Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75570/133889 blocks (56.4%), 0 events -2026-02-04T19:17:49.574227Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75580/133889 blocks (56.4%), 0 events -2026-02-04T19:17:49.782494Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75590/133889 blocks (56.5%), 0 events -2026-02-04T19:17:49.991041Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75600/133889 blocks (56.5%), 0 events -2026-02-04T19:17:50.249795Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75610/133889 blocks (56.5%), 0 events -2026-02-04T19:17:50.528801Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75620/133889 blocks (56.5%), 0 events -2026-02-04T19:17:50.569904Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75630/133889 blocks (56.5%), 0 events -2026-02-04T19:17:50.786502Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75640/133889 blocks (56.5%), 0 events -2026-02-04T19:17:51.036130Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75650/133889 blocks (56.5%), 0 events -2026-02-04T19:17:51.246355Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75660/133889 blocks (56.5%), 0 events -2026-02-04T19:17:51.529492Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75670/133889 blocks (56.5%), 0 events -2026-02-04T19:17:51.568889Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75680/133889 blocks (56.5%), 0 events -2026-02-04T19:17:51.761446Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75690/133889 blocks (56.5%), 0 events -2026-02-04T19:17:52.096945Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75700/133889 blocks (56.5%), 0 events -2026-02-04T19:17:52.258368Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75710/133889 blocks (56.5%), 0 events -2026-02-04T19:17:52.394933Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75720/133889 blocks (56.6%), 0 events -2026-02-04T19:17:52.610174Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75730/133889 blocks (56.6%), 0 events -2026-02-04T19:17:52.811861Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75740/133889 blocks (56.6%), 0 events -2026-02-04T19:17:53.106476Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75750/133889 blocks (56.6%), 0 events -2026-02-04T19:17:53.244155Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75760/133889 blocks (56.6%), 0 events -2026-02-04T19:17:53.446904Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75770/133889 blocks (56.6%), 0 events -2026-02-04T19:17:53.666819Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75780/133889 blocks (56.6%), 0 events -2026-02-04T19:17:53.774429Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75790/133889 blocks (56.6%), 0 events -2026-02-04T19:17:54.038104Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75800/133889 blocks (56.6%), 0 events -2026-02-04T19:17:54.186452Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75810/133889 blocks (56.6%), 0 events -2026-02-04T19:17:54.424102Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75820/133889 blocks (56.6%), 0 events -2026-02-04T19:17:54.708525Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75830/133889 blocks (56.6%), 0 events -2026-02-04T19:17:54.819427Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75840/133889 blocks (56.6%), 0 events -2026-02-04T19:17:55.062748Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75850/133889 blocks (56.7%), 0 events -2026-02-04T19:17:55.265141Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75860/133889 blocks (56.7%), 0 events -2026-02-04T19:17:55.420146Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75870/133889 blocks (56.7%), 0 events -2026-02-04T19:17:55.623607Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75880/133889 blocks (56.7%), 0 events -2026-02-04T19:17:55.792532Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75890/133889 blocks (56.7%), 0 events -2026-02-04T19:17:55.974953Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75900/133889 blocks (56.7%), 0 events -2026-02-04T19:17:56.248204Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75910/133889 blocks (56.7%), 0 events -2026-02-04T19:17:56.443252Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75920/133889 blocks (56.7%), 0 events -2026-02-04T19:17:56.609138Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75930/133889 blocks (56.7%), 0 events -2026-02-04T19:17:56.850580Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75940/133889 blocks (56.7%), 0 events -2026-02-04T19:17:57.017442Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75950/133889 blocks (56.7%), 0 events -2026-02-04T19:17:57.191608Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75960/133889 blocks (56.7%), 0 events -2026-02-04T19:17:57.454770Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75970/133889 blocks (56.7%), 0 events -2026-02-04T19:17:57.575697Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75980/133889 blocks (56.7%), 0 events -2026-02-04T19:17:57.861844Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 75990/133889 blocks (56.8%), 0 events -2026-02-04T19:17:58.036985Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76000/133889 blocks (56.8%), 0 events -2026-02-04T19:17:58.224128Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76010/133889 blocks (56.8%), 0 events -2026-02-04T19:17:58.416402Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76020/133889 blocks (56.8%), 0 events -2026-02-04T19:17:58.596068Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76030/133889 blocks (56.8%), 0 events -2026-02-04T19:17:58.764980Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76040/133889 blocks (56.8%), 0 events -2026-02-04T19:17:58.992356Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76050/133889 blocks (56.8%), 0 events -2026-02-04T19:17:59.185415Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76060/133889 blocks (56.8%), 0 events -2026-02-04T19:17:59.424306Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76070/133889 blocks (56.8%), 0 events -2026-02-04T19:17:59.624257Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76080/133889 blocks (56.8%), 0 events -2026-02-04T19:17:59.820759Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76090/133889 blocks (56.8%), 0 events -2026-02-04T19:17:59.998904Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76100/133889 blocks (56.8%), 0 events -2026-02-04T19:18:00.231420Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76110/133889 blocks (56.8%), 0 events -2026-02-04T19:18:00.472279Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76120/133889 blocks (56.9%), 0 events -2026-02-04T19:18:00.592406Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76130/133889 blocks (56.9%), 0 events -2026-02-04T19:18:00.857045Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76140/133889 blocks (56.9%), 0 events -2026-02-04T19:18:00.997386Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76150/133889 blocks (56.9%), 0 events -2026-02-04T19:18:01.171330Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76160/133889 blocks (56.9%), 0 events -2026-02-04T19:18:01.382903Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76170/133889 blocks (56.9%), 0 events -2026-02-04T19:18:01.567353Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76180/133889 blocks (56.9%), 0 events -2026-02-04T19:18:01.815147Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76190/133889 blocks (56.9%), 0 events -2026-02-04T19:18:02.054574Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76200/133889 blocks (56.9%), 0 events -2026-02-04T19:18:02.184037Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76210/133889 blocks (56.9%), 0 events -2026-02-04T19:18:02.415947Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76220/133889 blocks (56.9%), 0 events -2026-02-04T19:18:02.573055Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76230/133889 blocks (56.9%), 0 events -2026-02-04T19:18:02.849118Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76240/133889 blocks (56.9%), 0 events -2026-02-04T19:18:02.969828Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76250/133889 blocks (56.9%), 0 events -2026-02-04T19:18:03.232669Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76260/133889 blocks (57.0%), 0 events -2026-02-04T19:18:03.424058Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76270/133889 blocks (57.0%), 0 events -2026-02-04T19:18:03.655990Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76280/133889 blocks (57.0%), 0 events -2026-02-04T19:18:03.820091Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76290/133889 blocks (57.0%), 0 events -2026-02-04T19:18:03.992361Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76300/133889 blocks (57.0%), 0 events -2026-02-04T19:18:04.226112Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76310/133889 blocks (57.0%), 0 events -2026-02-04T19:18:04.379780Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76320/133889 blocks (57.0%), 0 events -2026-02-04T19:18:04.667348Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76330/133889 blocks (57.0%), 0 events -2026-02-04T19:18:04.839827Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76340/133889 blocks (57.0%), 0 events -2026-02-04T19:18:04.966655Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76350/133889 blocks (57.0%), 0 events -2026-02-04T19:18:05.196023Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76360/133889 blocks (57.0%), 0 events -2026-02-04T19:18:05.449603Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76370/133889 blocks (57.0%), 0 events -2026-02-04T19:18:05.685858Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76380/133889 blocks (57.0%), 0 events -2026-02-04T19:18:05.848325Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76390/133889 blocks (57.1%), 0 events -2026-02-04T19:18:06.058240Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76400/133889 blocks (57.1%), 0 events -2026-02-04T19:18:06.242173Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76410/133889 blocks (57.1%), 0 events -2026-02-04T19:18:06.456506Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76420/133889 blocks (57.1%), 0 events -2026-02-04T19:18:06.635163Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76430/133889 blocks (57.1%), 0 events -2026-02-04T19:18:06.794159Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76440/133889 blocks (57.1%), 0 events -2026-02-04T19:18:06.994682Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76450/133889 blocks (57.1%), 0 events -2026-02-04T19:18:07.258222Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76460/133889 blocks (57.1%), 0 events -2026-02-04T19:18:07.418308Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76470/133889 blocks (57.1%), 0 events -2026-02-04T19:18:07.568686Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76480/133889 blocks (57.1%), 0 events -2026-02-04T19:18:07.813096Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76490/133889 blocks (57.1%), 0 events -2026-02-04T19:18:08.021425Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76500/133889 blocks (57.1%), 0 events -2026-02-04T19:18:08.335535Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76510/133889 blocks (57.1%), 0 events -2026-02-04T19:18:08.368886Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76520/133889 blocks (57.2%), 0 events -2026-02-04T19:18:08.644762Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76530/133889 blocks (57.2%), 0 events -2026-02-04T19:18:08.863286Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76540/133889 blocks (57.2%), 0 events -2026-02-04T19:18:08.993617Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76550/133889 blocks (57.2%), 0 events -2026-02-04T19:18:09.190476Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76560/133889 blocks (57.2%), 0 events -2026-02-04T19:18:09.424045Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76570/133889 blocks (57.2%), 0 events -2026-02-04T19:18:09.609449Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76580/133889 blocks (57.2%), 0 events -2026-02-04T19:18:09.887622Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76590/133889 blocks (57.2%), 0 events -2026-02-04T19:18:09.993425Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76600/133889 blocks (57.2%), 0 events -2026-02-04T19:18:10.254674Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76610/133889 blocks (57.2%), 0 events -2026-02-04T19:18:10.435363Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76620/133889 blocks (57.2%), 0 events -2026-02-04T19:18:10.597041Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76630/133889 blocks (57.2%), 0 events -2026-02-04T19:18:10.788267Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76640/133889 blocks (57.2%), 0 events -2026-02-04T19:18:11.001153Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76650/133889 blocks (57.2%), 0 events -2026-02-04T19:18:11.226271Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76660/133889 blocks (57.3%), 0 events -2026-02-04T19:18:11.449644Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76670/133889 blocks (57.3%), 0 events -2026-02-04T19:18:11.634080Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76680/133889 blocks (57.3%), 0 events -2026-02-04T19:18:11.823614Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76690/133889 blocks (57.3%), 0 events -2026-02-04T19:18:12.008251Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76700/133889 blocks (57.3%), 0 events -2026-02-04T19:18:12.246467Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76710/133889 blocks (57.3%), 0 events -2026-02-04T19:18:12.499837Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76720/133889 blocks (57.3%), 0 events -2026-02-04T19:18:12.574213Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76730/133889 blocks (57.3%), 0 events -2026-02-04T19:18:12.826524Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76740/133889 blocks (57.3%), 0 events -2026-02-04T19:18:13.024909Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76750/133889 blocks (57.3%), 0 events -2026-02-04T19:18:13.224157Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76760/133889 blocks (57.3%), 0 events -2026-02-04T19:18:13.401700Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76770/133889 blocks (57.3%), 0 events -2026-02-04T19:18:13.605804Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76780/133889 blocks (57.3%), 0 events -2026-02-04T19:18:13.775558Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76790/133889 blocks (57.4%), 0 events -2026-02-04T19:18:14.103840Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76800/133889 blocks (57.4%), 0 events -2026-02-04T19:18:14.235903Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76810/133889 blocks (57.4%), 0 events -2026-02-04T19:18:14.422480Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76820/133889 blocks (57.4%), 0 events -2026-02-04T19:18:14.630419Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76830/133889 blocks (57.4%), 0 events -2026-02-04T19:18:14.793610Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76840/133889 blocks (57.4%), 0 events -2026-02-04T19:18:15.000757Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76850/133889 blocks (57.4%), 0 events -2026-02-04T19:18:15.170244Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76860/133889 blocks (57.4%), 0 events -2026-02-04T19:18:15.430110Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76870/133889 blocks (57.4%), 0 events -2026-02-04T19:18:15.644673Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76880/133889 blocks (57.4%), 0 events -2026-02-04T19:18:15.839256Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76890/133889 blocks (57.4%), 0 events -2026-02-04T19:18:15.966682Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76900/133889 blocks (57.4%), 0 events -2026-02-04T19:18:16.204553Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76910/133889 blocks (57.4%), 0 events -2026-02-04T19:18:16.435081Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76920/133889 blocks (57.5%), 0 events -2026-02-04T19:18:16.693039Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76930/133889 blocks (57.5%), 0 events -2026-02-04T19:18:16.783970Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76940/133889 blocks (57.5%), 0 events -2026-02-04T19:18:17.019810Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76950/133889 blocks (57.5%), 0 events -2026-02-04T19:18:17.253821Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76960/133889 blocks (57.5%), 0 events -2026-02-04T19:18:17.387286Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76970/133889 blocks (57.5%), 0 events -2026-02-04T19:18:17.590828Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76980/133889 blocks (57.5%), 0 events -2026-02-04T19:18:17.817147Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 76990/133889 blocks (57.5%), 0 events -2026-02-04T19:18:18.048162Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77000/133889 blocks (57.5%), 0 events -2026-02-04T19:18:18.174150Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77010/133889 blocks (57.5%), 0 events -2026-02-04T19:18:18.427437Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77020/133889 blocks (57.5%), 0 events -2026-02-04T19:18:18.635543Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77030/133889 blocks (57.5%), 0 events -2026-02-04T19:18:18.822217Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77040/133889 blocks (57.5%), 0 events -2026-02-04T19:18:18.992337Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77050/133889 blocks (57.5%), 0 events -2026-02-04T19:18:19.315184Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77060/133889 blocks (57.6%), 0 events -2026-02-04T19:18:19.356289Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77070/133889 blocks (57.6%), 0 events -2026-02-04T19:18:19.611053Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77080/133889 blocks (57.6%), 0 events -2026-02-04T19:18:19.873956Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77090/133889 blocks (57.6%), 0 events -2026-02-04T19:18:20.025506Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77100/133889 blocks (57.6%), 0 events -2026-02-04T19:18:20.232645Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77110/133889 blocks (57.6%), 0 events -2026-02-04T19:18:20.406230Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77120/133889 blocks (57.6%), 0 events -2026-02-04T19:18:20.621714Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77130/133889 blocks (57.6%), 0 events -2026-02-04T19:18:20.888459Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77140/133889 blocks (57.6%), 0 events -2026-02-04T19:18:21.059412Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77150/133889 blocks (57.6%), 0 events -2026-02-04T19:18:21.242372Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77160/133889 blocks (57.6%), 0 events -2026-02-04T19:18:21.446908Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77170/133889 blocks (57.6%), 0 events -2026-02-04T19:18:21.657222Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77180/133889 blocks (57.6%), 0 events -2026-02-04T19:18:21.826992Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77190/133889 blocks (57.7%), 0 events -2026-02-04T19:18:22.015355Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77200/133889 blocks (57.7%), 0 events -2026-02-04T19:18:22.213270Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77210/133889 blocks (57.7%), 0 events -2026-02-04T19:18:22.492903Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77220/133889 blocks (57.7%), 0 events -2026-02-04T19:18:22.592927Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77230/133889 blocks (57.7%), 0 events -2026-02-04T19:18:22.836508Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77240/133889 blocks (57.7%), 0 events -2026-02-04T19:18:23.053432Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77250/133889 blocks (57.7%), 0 events -2026-02-04T19:18:23.194216Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77260/133889 blocks (57.7%), 0 events -2026-02-04T19:18:23.399574Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77270/133889 blocks (57.7%), 0 events -2026-02-04T19:18:23.622327Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77280/133889 blocks (57.7%), 0 events -2026-02-04T19:18:23.796995Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77290/133889 blocks (57.7%), 0 events -2026-02-04T19:18:24.066361Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77300/133889 blocks (57.7%), 0 events -2026-02-04T19:18:24.175776Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77310/133889 blocks (57.7%), 0 events -2026-02-04T19:18:24.395614Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77320/133889 blocks (57.7%), 0 events -2026-02-04T19:18:24.611130Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77330/133889 blocks (57.8%), 0 events -2026-02-04T19:18:24.836767Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77340/133889 blocks (57.8%), 0 events -2026-02-04T19:18:25.081694Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77350/133889 blocks (57.8%), 0 events -2026-02-04T19:18:25.238227Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77360/133889 blocks (57.8%), 0 events -2026-02-04T19:18:25.378356Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77370/133889 blocks (57.8%), 0 events -2026-02-04T19:18:25.641623Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77380/133889 blocks (57.8%), 0 events -2026-02-04T19:18:25.843454Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77390/133889 blocks (57.8%), 0 events -2026-02-04T19:18:26.036798Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77400/133889 blocks (57.8%), 0 events -2026-02-04T19:18:26.259807Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77410/133889 blocks (57.8%), 0 events -2026-02-04T19:18:26.374078Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77420/133889 blocks (57.8%), 0 events -2026-02-04T19:18:26.658176Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77430/133889 blocks (57.8%), 0 events -2026-02-04T19:18:26.838937Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77440/133889 blocks (57.8%), 0 events -2026-02-04T19:18:26.972961Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77450/133889 blocks (57.8%), 0 events -2026-02-04T19:18:27.249393Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77460/133889 blocks (57.9%), 0 events -2026-02-04T19:18:27.449815Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77470/133889 blocks (57.9%), 0 events -2026-02-04T19:18:27.703281Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77480/133889 blocks (57.9%), 0 events -2026-02-04T19:18:27.857633Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77490/133889 blocks (57.9%), 0 events -2026-02-04T19:18:28.054964Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77500/133889 blocks (57.9%), 0 events -2026-02-04T19:18:28.257639Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77510/133889 blocks (57.9%), 0 events -2026-02-04T19:18:28.381489Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77520/133889 blocks (57.9%), 0 events -2026-02-04T19:18:28.634230Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77530/133889 blocks (57.9%), 0 events -2026-02-04T19:18:28.868343Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77540/133889 blocks (57.9%), 0 events -2026-02-04T19:18:29.012466Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77550/133889 blocks (57.9%), 0 events -2026-02-04T19:18:29.316740Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77560/133889 blocks (57.9%), 0 events -2026-02-04T19:18:29.355609Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77570/133889 blocks (57.9%), 0 events -2026-02-04T19:18:29.634500Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77580/133889 blocks (57.9%), 0 events -2026-02-04T19:18:29.836031Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77590/133889 blocks (58.0%), 0 events -2026-02-04T19:18:29.992071Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77600/133889 blocks (58.0%), 0 events -2026-02-04T19:18:30.326718Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77610/133889 blocks (58.0%), 0 events -2026-02-04T19:18:30.369843Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77620/133889 blocks (58.0%), 0 events -2026-02-04T19:18:30.599349Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77630/133889 blocks (58.0%), 0 events -2026-02-04T19:18:30.878226Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77640/133889 blocks (58.0%), 0 events -2026-02-04T19:18:31.057712Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77650/133889 blocks (58.0%), 0 events -2026-02-04T19:18:31.174832Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77660/133889 blocks (58.0%), 0 events -2026-02-04T19:18:31.413156Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77670/133889 blocks (58.0%), 0 events -2026-02-04T19:18:31.651950Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77680/133889 blocks (58.0%), 0 events -2026-02-04T19:18:31.899008Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77690/133889 blocks (58.0%), 0 events -2026-02-04T19:18:32.030060Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77700/133889 blocks (58.0%), 0 events -2026-02-04T19:18:32.163457Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77710/133889 blocks (58.0%), 0 events -2026-02-04T19:18:32.456841Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77720/133889 blocks (58.0%), 0 events -2026-02-04T19:18:32.583212Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77730/133889 blocks (58.1%), 0 events -2026-02-04T19:18:32.764475Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77740/133889 blocks (58.1%), 0 events -2026-02-04T19:18:33.023056Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77750/133889 blocks (58.1%), 0 events -2026-02-04T19:18:33.253704Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77760/133889 blocks (58.1%), 0 events -2026-02-04T19:18:33.510469Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77770/133889 blocks (58.1%), 0 events -2026-02-04T19:18:33.648979Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77780/133889 blocks (58.1%), 0 events -2026-02-04T19:18:33.764953Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77790/133889 blocks (58.1%), 0 events -2026-02-04T19:18:34.022702Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77800/133889 blocks (58.1%), 0 events -2026-02-04T19:18:34.226011Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77810/133889 blocks (58.1%), 0 events -2026-02-04T19:18:34.420534Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77820/133889 blocks (58.1%), 0 events -2026-02-04T19:18:34.605387Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77830/133889 blocks (58.1%), 0 events -2026-02-04T19:18:34.768543Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77840/133889 blocks (58.1%), 0 events -2026-02-04T19:18:35.078940Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77850/133889 blocks (58.1%), 0 events -2026-02-04T19:18:35.277814Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77860/133889 blocks (58.2%), 0 events -2026-02-04T19:18:35.450315Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77870/133889 blocks (58.2%), 0 events -2026-02-04T19:18:35.610615Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77880/133889 blocks (58.2%), 0 events -2026-02-04T19:18:35.976161Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77890/133889 blocks (58.2%), 0 events -2026-02-04T19:18:36.089670Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77900/133889 blocks (58.2%), 0 events -2026-02-04T19:18:36.185666Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77910/133889 blocks (58.2%), 0 events -2026-02-04T19:18:36.383406Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77920/133889 blocks (58.2%), 0 events -2026-02-04T19:18:36.669648Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77930/133889 blocks (58.2%), 0 events -2026-02-04T19:18:36.844807Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77940/133889 blocks (58.2%), 0 events -2026-02-04T19:18:37.008687Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77950/133889 blocks (58.2%), 0 events -2026-02-04T19:18:37.235061Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77960/133889 blocks (58.2%), 0 events -2026-02-04T19:18:37.421747Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77970/133889 blocks (58.2%), 0 events -2026-02-04T19:18:37.565927Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77980/133889 blocks (58.2%), 0 events -2026-02-04T19:18:37.894773Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 77990/133889 blocks (58.2%), 0 events -2026-02-04T19:18:38.058366Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78000/133889 blocks (58.3%), 0 events -2026-02-04T19:18:38.218948Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78010/133889 blocks (58.3%), 0 events -2026-02-04T19:18:38.417154Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78020/133889 blocks (58.3%), 0 events -2026-02-04T19:18:38.600416Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78030/133889 blocks (58.3%), 0 events -2026-02-04T19:18:38.909544Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78040/133889 blocks (58.3%), 0 events -2026-02-04T19:18:38.991773Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78050/133889 blocks (58.3%), 0 events -2026-02-04T19:18:39.269278Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78060/133889 blocks (58.3%), 0 events -2026-02-04T19:18:39.478338Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78070/133889 blocks (58.3%), 0 events -2026-02-04T19:18:39.605979Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78080/133889 blocks (58.3%), 0 events -2026-02-04T19:18:39.800981Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78090/133889 blocks (58.3%), 0 events -2026-02-04T19:18:39.993978Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78100/133889 blocks (58.3%), 0 events -2026-02-04T19:18:40.165733Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78110/133889 blocks (58.3%), 0 events -2026-02-04T19:18:40.372820Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78120/133889 blocks (58.3%), 0 events -2026-02-04T19:18:40.561404Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78130/133889 blocks (58.4%), 0 events -2026-02-04T19:18:40.848127Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78140/133889 blocks (58.4%), 0 events -2026-02-04T19:18:40.997805Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78150/133889 blocks (58.4%), 0 events -2026-02-04T19:18:41.188877Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78160/133889 blocks (58.4%), 0 events -2026-02-04T19:18:41.368212Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78170/133889 blocks (58.4%), 0 events -2026-02-04T19:18:41.589209Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78180/133889 blocks (58.4%), 0 events -2026-02-04T19:18:41.895530Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78190/133889 blocks (58.4%), 0 events -2026-02-04T19:18:41.977975Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78200/133889 blocks (58.4%), 0 events -2026-02-04T19:18:42.168143Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78210/133889 blocks (58.4%), 0 events -2026-02-04T19:18:42.433554Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78220/133889 blocks (58.4%), 0 events -2026-02-04T19:18:42.592703Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78230/133889 blocks (58.4%), 0 events -2026-02-04T19:18:42.800263Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78240/133889 blocks (58.4%), 0 events -2026-02-04T19:18:42.998305Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78250/133889 blocks (58.4%), 0 events -2026-02-04T19:18:43.231574Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78260/133889 blocks (58.5%), 0 events -2026-02-04T19:18:43.473907Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78270/133889 blocks (58.5%), 0 events -2026-02-04T19:18:43.664634Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78280/133889 blocks (58.5%), 0 events -2026-02-04T19:18:43.834328Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78290/133889 blocks (58.5%), 0 events -2026-02-04T19:18:44.004245Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78300/133889 blocks (58.5%), 0 events -2026-02-04T19:18:44.226647Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78310/133889 blocks (58.5%), 0 events -2026-02-04T19:18:44.480584Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78320/133889 blocks (58.5%), 0 events -2026-02-04T19:18:44.677898Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78330/133889 blocks (58.5%), 0 events -2026-02-04T19:18:44.802403Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78340/133889 blocks (58.5%), 0 events -2026-02-04T19:18:45.036831Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78350/133889 blocks (58.5%), 0 events -2026-02-04T19:18:45.233104Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78360/133889 blocks (58.5%), 0 events -2026-02-04T19:18:45.419169Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78370/133889 blocks (58.5%), 0 events -2026-02-04T19:18:45.606053Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78380/133889 blocks (58.5%), 0 events -2026-02-04T19:18:45.785524Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78390/133889 blocks (58.5%), 0 events -2026-02-04T19:18:46.054617Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78400/133889 blocks (58.6%), 0 events -2026-02-04T19:18:46.173080Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78410/133889 blocks (58.6%), 0 events -2026-02-04T19:18:46.446276Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78420/133889 blocks (58.6%), 0 events -2026-02-04T19:18:46.644139Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78430/133889 blocks (58.6%), 0 events -2026-02-04T19:18:46.804626Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78440/133889 blocks (58.6%), 0 events -2026-02-04T19:18:46.974256Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78450/133889 blocks (58.6%), 0 events -2026-02-04T19:18:47.181480Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78460/133889 blocks (58.6%), 0 events -2026-02-04T19:18:47.440855Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78470/133889 blocks (58.6%), 0 events -2026-02-04T19:18:47.665946Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78480/133889 blocks (58.6%), 0 events -2026-02-04T19:18:47.852998Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78490/133889 blocks (58.6%), 0 events -2026-02-04T19:18:48.151837Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78500/133889 blocks (58.6%), 0 events -2026-02-04T19:18:48.195204Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78510/133889 blocks (58.6%), 0 events -2026-02-04T19:18:48.420745Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78520/133889 blocks (58.6%), 0 events -2026-02-04T19:18:48.675199Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78530/133889 blocks (58.7%), 0 events -2026-02-04T19:18:48.837164Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78540/133889 blocks (58.7%), 0 events -2026-02-04T19:18:48.986390Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78550/133889 blocks (58.7%), 0 events -2026-02-04T19:18:49.233070Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78560/133889 blocks (58.7%), 0 events -2026-02-04T19:18:49.409989Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78570/133889 blocks (58.7%), 0 events -2026-02-04T19:18:49.725243Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78580/133889 blocks (58.7%), 0 events -2026-02-04T19:18:49.778168Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78590/133889 blocks (58.7%), 0 events -2026-02-04T19:18:50.018842Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78600/133889 blocks (58.7%), 0 events -2026-02-04T19:18:50.247590Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78610/133889 blocks (58.7%), 0 events -2026-02-04T19:18:50.405481Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78620/133889 blocks (58.7%), 0 events -2026-02-04T19:18:50.608452Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78630/133889 blocks (58.7%), 0 events -2026-02-04T19:18:50.806441Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78640/133889 blocks (58.7%), 0 events -2026-02-04T19:18:51.020051Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78650/133889 blocks (58.7%), 0 events -2026-02-04T19:18:51.203815Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78660/133889 blocks (58.7%), 0 events -2026-02-04T19:18:51.372289Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78670/133889 blocks (58.8%), 0 events -2026-02-04T19:18:51.621302Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78680/133889 blocks (58.8%), 0 events -2026-02-04T19:18:51.852375Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78690/133889 blocks (58.8%), 0 events -2026-02-04T19:18:52.025671Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78700/133889 blocks (58.8%), 0 events -2026-02-04T19:18:52.170210Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78710/133889 blocks (58.8%), 0 events -2026-02-04T19:18:52.427089Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78720/133889 blocks (58.8%), 0 events -2026-02-04T19:18:52.580208Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78730/133889 blocks (58.8%), 0 events -2026-02-04T19:18:52.897313Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78740/133889 blocks (58.8%), 0 events -2026-02-04T19:18:53.096470Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78750/133889 blocks (58.8%), 0 events -2026-02-04T19:18:53.179693Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78760/133889 blocks (58.8%), 0 events -2026-02-04T19:18:53.453839Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78770/133889 blocks (58.8%), 0 events -2026-02-04T19:18:53.622346Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78780/133889 blocks (58.8%), 0 events -2026-02-04T19:18:53.915285Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78790/133889 blocks (58.8%), 0 events -2026-02-04T19:18:53.948590Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78800/133889 blocks (58.9%), 0 events -2026-02-04T19:18:54.242035Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78810/133889 blocks (58.9%), 0 events -2026-02-04T19:18:54.478513Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78820/133889 blocks (58.9%), 0 events -2026-02-04T19:18:54.655736Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78830/133889 blocks (58.9%), 0 events -2026-02-04T19:18:54.846878Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78840/133889 blocks (58.9%), 0 events -2026-02-04T19:18:55.016647Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78850/133889 blocks (58.9%), 0 events -2026-02-04T19:18:55.194869Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78860/133889 blocks (58.9%), 0 events -2026-02-04T19:18:55.366002Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78870/133889 blocks (58.9%), 0 events -2026-02-04T19:18:55.602348Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78880/133889 blocks (58.9%), 0 events -2026-02-04T19:18:55.781254Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78890/133889 blocks (58.9%), 0 events -2026-02-04T19:18:56.050639Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78900/133889 blocks (58.9%), 0 events -2026-02-04T19:18:56.187936Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78910/133889 blocks (58.9%), 0 events -2026-02-04T19:18:56.364626Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78920/133889 blocks (58.9%), 0 events -2026-02-04T19:18:56.617618Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78930/133889 blocks (59.0%), 0 events -2026-02-04T19:18:56.841348Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78940/133889 blocks (59.0%), 0 events -2026-02-04T19:18:57.062868Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78950/133889 blocks (59.0%), 0 events -2026-02-04T19:18:57.257545Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78960/133889 blocks (59.0%), 0 events -2026-02-04T19:18:57.377660Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78970/133889 blocks (59.0%), 0 events -2026-02-04T19:18:57.617817Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78980/133889 blocks (59.0%), 0 events -2026-02-04T19:18:57.764098Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 78990/133889 blocks (59.0%), 0 events -2026-02-04T19:18:58.110194Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79000/133889 blocks (59.0%), 0 events -2026-02-04T19:18:58.307034Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79010/133889 blocks (59.0%), 0 events -2026-02-04T19:18:58.422226Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79020/133889 blocks (59.0%), 0 events -2026-02-04T19:18:58.666129Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79030/133889 blocks (59.0%), 0 events -2026-02-04T19:18:58.860925Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79040/133889 blocks (59.0%), 0 events -2026-02-04T19:18:59.033844Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79050/133889 blocks (59.0%), 0 events -2026-02-04T19:18:59.228441Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79060/133889 blocks (59.0%), 0 events -2026-02-04T19:18:59.387383Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79070/133889 blocks (59.1%), 0 events -2026-02-04T19:18:59.715752Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79080/133889 blocks (59.1%), 0 events -2026-02-04T19:18:59.753806Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79090/133889 blocks (59.1%), 0 events -2026-02-04T19:19:00.007726Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79100/133889 blocks (59.1%), 0 events -2026-02-04T19:19:00.242733Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79110/133889 blocks (59.1%), 0 events -2026-02-04T19:19:00.413709Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79120/133889 blocks (59.1%), 0 events -2026-02-04T19:19:00.586275Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79130/133889 blocks (59.1%), 0 events -2026-02-04T19:19:00.792932Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79140/133889 blocks (59.1%), 0 events -2026-02-04T19:19:01.048618Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79150/133889 blocks (59.1%), 0 events -2026-02-04T19:19:01.306726Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79160/133889 blocks (59.1%), 0 events -2026-02-04T19:19:01.425797Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79170/133889 blocks (59.1%), 0 events -2026-02-04T19:19:01.599287Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79180/133889 blocks (59.1%), 0 events -2026-02-04T19:19:01.826754Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79190/133889 blocks (59.1%), 0 events -2026-02-04T19:19:02.027027Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79200/133889 blocks (59.2%), 0 events -2026-02-04T19:19:02.172187Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79210/133889 blocks (59.2%), 0 events -2026-02-04T19:19:02.406132Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79220/133889 blocks (59.2%), 0 events -2026-02-04T19:19:02.574943Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79230/133889 blocks (59.2%), 0 events -2026-02-04T19:19:02.863070Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79240/133889 blocks (59.2%), 0 events -2026-02-04T19:19:02.964883Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79250/133889 blocks (59.2%), 0 events -2026-02-04T19:19:03.244089Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79260/133889 blocks (59.2%), 0 events -2026-02-04T19:19:03.384287Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79270/133889 blocks (59.2%), 0 events -2026-02-04T19:19:03.652626Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79280/133889 blocks (59.2%), 0 events -2026-02-04T19:19:03.910447Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79290/133889 blocks (59.2%), 0 events -2026-02-04T19:19:03.972475Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79300/133889 blocks (59.2%), 0 events -2026-02-04T19:19:04.191991Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79310/133889 blocks (59.2%), 0 events -2026-02-04T19:19:04.442655Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79320/133889 blocks (59.2%), 0 events -2026-02-04T19:19:04.618620Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79330/133889 blocks (59.3%), 0 events -2026-02-04T19:19:04.804420Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79340/133889 blocks (59.3%), 0 events -2026-02-04T19:19:04.994086Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79350/133889 blocks (59.3%), 0 events -2026-02-04T19:19:05.223982Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79360/133889 blocks (59.3%), 0 events -2026-02-04T19:19:05.488148Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79370/133889 blocks (59.3%), 0 events -2026-02-04T19:19:05.644260Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79380/133889 blocks (59.3%), 0 events -2026-02-04T19:19:05.849233Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79390/133889 blocks (59.3%), 0 events -2026-02-04T19:19:06.025104Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79400/133889 blocks (59.3%), 0 events -2026-02-04T19:19:06.188363Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79410/133889 blocks (59.3%), 0 events -2026-02-04T19:19:06.372872Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79420/133889 blocks (59.3%), 0 events -2026-02-04T19:19:06.600677Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79430/133889 blocks (59.3%), 0 events -2026-02-04T19:19:06.792290Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79440/133889 blocks (59.3%), 0 events -2026-02-04T19:19:07.063165Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79450/133889 blocks (59.3%), 0 events -2026-02-04T19:19:07.245281Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79460/133889 blocks (59.3%), 0 events -2026-02-04T19:19:07.435117Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79470/133889 blocks (59.4%), 0 events -2026-02-04T19:19:07.629895Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79480/133889 blocks (59.4%), 0 events -2026-02-04T19:19:07.773150Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79490/133889 blocks (59.4%), 0 events -2026-02-04T19:19:08.112292Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79500/133889 blocks (59.4%), 0 events -2026-02-04T19:19:08.186388Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79510/133889 blocks (59.4%), 0 events -2026-02-04T19:19:08.399426Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79520/133889 blocks (59.4%), 0 events -2026-02-04T19:19:08.627222Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79530/133889 blocks (59.4%), 0 events -2026-02-04T19:19:08.774225Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79540/133889 blocks (59.4%), 0 events -2026-02-04T19:19:09.005245Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79550/133889 blocks (59.4%), 0 events -2026-02-04T19:19:09.203971Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79560/133889 blocks (59.4%), 0 events -2026-02-04T19:19:09.416663Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79570/133889 blocks (59.4%), 0 events -2026-02-04T19:19:09.681532Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79580/133889 blocks (59.4%), 0 events -2026-02-04T19:19:09.838799Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79590/133889 blocks (59.4%), 0 events -2026-02-04T19:19:10.042321Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79600/133889 blocks (59.5%), 0 events -2026-02-04T19:19:10.209949Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79610/133889 blocks (59.5%), 0 events -2026-02-04T19:19:10.381948Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79620/133889 blocks (59.5%), 0 events -2026-02-04T19:19:10.586379Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79630/133889 blocks (59.5%), 0 events -2026-02-04T19:19:10.836303Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79640/133889 blocks (59.5%), 0 events -2026-02-04T19:19:11.015595Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79650/133889 blocks (59.5%), 0 events -2026-02-04T19:19:11.257108Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79660/133889 blocks (59.5%), 0 events -2026-02-04T19:19:11.416156Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79670/133889 blocks (59.5%), 0 events -2026-02-04T19:19:11.740855Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79680/133889 blocks (59.5%), 0 events -2026-02-04T19:19:11.790805Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79690/133889 blocks (59.5%), 0 events -2026-02-04T19:19:12.057543Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79700/133889 blocks (59.5%), 0 events -2026-02-04T19:19:12.298490Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79710/133889 blocks (59.5%), 0 events -2026-02-04T19:19:12.404053Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79720/133889 blocks (59.5%), 0 events -2026-02-04T19:19:12.575915Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79730/133889 blocks (59.5%), 0 events -2026-02-04T19:19:12.824712Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79740/133889 blocks (59.6%), 0 events -2026-02-04T19:19:13.032339Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79750/133889 blocks (59.6%), 0 events -2026-02-04T19:19:13.217397Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79760/133889 blocks (59.6%), 0 events -2026-02-04T19:19:13.461153Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79770/133889 blocks (59.6%), 0 events -2026-02-04T19:19:13.654803Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79780/133889 blocks (59.6%), 0 events -2026-02-04T19:19:13.872656Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79790/133889 blocks (59.6%), 0 events -2026-02-04T19:19:13.973537Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79800/133889 blocks (59.6%), 0 events -2026-02-04T19:19:14.254497Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79810/133889 blocks (59.6%), 0 events -2026-02-04T19:19:14.413419Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79820/133889 blocks (59.6%), 0 events -2026-02-04T19:19:14.581257Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79830/133889 blocks (59.6%), 0 events -2026-02-04T19:19:14.923647Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79840/133889 blocks (59.6%), 0 events -2026-02-04T19:19:14.964810Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79850/133889 blocks (59.6%), 0 events -2026-02-04T19:19:15.252069Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79860/133889 blocks (59.6%), 0 events -2026-02-04T19:19:15.442561Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79870/133889 blocks (59.7%), 0 events -2026-02-04T19:19:15.614033Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79880/133889 blocks (59.7%), 0 events -2026-02-04T19:19:15.937959Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79890/133889 blocks (59.7%), 0 events -2026-02-04T19:19:15.977593Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79900/133889 blocks (59.7%), 0 events -2026-02-04T19:19:16.186246Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79910/133889 blocks (59.7%), 0 events -2026-02-04T19:19:16.497048Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79920/133889 blocks (59.7%), 0 events -2026-02-04T19:19:16.580924Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79930/133889 blocks (59.7%), 0 events -2026-02-04T19:19:16.776419Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79940/133889 blocks (59.7%), 0 events -2026-02-04T19:19:17.026428Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79950/133889 blocks (59.7%), 0 events -2026-02-04T19:19:17.163553Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79960/133889 blocks (59.7%), 0 events -2026-02-04T19:19:17.509617Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79970/133889 blocks (59.7%), 0 events -2026-02-04T19:19:17.559406Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79980/133889 blocks (59.7%), 0 events -2026-02-04T19:19:17.840245Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 79990/133889 blocks (59.7%), 0 events -2026-02-04T19:19:18.033915Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80000/133889 blocks (59.8%), 0 events -2026-02-04T19:19:18.168432Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80010/133889 blocks (59.8%), 0 events -2026-02-04T19:19:18.416420Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80020/133889 blocks (59.8%), 0 events -2026-02-04T19:19:18.587980Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80030/133889 blocks (59.8%), 0 events -2026-02-04T19:19:18.826816Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80040/133889 blocks (59.8%), 0 events -2026-02-04T19:19:19.111778Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80050/133889 blocks (59.8%), 0 events -2026-02-04T19:19:19.221140Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80060/133889 blocks (59.8%), 0 events -2026-02-04T19:19:19.452889Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80070/133889 blocks (59.8%), 0 events -2026-02-04T19:19:19.642509Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80080/133889 blocks (59.8%), 0 events -2026-02-04T19:19:19.766299Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80090/133889 blocks (59.8%), 0 events -2026-02-04T19:19:20.020161Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80100/133889 blocks (59.8%), 0 events -2026-02-04T19:19:20.212927Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80110/133889 blocks (59.8%), 0 events -2026-02-04T19:19:20.422476Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80120/133889 blocks (59.8%), 0 events -2026-02-04T19:19:20.652644Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80130/133889 blocks (59.8%), 0 events -2026-02-04T19:19:20.824782Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80140/133889 blocks (59.9%), 0 events -2026-02-04T19:19:20.959307Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80150/133889 blocks (59.9%), 0 events -2026-02-04T19:19:21.249263Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80160/133889 blocks (59.9%), 0 events -2026-02-04T19:19:21.456247Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80170/133889 blocks (59.9%), 0 events -2026-02-04T19:19:21.577492Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80180/133889 blocks (59.9%), 0 events -2026-02-04T19:19:21.788693Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80190/133889 blocks (59.9%), 0 events -2026-02-04T19:19:21.995550Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80200/133889 blocks (59.9%), 0 events -2026-02-04T19:19:22.261322Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80210/133889 blocks (59.9%), 0 events -2026-02-04T19:19:22.374797Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80220/133889 blocks (59.9%), 0 events -2026-02-04T19:19:22.596751Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80230/133889 blocks (59.9%), 0 events -2026-02-04T19:19:22.778993Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80240/133889 blocks (59.9%), 0 events -2026-02-04T19:19:23.023252Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80250/133889 blocks (59.9%), 0 events -2026-02-04T19:19:23.273940Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80260/133889 blocks (59.9%), 0 events -2026-02-04T19:19:23.466436Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80270/133889 blocks (60.0%), 0 events -2026-02-04T19:19:23.562933Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80280/133889 blocks (60.0%), 0 events -2026-02-04T19:19:23.860125Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80290/133889 blocks (60.0%), 0 events -2026-02-04T19:19:23.981491Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80300/133889 blocks (60.0%), 0 events -2026-02-04T19:19:24.177473Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80310/133889 blocks (60.0%), 0 events -2026-02-04T19:19:24.381372Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80320/133889 blocks (60.0%), 0 events -2026-02-04T19:19:24.559775Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80330/133889 blocks (60.0%), 0 events -2026-02-04T19:19:24.884724Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80340/133889 blocks (60.0%), 0 events -2026-02-04T19:19:24.990673Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80350/133889 blocks (60.0%), 0 events -2026-02-04T19:19:25.261328Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80360/133889 blocks (60.0%), 0 events -2026-02-04T19:19:25.407912Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80370/133889 blocks (60.0%), 0 events -2026-02-04T19:19:25.612134Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80380/133889 blocks (60.0%), 0 events -2026-02-04T19:19:25.789794Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80390/133889 blocks (60.0%), 0 events -2026-02-04T19:19:26.018189Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80400/133889 blocks (60.0%), 0 events -2026-02-04T19:19:26.184289Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80410/133889 blocks (60.1%), 0 events -2026-02-04T19:19:26.457008Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80420/133889 blocks (60.1%), 0 events -2026-02-04T19:19:26.596251Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80430/133889 blocks (60.1%), 0 events -2026-02-04T19:19:26.789954Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80440/133889 blocks (60.1%), 0 events -2026-02-04T19:19:26.988061Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80450/133889 blocks (60.1%), 0 events -2026-02-04T19:19:27.224733Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80460/133889 blocks (60.1%), 0 events -2026-02-04T19:19:27.510758Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80470/133889 blocks (60.1%), 0 events -2026-02-04T19:19:27.646328Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80480/133889 blocks (60.1%), 0 events -2026-02-04T19:19:27.787451Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80490/133889 blocks (60.1%), 0 events -2026-02-04T19:19:28.026847Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80500/133889 blocks (60.1%), 0 events -2026-02-04T19:19:28.250375Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80510/133889 blocks (60.1%), 0 events -2026-02-04T19:19:28.365970Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80520/133889 blocks (60.1%), 0 events -2026-02-04T19:19:28.609994Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80530/133889 blocks (60.1%), 0 events -2026-02-04T19:19:28.833021Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80540/133889 blocks (60.2%), 0 events -2026-02-04T19:19:29.075854Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80550/133889 blocks (60.2%), 0 events -2026-02-04T19:19:29.203031Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80560/133889 blocks (60.2%), 0 events -2026-02-04T19:19:29.422118Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80570/133889 blocks (60.2%), 0 events -2026-02-04T19:19:29.625883Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80580/133889 blocks (60.2%), 0 events -2026-02-04T19:19:29.783417Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80590/133889 blocks (60.2%), 0 events -2026-02-04T19:19:30.091492Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80600/133889 blocks (60.2%), 0 events -2026-02-04T19:19:30.254121Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80610/133889 blocks (60.2%), 0 events -2026-02-04T19:19:30.382336Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80620/133889 blocks (60.2%), 0 events -2026-02-04T19:19:30.649280Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80630/133889 blocks (60.2%), 0 events -2026-02-04T19:19:30.816094Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80640/133889 blocks (60.2%), 0 events -2026-02-04T19:19:31.025171Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80650/133889 blocks (60.2%), 0 events -2026-02-04T19:19:31.209391Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80660/133889 blocks (60.2%), 0 events -2026-02-04T19:19:31.379593Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80670/133889 blocks (60.3%), 0 events -2026-02-04T19:19:31.664341Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80680/133889 blocks (60.3%), 0 events -2026-02-04T19:19:31.807339Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80690/133889 blocks (60.3%), 0 events -2026-02-04T19:19:31.964418Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80700/133889 blocks (60.3%), 0 events -2026-02-04T19:19:32.233884Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80710/133889 blocks (60.3%), 0 events -2026-02-04T19:19:32.431893Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80720/133889 blocks (60.3%), 0 events -2026-02-04T19:19:32.711028Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80730/133889 blocks (60.3%), 0 events -2026-02-04T19:19:32.783031Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80740/133889 blocks (60.3%), 0 events -2026-02-04T19:19:32.993144Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80750/133889 blocks (60.3%), 0 events -2026-02-04T19:19:33.265858Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80760/133889 blocks (60.3%), 0 events -2026-02-04T19:19:33.411972Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80770/133889 blocks (60.3%), 0 events -2026-02-04T19:19:33.646132Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80780/133889 blocks (60.3%), 0 events -2026-02-04T19:19:33.823530Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80790/133889 blocks (60.3%), 0 events -2026-02-04T19:19:33.974873Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80800/133889 blocks (60.3%), 0 events -2026-02-04T19:19:34.189146Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80810/133889 blocks (60.4%), 0 events -2026-02-04T19:19:34.396027Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80820/133889 blocks (60.4%), 0 events -2026-02-04T19:19:34.585043Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80830/133889 blocks (60.4%), 0 events -2026-02-04T19:19:34.842333Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80840/133889 blocks (60.4%), 0 events -2026-02-04T19:19:34.981019Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80850/133889 blocks (60.4%), 0 events -2026-02-04T19:19:35.333086Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80860/133889 blocks (60.4%), 0 events -2026-02-04T19:19:35.369466Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80870/133889 blocks (60.4%), 0 events -2026-02-04T19:19:35.656227Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80880/133889 blocks (60.4%), 0 events -2026-02-04T19:19:35.856288Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80890/133889 blocks (60.4%), 0 events -2026-02-04T19:19:36.011191Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80900/133889 blocks (60.4%), 0 events -2026-02-04T19:19:36.215713Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80910/133889 blocks (60.4%), 0 events -2026-02-04T19:19:36.419346Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80920/133889 blocks (60.4%), 0 events -2026-02-04T19:19:36.557094Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80930/133889 blocks (60.4%), 0 events -2026-02-04T19:19:36.796372Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80940/133889 blocks (60.5%), 0 events -2026-02-04T19:19:37.026092Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80950/133889 blocks (60.5%), 0 events -2026-02-04T19:19:37.206431Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80960/133889 blocks (60.5%), 0 events -2026-02-04T19:19:37.470452Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80970/133889 blocks (60.5%), 0 events -2026-02-04T19:19:37.615215Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80980/133889 blocks (60.5%), 0 events -2026-02-04T19:19:37.860726Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 80990/133889 blocks (60.5%), 0 events -2026-02-04T19:19:37.989887Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81000/133889 blocks (60.5%), 0 events -2026-02-04T19:19:38.184221Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81010/133889 blocks (60.5%), 0 events -2026-02-04T19:19:38.511884Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81020/133889 blocks (60.5%), 0 events -2026-02-04T19:19:38.619566Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81030/133889 blocks (60.5%), 0 events -2026-02-04T19:19:38.788724Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81040/133889 blocks (60.5%), 0 events -2026-02-04T19:19:39.039639Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81050/133889 blocks (60.5%), 0 events -2026-02-04T19:19:39.204951Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81060/133889 blocks (60.5%), 0 events -2026-02-04T19:19:39.585105Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81070/133889 blocks (60.5%), 0 events -2026-02-04T19:19:39.623271Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81080/133889 blocks (60.6%), 0 events -2026-02-04T19:19:39.808436Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81090/133889 blocks (60.6%), 0 events -2026-02-04T19:19:40.052670Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81100/133889 blocks (60.6%), 0 events -2026-02-04T19:19:40.273661Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81110/133889 blocks (60.6%), 0 events -2026-02-04T19:19:40.427345Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81120/133889 blocks (60.6%), 0 events -2026-02-04T19:19:40.616322Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81130/133889 blocks (60.6%), 0 events -2026-02-04T19:19:40.827372Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81140/133889 blocks (60.6%), 0 events -2026-02-04T19:19:40.974747Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81150/133889 blocks (60.6%), 0 events -2026-02-04T19:19:41.253199Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81160/133889 blocks (60.6%), 0 events -2026-02-04T19:19:41.403867Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81170/133889 blocks (60.6%), 0 events -2026-02-04T19:19:41.661938Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81180/133889 blocks (60.6%), 0 events -2026-02-04T19:19:41.799894Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81190/133889 blocks (60.6%), 0 events -2026-02-04T19:19:41.983062Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81200/133889 blocks (60.6%), 0 events -2026-02-04T19:19:42.209562Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81210/133889 blocks (60.7%), 0 events -2026-02-04T19:19:42.385259Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81220/133889 blocks (60.7%), 0 events -2026-02-04T19:19:42.704721Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81230/133889 blocks (60.7%), 0 events -2026-02-04T19:19:42.806216Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81240/133889 blocks (60.7%), 0 events -2026-02-04T19:19:43.041968Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81250/133889 blocks (60.7%), 0 events -2026-02-04T19:19:43.227094Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81260/133889 blocks (60.7%), 0 events -2026-02-04T19:19:43.454024Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81270/133889 blocks (60.7%), 0 events -2026-02-04T19:19:43.567341Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81280/133889 blocks (60.7%), 0 events -2026-02-04T19:19:43.770189Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81290/133889 blocks (60.7%), 0 events -2026-02-04T19:19:43.980346Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81300/133889 blocks (60.7%), 0 events -2026-02-04T19:19:44.280519Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81310/133889 blocks (60.7%), 0 events -2026-02-04T19:19:44.443985Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81320/133889 blocks (60.7%), 0 events -2026-02-04T19:19:44.563312Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81330/133889 blocks (60.7%), 0 events -2026-02-04T19:19:44.800432Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81340/133889 blocks (60.8%), 0 events -2026-02-04T19:19:44.992585Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81350/133889 blocks (60.8%), 0 events -2026-02-04T19:19:45.178223Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81360/133889 blocks (60.8%), 0 events -2026-02-04T19:19:45.423277Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81370/133889 blocks (60.8%), 0 events -2026-02-04T19:19:45.628643Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81380/133889 blocks (60.8%), 0 events -2026-02-04T19:19:45.882517Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81390/133889 blocks (60.8%), 0 events -2026-02-04T19:19:46.014998Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81400/133889 blocks (60.8%), 0 events -2026-02-04T19:19:46.207581Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81410/133889 blocks (60.8%), 0 events -2026-02-04T19:19:46.445474Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81420/133889 blocks (60.8%), 0 events -2026-02-04T19:19:46.587476Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81430/133889 blocks (60.8%), 0 events -2026-02-04T19:19:46.865809Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81440/133889 blocks (60.8%), 0 events -2026-02-04T19:19:47.031606Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81450/133889 blocks (60.8%), 0 events -2026-02-04T19:19:47.163336Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81460/133889 blocks (60.8%), 0 events -2026-02-04T19:19:47.422375Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81470/133889 blocks (60.8%), 0 events -2026-02-04T19:19:47.616855Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81480/133889 blocks (60.9%), 0 events -2026-02-04T19:19:47.811951Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81490/133889 blocks (60.9%), 0 events -2026-02-04T19:19:47.987564Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81500/133889 blocks (60.9%), 0 events -2026-02-04T19:19:48.252578Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81510/133889 blocks (60.9%), 0 events -2026-02-04T19:19:48.439320Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81520/133889 blocks (60.9%), 0 events -2026-02-04T19:19:48.628866Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81530/133889 blocks (60.9%), 0 events -2026-02-04T19:19:48.781641Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81540/133889 blocks (60.9%), 0 events -2026-02-04T19:19:49.012358Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81550/133889 blocks (60.9%), 0 events -2026-02-04T19:19:49.200787Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81560/133889 blocks (60.9%), 0 events -2026-02-04T19:19:49.490378Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81570/133889 blocks (60.9%), 0 events -2026-02-04T19:19:49.642718Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81580/133889 blocks (60.9%), 0 events -2026-02-04T19:19:49.825178Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81590/133889 blocks (60.9%), 0 events -2026-02-04T19:19:50.045691Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81600/133889 blocks (60.9%), 0 events -2026-02-04T19:19:50.182258Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81610/133889 blocks (61.0%), 0 events -2026-02-04T19:19:50.361677Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81620/133889 blocks (61.0%), 0 events -2026-02-04T19:19:50.653529Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81630/133889 blocks (61.0%), 0 events -2026-02-04T19:19:50.919047Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81640/133889 blocks (61.0%), 0 events -2026-02-04T19:19:50.954072Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81650/133889 blocks (61.0%), 0 events -2026-02-04T19:19:51.236161Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81660/133889 blocks (61.0%), 0 events -2026-02-04T19:19:51.365549Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81670/133889 blocks (61.0%), 0 events -2026-02-04T19:19:51.619246Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81680/133889 blocks (61.0%), 0 events -2026-02-04T19:19:51.848032Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81690/133889 blocks (61.0%), 0 events -2026-02-04T19:19:51.981431Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81700/133889 blocks (61.0%), 0 events -2026-02-04T19:19:52.233541Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81710/133889 blocks (61.0%), 0 events -2026-02-04T19:19:52.371407Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81720/133889 blocks (61.0%), 0 events -2026-02-04T19:19:52.672571Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81730/133889 blocks (61.0%), 0 events -2026-02-04T19:19:52.825967Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81740/133889 blocks (61.1%), 0 events -2026-02-04T19:19:53.007721Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81750/133889 blocks (61.1%), 0 events -2026-02-04T19:19:53.220459Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81760/133889 blocks (61.1%), 0 events -2026-02-04T19:19:53.444086Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81770/133889 blocks (61.1%), 0 events -2026-02-04T19:19:53.681653Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81780/133889 blocks (61.1%), 0 events -2026-02-04T19:19:53.765256Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81790/133889 blocks (61.1%), 0 events -2026-02-04T19:19:54.016004Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81800/133889 blocks (61.1%), 0 events -2026-02-04T19:19:54.237262Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81810/133889 blocks (61.1%), 0 events -2026-02-04T19:19:54.432582Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81820/133889 blocks (61.1%), 0 events -2026-02-04T19:19:54.573317Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81830/133889 blocks (61.1%), 0 events -2026-02-04T19:19:54.841810Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81840/133889 blocks (61.1%), 0 events -2026-02-04T19:19:55.018048Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81850/133889 blocks (61.1%), 0 events -2026-02-04T19:19:55.287862Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81860/133889 blocks (61.1%), 0 events -2026-02-04T19:19:55.377552Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81870/133889 blocks (61.1%), 0 events -2026-02-04T19:19:55.648309Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81880/133889 blocks (61.2%), 0 events -2026-02-04T19:19:55.824202Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81890/133889 blocks (61.2%), 0 events -2026-02-04T19:19:56.033829Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81900/133889 blocks (61.2%), 0 events -2026-02-04T19:19:56.303197Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81910/133889 blocks (61.2%), 0 events -2026-02-04T19:19:56.445461Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81920/133889 blocks (61.2%), 0 events -2026-02-04T19:19:56.594263Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81930/133889 blocks (61.2%), 0 events -2026-02-04T19:19:56.863301Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81940/133889 blocks (61.2%), 0 events -2026-02-04T19:19:57.003554Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81950/133889 blocks (61.2%), 0 events -2026-02-04T19:19:57.196049Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81960/133889 blocks (61.2%), 0 events -2026-02-04T19:19:57.444023Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81970/133889 blocks (61.2%), 0 events -2026-02-04T19:19:57.575236Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81980/133889 blocks (61.2%), 0 events -2026-02-04T19:19:57.876502Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 81990/133889 blocks (61.2%), 0 events -2026-02-04T19:19:58.028519Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82000/133889 blocks (61.2%), 0 events -2026-02-04T19:19:58.169293Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82010/133889 blocks (61.3%), 0 events -2026-02-04T19:19:58.433099Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82020/133889 blocks (61.3%), 0 events -2026-02-04T19:19:58.563479Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82030/133889 blocks (61.3%), 0 events -2026-02-04T19:19:58.783092Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82040/133889 blocks (61.3%), 0 events -2026-02-04T19:19:59.061942Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82050/133889 blocks (61.3%), 0 events -2026-02-04T19:19:59.246636Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82060/133889 blocks (61.3%), 0 events -2026-02-04T19:19:59.448969Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82070/133889 blocks (61.3%), 0 events -2026-02-04T19:19:59.627804Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82080/133889 blocks (61.3%), 0 events -2026-02-04T19:19:59.772759Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82090/133889 blocks (61.3%), 0 events -2026-02-04T19:20:00.020053Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82100/133889 blocks (61.3%), 0 events -2026-02-04T19:20:00.256797Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82110/133889 blocks (61.3%), 0 events -2026-02-04T19:20:00.390224Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82120/133889 blocks (61.3%), 0 events -2026-02-04T19:20:00.661238Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82130/133889 blocks (61.3%), 0 events -2026-02-04T19:20:00.828871Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82140/133889 blocks (61.3%), 0 events -2026-02-04T19:20:01.075335Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82150/133889 blocks (61.4%), 0 events -2026-02-04T19:20:01.186367Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82160/133889 blocks (61.4%), 0 events -2026-02-04T19:20:01.442960Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82170/133889 blocks (61.4%), 0 events -2026-02-04T19:20:01.659794Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82180/133889 blocks (61.4%), 0 events -2026-02-04T19:20:01.796535Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82190/133889 blocks (61.4%), 0 events -2026-02-04T19:20:02.069901Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82200/133889 blocks (61.4%), 0 events -2026-02-04T19:20:02.271256Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82210/133889 blocks (61.4%), 0 events -2026-02-04T19:20:02.415500Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82220/133889 blocks (61.4%), 0 events -2026-02-04T19:20:02.627826Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82230/133889 blocks (61.4%), 0 events -2026-02-04T19:20:02.797236Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82240/133889 blocks (61.4%), 0 events -2026-02-04T19:20:02.965523Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82250/133889 blocks (61.4%), 0 events -2026-02-04T19:20:03.195579Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82260/133889 blocks (61.4%), 0 events -2026-02-04T19:20:03.444982Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82270/133889 blocks (61.4%), 0 events -2026-02-04T19:20:03.644785Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82280/133889 blocks (61.5%), 0 events -2026-02-04T19:20:03.780636Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82290/133889 blocks (61.5%), 0 events -2026-02-04T19:20:04.005608Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82300/133889 blocks (61.5%), 0 events -2026-02-04T19:20:04.236642Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82310/133889 blocks (61.5%), 0 events -2026-02-04T19:20:04.380542Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82320/133889 blocks (61.5%), 0 events -2026-02-04T19:20:04.693989Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82330/133889 blocks (61.5%), 0 events -2026-02-04T19:20:04.835856Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82340/133889 blocks (61.5%), 0 events -2026-02-04T19:20:05.015059Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82350/133889 blocks (61.5%), 0 events -2026-02-04T19:20:05.260146Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82360/133889 blocks (61.5%), 0 events -2026-02-04T19:20:05.414686Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82370/133889 blocks (61.5%), 0 events -2026-02-04T19:20:05.740447Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82380/133889 blocks (61.5%), 0 events -2026-02-04T19:20:05.785722Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82390/133889 blocks (61.5%), 0 events -2026-02-04T19:20:06.046086Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82400/133889 blocks (61.5%), 0 events -2026-02-04T19:20:06.265949Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82410/133889 blocks (61.6%), 0 events -2026-02-04T19:20:06.451320Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82420/133889 blocks (61.6%), 0 events -2026-02-04T19:20:06.652128Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82430/133889 blocks (61.6%), 0 events -2026-02-04T19:20:06.838533Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82440/133889 blocks (61.6%), 0 events -2026-02-04T19:20:07.004574Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82450/133889 blocks (61.6%), 0 events -2026-02-04T19:20:07.348740Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82460/133889 blocks (61.6%), 0 events -2026-02-04T19:20:07.391707Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82470/133889 blocks (61.6%), 0 events -2026-02-04T19:20:07.610077Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82480/133889 blocks (61.6%), 0 events -2026-02-04T19:20:07.837277Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82490/133889 blocks (61.6%), 0 events -2026-02-04T19:20:07.972965Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82500/133889 blocks (61.6%), 0 events -2026-02-04T19:20:08.243772Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82510/133889 blocks (61.6%), 0 events -2026-02-04T19:20:08.393748Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82520/133889 blocks (61.6%), 0 events -2026-02-04T19:20:08.601156Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82530/133889 blocks (61.6%), 0 events -2026-02-04T19:20:08.884611Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82540/133889 blocks (61.6%), 0 events -2026-02-04T19:20:09.021358Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82550/133889 blocks (61.7%), 0 events -2026-02-04T19:20:09.219831Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82560/133889 blocks (61.7%), 0 events -2026-02-04T19:20:09.446509Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82570/133889 blocks (61.7%), 0 events -2026-02-04T19:20:09.576064Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82580/133889 blocks (61.7%), 0 events -2026-02-04T19:20:09.781582Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82590/133889 blocks (61.7%), 0 events -2026-02-04T19:20:10.030019Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82600/133889 blocks (61.7%), 0 events -2026-02-04T19:20:10.276059Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82610/133889 blocks (61.7%), 0 events -2026-02-04T19:20:10.457428Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82620/133889 blocks (61.7%), 0 events -2026-02-04T19:20:10.567497Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82630/133889 blocks (61.7%), 0 events -2026-02-04T19:20:10.854709Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82640/133889 blocks (61.7%), 0 events -2026-02-04T19:20:11.014890Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82650/133889 blocks (61.7%), 0 events -2026-02-04T19:20:11.189619Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82660/133889 blocks (61.7%), 0 events -2026-02-04T19:20:11.506976Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82670/133889 blocks (61.7%), 0 events -2026-02-04T19:20:11.645372Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82680/133889 blocks (61.8%), 0 events -2026-02-04T19:20:11.808283Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82690/133889 blocks (61.8%), 0 events -2026-02-04T19:20:12.070228Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82700/133889 blocks (61.8%), 0 events -2026-02-04T19:20:12.213825Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82710/133889 blocks (61.8%), 0 events -2026-02-04T19:20:12.460544Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82720/133889 blocks (61.8%), 0 events -2026-02-04T19:20:12.635754Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82730/133889 blocks (61.8%), 0 events -2026-02-04T19:20:12.828606Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82740/133889 blocks (61.8%), 0 events -2026-02-04T19:20:12.981021Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82750/133889 blocks (61.8%), 0 events -2026-02-04T19:20:13.189070Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82760/133889 blocks (61.8%), 0 events -2026-02-04T19:20:13.401528Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82770/133889 blocks (61.8%), 0 events -2026-02-04T19:20:13.641419Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82780/133889 blocks (61.8%), 0 events -2026-02-04T19:20:13.828447Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82790/133889 blocks (61.8%), 0 events -2026-02-04T19:20:13.979884Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82800/133889 blocks (61.8%), 0 events -2026-02-04T19:20:14.212152Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82810/133889 blocks (61.8%), 0 events -2026-02-04T19:20:14.390336Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82820/133889 blocks (61.9%), 0 events -2026-02-04T19:20:14.715298Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82830/133889 blocks (61.9%), 0 events -2026-02-04T19:20:14.749724Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82840/133889 blocks (61.9%), 0 events -2026-02-04T19:20:15.042394Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82850/133889 blocks (61.9%), 0 events -2026-02-04T19:20:15.239266Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82860/133889 blocks (61.9%), 0 events -2026-02-04T19:20:15.413557Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82870/133889 blocks (61.9%), 0 events -2026-02-04T19:20:15.702056Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82880/133889 blocks (61.9%), 0 events -2026-02-04T19:20:15.898043Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82890/133889 blocks (61.9%), 0 events -2026-02-04T19:20:16.041828Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82900/133889 blocks (61.9%), 0 events -2026-02-04T19:20:16.256523Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82910/133889 blocks (61.9%), 0 events -2026-02-04T19:20:16.455346Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82920/133889 blocks (61.9%), 0 events -2026-02-04T19:20:16.614052Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82930/133889 blocks (61.9%), 0 events -2026-02-04T19:20:16.784421Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82940/133889 blocks (61.9%), 0 events -2026-02-04T19:20:17.044538Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82950/133889 blocks (62.0%), 0 events -2026-02-04T19:20:17.274730Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82960/133889 blocks (62.0%), 0 events -2026-02-04T19:20:17.514407Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82970/133889 blocks (62.0%), 0 events -2026-02-04T19:20:17.562486Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82980/133889 blocks (62.0%), 0 events -2026-02-04T19:20:17.831354Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 82990/133889 blocks (62.0%), 0 events -2026-02-04T19:20:18.041884Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83000/133889 blocks (62.0%), 0 events -2026-02-04T19:20:18.323192Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83010/133889 blocks (62.0%), 0 events -2026-02-04T19:20:18.409298Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83020/133889 blocks (62.0%), 0 events -2026-02-04T19:20:18.558016Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83030/133889 blocks (62.0%), 0 events -2026-02-04T19:20:18.883513Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83040/133889 blocks (62.0%), 0 events -2026-02-04T19:20:19.081586Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83050/133889 blocks (62.0%), 0 events -2026-02-04T19:20:19.170250Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83060/133889 blocks (62.0%), 0 events -2026-02-04T19:20:19.421965Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83070/133889 blocks (62.0%), 0 events -2026-02-04T19:20:19.619065Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83080/133889 blocks (62.1%), 0 events -2026-02-04T19:20:19.894348Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83090/133889 blocks (62.1%), 0 events -2026-02-04T19:20:19.971615Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83100/133889 blocks (62.1%), 0 events -2026-02-04T19:20:20.455905Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83110/133889 blocks (62.1%), 0 events -2026-02-04T19:20:20.506926Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83120/133889 blocks (62.1%), 0 events -2026-02-04T19:20:20.651088Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83130/133889 blocks (62.1%), 0 events -2026-02-04T19:20:20.825767Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83140/133889 blocks (62.1%), 0 events -2026-02-04T19:20:21.032040Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83150/133889 blocks (62.1%), 0 events -2026-02-04T19:20:21.186527Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83160/133889 blocks (62.1%), 0 events -2026-02-04T19:20:21.469360Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83170/133889 blocks (62.1%), 0 events -2026-02-04T19:20:21.698680Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83180/133889 blocks (62.1%), 0 events -2026-02-04T19:20:21.819772Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83190/133889 blocks (62.1%), 0 events -2026-02-04T19:20:22.024059Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83200/133889 blocks (62.1%), 0 events -2026-02-04T19:20:22.221255Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83210/133889 blocks (62.1%), 0 events -2026-02-04T19:20:22.379668Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83220/133889 blocks (62.2%), 0 events -2026-02-04T19:20:22.598931Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83230/133889 blocks (62.2%), 0 events -2026-02-04T19:20:22.836006Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83240/133889 blocks (62.2%), 0 events -2026-02-04T19:20:23.043950Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83250/133889 blocks (62.2%), 0 events -2026-02-04T19:20:23.237240Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83260/133889 blocks (62.2%), 0 events -2026-02-04T19:20:23.420472Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83270/133889 blocks (62.2%), 0 events -2026-02-04T19:20:23.604652Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83280/133889 blocks (62.2%), 0 events -2026-02-04T19:20:23.827138Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83290/133889 blocks (62.2%), 0 events -2026-02-04T19:20:23.963166Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83300/133889 blocks (62.2%), 0 events -2026-02-04T19:20:24.288520Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83310/133889 blocks (62.2%), 0 events -2026-02-04T19:20:24.401702Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83320/133889 blocks (62.2%), 0 events -2026-02-04T19:20:24.650939Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83330/133889 blocks (62.2%), 0 events -2026-02-04T19:20:24.841929Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83340/133889 blocks (62.2%), 0 events -2026-02-04T19:20:25.044114Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83350/133889 blocks (62.3%), 0 events -2026-02-04T19:20:25.202382Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83360/133889 blocks (62.3%), 0 events -2026-02-04T19:20:25.410915Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83370/133889 blocks (62.3%), 0 events -2026-02-04T19:20:25.703170Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83380/133889 blocks (62.3%), 0 events -2026-02-04T19:20:25.858528Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83390/133889 blocks (62.3%), 0 events -2026-02-04T19:20:25.998824Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83400/133889 blocks (62.3%), 0 events -2026-02-04T19:20:26.227047Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83410/133889 blocks (62.3%), 0 events -2026-02-04T19:20:26.441104Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83420/133889 blocks (62.3%), 0 events -2026-02-04T19:20:26.710645Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83430/133889 blocks (62.3%), 0 events -2026-02-04T19:20:26.809696Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83440/133889 blocks (62.3%), 0 events -2026-02-04T19:20:27.040029Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83450/133889 blocks (62.3%), 0 events -2026-02-04T19:20:27.268724Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83460/133889 blocks (62.3%), 0 events -2026-02-04T19:20:27.462861Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83470/133889 blocks (62.3%), 0 events -2026-02-04T19:20:27.577269Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83480/133889 blocks (62.3%), 0 events -2026-02-04T19:20:27.794536Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83490/133889 blocks (62.4%), 0 events -2026-02-04T19:20:27.990724Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83500/133889 blocks (62.4%), 0 events -2026-02-04T19:20:28.282344Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83510/133889 blocks (62.4%), 0 events -2026-02-04T19:20:28.529001Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83520/133889 blocks (62.4%), 0 events -2026-02-04T19:20:28.570592Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83530/133889 blocks (62.4%), 0 events -2026-02-04T19:20:28.843985Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83540/133889 blocks (62.4%), 0 events -2026-02-04T19:20:29.040039Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83550/133889 blocks (62.4%), 0 events -2026-02-04T19:20:29.169725Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83560/133889 blocks (62.4%), 0 events -2026-02-04T19:20:29.527677Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83570/133889 blocks (62.4%), 0 events -2026-02-04T19:20:29.570606Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83580/133889 blocks (62.4%), 0 events -2026-02-04T19:20:29.856395Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83590/133889 blocks (62.4%), 0 events -2026-02-04T19:20:30.063380Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83600/133889 blocks (62.4%), 0 events -2026-02-04T19:20:30.239722Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83610/133889 blocks (62.4%), 0 events -2026-02-04T19:20:30.413616Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83620/133889 blocks (62.5%), 0 events -2026-02-04T19:20:30.564455Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83630/133889 blocks (62.5%), 0 events -2026-02-04T19:20:30.940509Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83640/133889 blocks (62.5%), 0 events -2026-02-04T19:20:30.980564Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83650/133889 blocks (62.5%), 0 events -2026-02-04T19:20:31.213606Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83660/133889 blocks (62.5%), 0 events -2026-02-04T19:20:31.460912Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83670/133889 blocks (62.5%), 0 events -2026-02-04T19:20:31.645865Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83680/133889 blocks (62.5%), 0 events -2026-02-04T19:20:31.847593Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83690/133889 blocks (62.5%), 0 events -2026-02-04T19:20:32.046744Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83700/133889 blocks (62.5%), 0 events -2026-02-04T19:20:32.245546Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83710/133889 blocks (62.5%), 0 events -2026-02-04T19:20:32.516885Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83720/133889 blocks (62.5%), 0 events -2026-02-04T19:20:32.558226Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83730/133889 blocks (62.5%), 0 events -2026-02-04T19:20:32.810063Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83740/133889 blocks (62.5%), 0 events -2026-02-04T19:20:33.036283Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83750/133889 blocks (62.6%), 0 events -2026-02-04T19:20:33.181840Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83760/133889 blocks (62.6%), 0 events -2026-02-04T19:20:33.413809Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83770/133889 blocks (62.6%), 0 events -2026-02-04T19:20:33.582448Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83780/133889 blocks (62.6%), 0 events -2026-02-04T19:20:34.052453Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83790/133889 blocks (62.6%), 0 events -2026-02-04T19:20:34.091640Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83800/133889 blocks (62.6%), 0 events -2026-02-04T19:20:34.170544Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83810/133889 blocks (62.6%), 0 events -2026-02-04T19:20:34.437978Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83820/133889 blocks (62.6%), 0 events -2026-02-04T19:20:34.612514Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83830/133889 blocks (62.6%), 0 events -2026-02-04T19:20:34.809145Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83840/133889 blocks (62.6%), 0 events -2026-02-04T19:20:34.992671Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83850/133889 blocks (62.6%), 0 events -2026-02-04T19:20:35.246278Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83860/133889 blocks (62.6%), 0 events -2026-02-04T19:20:35.436221Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83870/133889 blocks (62.6%), 0 events -2026-02-04T19:20:35.660970Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83880/133889 blocks (62.6%), 0 events -2026-02-04T19:20:35.847151Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83890/133889 blocks (62.7%), 0 events -2026-02-04T19:20:35.996528Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83900/133889 blocks (62.7%), 0 events -2026-02-04T19:20:36.252666Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83910/133889 blocks (62.7%), 0 events -2026-02-04T19:20:36.457464Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83920/133889 blocks (62.7%), 0 events -2026-02-04T19:20:36.686615Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83930/133889 blocks (62.7%), 0 events -2026-02-04T19:20:36.824498Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83940/133889 blocks (62.7%), 0 events -2026-02-04T19:20:37.071636Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83950/133889 blocks (62.7%), 0 events -2026-02-04T19:20:37.230760Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83960/133889 blocks (62.7%), 0 events -2026-02-04T19:20:37.437839Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83970/133889 blocks (62.7%), 0 events -2026-02-04T19:20:37.720947Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83980/133889 blocks (62.7%), 0 events -2026-02-04T19:20:37.760485Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 83990/133889 blocks (62.7%), 0 events -2026-02-04T19:20:37.978732Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84000/133889 blocks (62.7%), 0 events -2026-02-04T19:20:38.280450Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84010/133889 blocks (62.7%), 0 events -2026-02-04T19:20:38.412422Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84020/133889 blocks (62.8%), 0 events -2026-02-04T19:20:38.592381Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84030/133889 blocks (62.8%), 0 events -2026-02-04T19:20:38.808946Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84040/133889 blocks (62.8%), 0 events -2026-02-04T19:20:38.990969Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84050/133889 blocks (62.8%), 0 events -2026-02-04T19:20:39.165641Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84060/133889 blocks (62.8%), 0 events -2026-02-04T19:20:39.410022Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84070/133889 blocks (62.8%), 0 events -2026-02-04T19:20:39.657226Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84080/133889 blocks (62.8%), 0 events -2026-02-04T19:20:39.853097Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84090/133889 blocks (62.8%), 0 events -2026-02-04T19:20:40.019785Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84100/133889 blocks (62.8%), 0 events -2026-02-04T19:20:40.162782Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84110/133889 blocks (62.8%), 0 events -2026-02-04T19:20:40.372174Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84120/133889 blocks (62.8%), 0 events -2026-02-04T19:20:40.583372Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84130/133889 blocks (62.8%), 0 events -2026-02-04T19:20:40.897451Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84140/133889 blocks (62.8%), 0 events -2026-02-04T19:20:40.986822Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84150/133889 blocks (62.9%), 0 events -2026-02-04T19:20:41.256982Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84160/133889 blocks (62.9%), 0 events -2026-02-04T19:20:41.441226Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84170/133889 blocks (62.9%), 0 events -2026-02-04T19:20:41.566639Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84180/133889 blocks (62.9%), 0 events -2026-02-04T19:20:41.914351Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84190/133889 blocks (62.9%), 0 events -2026-02-04T19:20:41.952092Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84200/133889 blocks (62.9%), 0 events -2026-02-04T19:20:42.170905Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84210/133889 blocks (62.9%), 0 events -2026-02-04T19:20:42.438232Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84220/133889 blocks (62.9%), 0 events -2026-02-04T19:20:42.605651Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84230/133889 blocks (62.9%), 0 events -2026-02-04T19:20:42.831311Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84240/133889 blocks (62.9%), 0 events -2026-02-04T19:20:43.049604Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84250/133889 blocks (62.9%), 0 events -2026-02-04T19:20:43.216258Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84260/133889 blocks (62.9%), 0 events -2026-02-04T19:20:43.364732Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84270/133889 blocks (62.9%), 0 events -2026-02-04T19:20:43.599916Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84280/133889 blocks (62.9%), 0 events -2026-02-04T19:20:43.857000Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84290/133889 blocks (63.0%), 0 events -2026-02-04T19:20:44.052735Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84300/133889 blocks (63.0%), 0 events -2026-02-04T19:20:44.181808Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84310/133889 blocks (63.0%), 0 events -2026-02-04T19:20:44.538875Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84320/133889 blocks (63.0%), 0 events -2026-02-04T19:20:44.579591Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84330/133889 blocks (63.0%), 0 events -2026-02-04T19:20:44.776350Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84340/133889 blocks (63.0%), 0 events -2026-02-04T19:20:45.062448Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84350/133889 blocks (63.0%), 0 events -2026-02-04T19:20:45.234040Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84360/133889 blocks (63.0%), 0 events -2026-02-04T19:20:45.355497Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84370/133889 blocks (63.0%), 0 events -2026-02-04T19:20:45.614715Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84380/133889 blocks (63.0%), 0 events -2026-02-04T19:20:45.835549Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84390/133889 blocks (63.0%), 0 events -2026-02-04T19:20:46.107794Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84400/133889 blocks (63.0%), 0 events -2026-02-04T19:20:46.213918Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84410/133889 blocks (63.0%), 0 events -2026-02-04T19:20:46.412314Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84420/133889 blocks (63.1%), 0 events -2026-02-04T19:20:46.676907Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84430/133889 blocks (63.1%), 0 events -2026-02-04T19:20:46.806901Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84440/133889 blocks (63.1%), 0 events -2026-02-04T19:20:46.962139Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84450/133889 blocks (63.1%), 0 events -2026-02-04T19:20:47.259249Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84460/133889 blocks (63.1%), 0 events -2026-02-04T19:20:47.418471Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84470/133889 blocks (63.1%), 0 events -2026-02-04T19:20:47.579852Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84480/133889 blocks (63.1%), 0 events -2026-02-04T19:20:47.752193Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84490/133889 blocks (63.1%), 0 events -2026-02-04T19:20:47.990233Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84500/133889 blocks (63.1%), 0 events -2026-02-04T19:20:48.238092Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84510/133889 blocks (63.1%), 0 events -2026-02-04T19:20:48.420085Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84520/133889 blocks (63.1%), 0 events -2026-02-04T19:20:48.626147Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84530/133889 blocks (63.1%), 0 events -2026-02-04T19:20:48.763862Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84540/133889 blocks (63.1%), 0 events -2026-02-04T19:20:49.010108Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84550/133889 blocks (63.1%), 0 events -2026-02-04T19:20:49.286945Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84560/133889 blocks (63.2%), 0 events -2026-02-04T19:20:49.350769Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84570/133889 blocks (63.2%), 0 events -2026-02-04T19:20:49.571043Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84580/133889 blocks (63.2%), 0 events -2026-02-04T19:20:49.839383Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84590/133889 blocks (63.2%), 0 events -2026-02-04T19:20:49.970072Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84600/133889 blocks (63.2%), 0 events -2026-02-04T19:20:50.301935Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84610/133889 blocks (63.2%), 0 events -2026-02-04T19:20:50.418749Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84620/133889 blocks (63.2%), 0 events -2026-02-04T19:20:50.647106Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84630/133889 blocks (63.2%), 0 events -2026-02-04T19:20:50.874973Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84640/133889 blocks (63.2%), 0 events -2026-02-04T19:20:50.958215Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84650/133889 blocks (63.2%), 0 events -2026-02-04T19:20:51.193047Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84660/133889 blocks (63.2%), 0 events -2026-02-04T19:20:51.403071Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84670/133889 blocks (63.2%), 0 events -2026-02-04T19:20:51.637082Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84680/133889 blocks (63.2%), 0 events -2026-02-04T19:20:51.913687Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84690/133889 blocks (63.3%), 0 events -2026-02-04T19:20:52.007783Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84700/133889 blocks (63.3%), 0 events -2026-02-04T19:20:52.189677Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84710/133889 blocks (63.3%), 0 events -2026-02-04T19:20:52.432305Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84720/133889 blocks (63.3%), 0 events -2026-02-04T19:20:52.560338Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84730/133889 blocks (63.3%), 0 events -2026-02-04T19:20:52.922122Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84740/133889 blocks (63.3%), 0 events -2026-02-04T19:20:52.956421Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84750/133889 blocks (63.3%), 0 events -2026-02-04T19:20:53.219461Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84760/133889 blocks (63.3%), 0 events -2026-02-04T19:20:53.485784Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84770/133889 blocks (63.3%), 0 events -2026-02-04T19:20:53.652318Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84780/133889 blocks (63.3%), 0 events -2026-02-04T19:20:53.829294Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84790/133889 blocks (63.3%), 0 events -2026-02-04T19:20:54.025230Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84800/133889 blocks (63.3%), 0 events -2026-02-04T19:20:54.235721Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84810/133889 blocks (63.3%), 0 events -2026-02-04T19:20:54.359097Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84820/133889 blocks (63.4%), 0 events -2026-02-04T19:20:54.607236Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84830/133889 blocks (63.4%), 0 events -2026-02-04T19:20:54.833960Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84840/133889 blocks (63.4%), 0 events -2026-02-04T19:20:55.056334Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84850/133889 blocks (63.4%), 0 events -2026-02-04T19:20:55.165985Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84860/133889 blocks (63.4%), 0 events -2026-02-04T19:20:55.449814Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84870/133889 blocks (63.4%), 0 events -2026-02-04T19:20:55.657050Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84880/133889 blocks (63.4%), 0 events -2026-02-04T19:20:55.809477Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84890/133889 blocks (63.4%), 0 events -2026-02-04T19:20:56.070966Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84900/133889 blocks (63.4%), 0 events -2026-02-04T19:20:56.187746Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84910/133889 blocks (63.4%), 0 events -2026-02-04T19:20:56.408789Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84920/133889 blocks (63.4%), 0 events -2026-02-04T19:20:56.628232Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84930/133889 blocks (63.4%), 0 events -2026-02-04T19:20:56.849015Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84940/133889 blocks (63.4%), 0 events -2026-02-04T19:20:57.118392Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84950/133889 blocks (63.4%), 0 events -2026-02-04T19:20:57.161068Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84960/133889 blocks (63.5%), 0 events -2026-02-04T19:20:57.442251Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84970/133889 blocks (63.5%), 0 events -2026-02-04T19:20:57.640693Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84980/133889 blocks (63.5%), 0 events -2026-02-04T19:20:57.856248Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 84990/133889 blocks (63.5%), 0 events -2026-02-04T19:20:57.976142Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85000/133889 blocks (63.5%), 0 events -2026-02-04T19:20:58.240357Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85010/133889 blocks (63.5%), 0 events -2026-02-04T19:20:58.370113Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85020/133889 blocks (63.5%), 0 events -2026-02-04T19:20:58.693372Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85030/133889 blocks (63.5%), 0 events -2026-02-04T19:20:58.853131Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85040/133889 blocks (63.5%), 0 events -2026-02-04T19:20:59.038434Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85050/133889 blocks (63.5%), 0 events -2026-02-04T19:20:59.249597Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85060/133889 blocks (63.5%), 0 events -2026-02-04T19:20:59.447328Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85070/133889 blocks (63.5%), 0 events -2026-02-04T19:20:59.604670Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85080/133889 blocks (63.5%), 0 events -2026-02-04T19:20:59.776281Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85090/133889 blocks (63.6%), 0 events -2026-02-04T19:20:59.992829Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85100/133889 blocks (63.6%), 0 events -2026-02-04T19:21:00.264479Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85110/133889 blocks (63.6%), 0 events -2026-02-04T19:21:00.492453Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85120/133889 blocks (63.6%), 0 events -2026-02-04T19:21:00.564719Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85130/133889 blocks (63.6%), 0 events -2026-02-04T19:21:00.817246Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85140/133889 blocks (63.6%), 0 events -2026-02-04T19:21:01.042622Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85150/133889 blocks (63.6%), 0 events -2026-02-04T19:21:01.183107Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85160/133889 blocks (63.6%), 0 events -2026-02-04T19:21:01.445645Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85170/133889 blocks (63.6%), 0 events -2026-02-04T19:21:01.586147Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85180/133889 blocks (63.6%), 0 events -2026-02-04T19:21:01.869235Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85190/133889 blocks (63.6%), 0 events -2026-02-04T19:21:02.064663Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85200/133889 blocks (63.6%), 0 events -2026-02-04T19:21:02.251568Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85210/133889 blocks (63.6%), 0 events -2026-02-04T19:21:02.425562Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85220/133889 blocks (63.6%), 0 events -2026-02-04T19:21:02.587938Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85230/133889 blocks (63.7%), 0 events -2026-02-04T19:21:02.924851Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85240/133889 blocks (63.7%), 0 events -2026-02-04T19:21:02.966139Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85250/133889 blocks (63.7%), 0 events -2026-02-04T19:21:03.188896Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85260/133889 blocks (63.7%), 0 events -2026-02-04T19:21:03.440425Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85270/133889 blocks (63.7%), 0 events -2026-02-04T19:21:03.644460Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85280/133889 blocks (63.7%), 0 events -2026-02-04T19:21:03.777657Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85290/133889 blocks (63.7%), 0 events -2026-02-04T19:21:04.029879Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85300/133889 blocks (63.7%), 0 events -2026-02-04T19:21:04.250568Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85310/133889 blocks (63.7%), 0 events -2026-02-04T19:21:04.491080Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85320/133889 blocks (63.7%), 0 events -2026-02-04T19:21:04.654891Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85330/133889 blocks (63.7%), 0 events -2026-02-04T19:21:04.847584Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85340/133889 blocks (63.7%), 0 events -2026-02-04T19:21:05.031645Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85350/133889 blocks (63.7%), 0 events -2026-02-04T19:21:05.210310Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85360/133889 blocks (63.8%), 0 events -2026-02-04T19:21:05.389742Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85370/133889 blocks (63.8%), 0 events -2026-02-04T19:21:05.592500Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85380/133889 blocks (63.8%), 0 events -2026-02-04T19:21:05.755137Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85390/133889 blocks (63.8%), 0 events -2026-02-04T19:21:06.067083Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85400/133889 blocks (63.8%), 0 events -2026-02-04T19:21:06.258300Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85410/133889 blocks (63.8%), 0 events -2026-02-04T19:21:06.383040Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85420/133889 blocks (63.8%), 0 events -2026-02-04T19:21:06.603084Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85430/133889 blocks (63.8%), 0 events -2026-02-04T19:21:06.832611Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85440/133889 blocks (63.8%), 0 events -2026-02-04T19:21:07.113014Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85450/133889 blocks (63.8%), 0 events -2026-02-04T19:21:07.317575Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85460/133889 blocks (63.8%), 0 events -2026-02-04T19:21:07.362578Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85470/133889 blocks (63.8%), 0 events -2026-02-04T19:21:07.647288Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85480/133889 blocks (63.8%), 0 events -2026-02-04T19:21:07.832607Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85490/133889 blocks (63.9%), 0 events -2026-02-04T19:21:08.001105Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85500/133889 blocks (63.9%), 0 events -2026-02-04T19:21:08.232443Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85510/133889 blocks (63.9%), 0 events -2026-02-04T19:21:08.373144Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85520/133889 blocks (63.9%), 0 events -2026-02-04T19:21:08.684625Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85530/133889 blocks (63.9%), 0 events -2026-02-04T19:21:08.847523Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85540/133889 blocks (63.9%), 0 events -2026-02-04T19:21:08.968525Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85550/133889 blocks (63.9%), 0 events -2026-02-04T19:21:09.209429Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85560/133889 blocks (63.9%), 0 events -2026-02-04T19:21:09.422077Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85570/133889 blocks (63.9%), 0 events -2026-02-04T19:21:09.581946Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85580/133889 blocks (63.9%), 0 events -2026-02-04T19:21:09.899407Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85590/133889 blocks (63.9%), 0 events -2026-02-04T19:21:10.012081Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85600/133889 blocks (63.9%), 0 events -2026-02-04T19:21:10.260963Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85610/133889 blocks (63.9%), 0 events -2026-02-04T19:21:10.413838Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85620/133889 blocks (63.9%), 0 events -2026-02-04T19:21:10.558677Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85630/133889 blocks (64.0%), 0 events -2026-02-04T19:21:10.794115Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85640/133889 blocks (64.0%), 0 events -2026-02-04T19:21:11.059157Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85650/133889 blocks (64.0%), 0 events -2026-02-04T19:21:11.274865Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85660/133889 blocks (64.0%), 0 events -2026-02-04T19:21:11.382493Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85670/133889 blocks (64.0%), 0 events -2026-02-04T19:21:11.576785Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85680/133889 blocks (64.0%), 0 events -2026-02-04T19:21:11.904776Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85690/133889 blocks (64.0%), 0 events -2026-02-04T19:21:11.974092Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85700/133889 blocks (64.0%), 0 events -2026-02-04T19:21:12.321395Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85710/133889 blocks (64.0%), 0 events -2026-02-04T19:21:12.354744Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85720/133889 blocks (64.0%), 0 events -2026-02-04T19:21:12.653638Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85730/133889 blocks (64.0%), 0 events -2026-02-04T19:21:12.881802Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85740/133889 blocks (64.0%), 0 events -2026-02-04T19:21:13.044534Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85750/133889 blocks (64.0%), 0 events -2026-02-04T19:21:13.172676Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85760/133889 blocks (64.1%), 0 events -2026-02-04T19:21:13.403553Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85770/133889 blocks (64.1%), 0 events -2026-02-04T19:21:13.635505Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85780/133889 blocks (64.1%), 0 events -2026-02-04T19:21:13.793888Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85790/133889 blocks (64.1%), 0 events -2026-02-04T19:21:13.991782Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85800/133889 blocks (64.1%), 0 events -2026-02-04T19:21:14.263434Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85810/133889 blocks (64.1%), 0 events -2026-02-04T19:21:14.419844Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85820/133889 blocks (64.1%), 0 events -2026-02-04T19:21:14.603777Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85830/133889 blocks (64.1%), 0 events -2026-02-04T19:21:14.806727Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85840/133889 blocks (64.1%), 0 events -2026-02-04T19:21:15.018652Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85850/133889 blocks (64.1%), 0 events -2026-02-04T19:21:15.185759Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85860/133889 blocks (64.1%), 0 events -2026-02-04T19:21:15.504680Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85870/133889 blocks (64.1%), 0 events -2026-02-04T19:21:15.569853Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85880/133889 blocks (64.1%), 0 events -2026-02-04T19:21:15.786283Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85890/133889 blocks (64.1%), 0 events -2026-02-04T19:21:16.026302Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85900/133889 blocks (64.2%), 0 events -2026-02-04T19:21:16.221208Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85910/133889 blocks (64.2%), 0 events -2026-02-04T19:21:16.520490Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85920/133889 blocks (64.2%), 0 events -2026-02-04T19:21:16.558166Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85930/133889 blocks (64.2%), 0 events -2026-02-04T19:21:16.810219Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85940/133889 blocks (64.2%), 0 events -2026-02-04T19:21:17.072861Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85950/133889 blocks (64.2%), 0 events -2026-02-04T19:21:17.273299Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85960/133889 blocks (64.2%), 0 events -2026-02-04T19:21:17.449448Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85970/133889 blocks (64.2%), 0 events -2026-02-04T19:21:17.595294Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85980/133889 blocks (64.2%), 0 events -2026-02-04T19:21:17.818741Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 85990/133889 blocks (64.2%), 0 events -2026-02-04T19:21:17.984747Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86000/133889 blocks (64.2%), 0 events -2026-02-04T19:21:18.325648Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86010/133889 blocks (64.2%), 0 events -2026-02-04T19:21:18.361261Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86020/133889 blocks (64.2%), 0 events -2026-02-04T19:21:18.646879Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86030/133889 blocks (64.3%), 0 events -2026-02-04T19:21:18.848479Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86040/133889 blocks (64.3%), 0 events -2026-02-04T19:21:18.982514Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86050/133889 blocks (64.3%), 0 events -2026-02-04T19:21:19.239826Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86060/133889 blocks (64.3%), 0 events -2026-02-04T19:21:19.462452Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86070/133889 blocks (64.3%), 0 events -2026-02-04T19:21:19.695539Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86080/133889 blocks (64.3%), 0 events -2026-02-04T19:21:19.861899Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86090/133889 blocks (64.3%), 0 events -2026-02-04T19:21:19.982250Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86100/133889 blocks (64.3%), 0 events -2026-02-04T19:21:20.223748Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86110/133889 blocks (64.3%), 0 events -2026-02-04T19:21:20.389345Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86120/133889 blocks (64.3%), 0 events -2026-02-04T19:21:20.586153Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86130/133889 blocks (64.3%), 0 events -2026-02-04T19:21:20.776426Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86140/133889 blocks (64.3%), 0 events -2026-02-04T19:21:21.049107Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86150/133889 blocks (64.3%), 0 events -2026-02-04T19:21:21.236461Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86160/133889 blocks (64.4%), 0 events -2026-02-04T19:21:21.469708Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86170/133889 blocks (64.4%), 0 events -2026-02-04T19:21:21.619523Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86180/133889 blocks (64.4%), 0 events -2026-02-04T19:21:21.804317Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86190/133889 blocks (64.4%), 0 events -2026-02-04T19:21:21.989849Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86200/133889 blocks (64.4%), 0 events -2026-02-04T19:21:22.318667Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86210/133889 blocks (64.4%), 0 events -2026-02-04T19:21:22.362919Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86220/133889 blocks (64.4%), 0 events -2026-02-04T19:21:22.579431Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86230/133889 blocks (64.4%), 0 events -2026-02-04T19:21:22.843991Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86240/133889 blocks (64.4%), 0 events -2026-02-04T19:21:22.984802Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86250/133889 blocks (64.4%), 0 events -2026-02-04T19:21:23.210691Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86260/133889 blocks (64.4%), 0 events -2026-02-04T19:21:23.411584Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86270/133889 blocks (64.4%), 0 events -2026-02-04T19:21:23.629848Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86280/133889 blocks (64.4%), 0 events -2026-02-04T19:21:23.888493Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86290/133889 blocks (64.4%), 0 events -2026-02-04T19:21:23.971920Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86300/133889 blocks (64.5%), 0 events -2026-02-04T19:21:24.221679Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86310/133889 blocks (64.5%), 0 events -2026-02-04T19:21:24.431402Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86320/133889 blocks (64.5%), 0 events -2026-02-04T19:21:24.607225Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86330/133889 blocks (64.5%), 0 events -2026-02-04T19:21:24.786225Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86340/133889 blocks (64.5%), 0 events -2026-02-04T19:21:25.036472Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86350/133889 blocks (64.5%), 0 events -2026-02-04T19:21:25.208819Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86360/133889 blocks (64.5%), 0 events -2026-02-04T19:21:25.464884Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86370/133889 blocks (64.5%), 0 events -2026-02-04T19:21:25.644519Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86380/133889 blocks (64.5%), 0 events -2026-02-04T19:21:25.863369Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86390/133889 blocks (64.5%), 0 events -2026-02-04T19:21:25.990171Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86400/133889 blocks (64.5%), 0 events -2026-02-04T19:21:26.161716Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86410/133889 blocks (64.5%), 0 events -2026-02-04T19:21:26.547487Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86420/133889 blocks (64.5%), 0 events -2026-02-04T19:21:26.602471Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86430/133889 blocks (64.6%), 0 events -2026-02-04T19:21:26.789321Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86440/133889 blocks (64.6%), 0 events -2026-02-04T19:21:27.038891Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86450/133889 blocks (64.6%), 0 events -2026-02-04T19:21:27.218615Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86460/133889 blocks (64.6%), 0 events -2026-02-04T19:21:27.381796Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86470/133889 blocks (64.6%), 0 events -2026-02-04T19:21:27.650182Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86480/133889 blocks (64.6%), 0 events -2026-02-04T19:21:27.820550Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86490/133889 blocks (64.6%), 0 events -2026-02-04T19:21:28.049978Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86500/133889 blocks (64.6%), 0 events -2026-02-04T19:21:28.178691Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86510/133889 blocks (64.6%), 0 events -2026-02-04T19:21:28.381710Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86520/133889 blocks (64.6%), 0 events -2026-02-04T19:21:28.645846Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86530/133889 blocks (64.6%), 0 events -2026-02-04T19:21:28.813338Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86540/133889 blocks (64.6%), 0 events -2026-02-04T19:21:28.988696Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86550/133889 blocks (64.6%), 0 events -2026-02-04T19:21:29.224268Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86560/133889 blocks (64.7%), 0 events -2026-02-04T19:21:29.402738Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86570/133889 blocks (64.7%), 0 events -2026-02-04T19:21:29.665332Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86580/133889 blocks (64.7%), 0 events -2026-02-04T19:21:29.810767Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86590/133889 blocks (64.7%), 0 events -2026-02-04T19:21:30.035718Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86600/133889 blocks (64.7%), 0 events -2026-02-04T19:21:30.180397Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86610/133889 blocks (64.7%), 0 events -2026-02-04T19:21:30.446516Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86620/133889 blocks (64.7%), 0 events -2026-02-04T19:21:30.709348Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86630/133889 blocks (64.7%), 0 events -2026-02-04T19:21:30.897959Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86640/133889 blocks (64.7%), 0 events -2026-02-04T19:21:31.030460Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86650/133889 blocks (64.7%), 0 events -2026-02-04T19:21:31.230911Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86660/133889 blocks (64.7%), 0 events -2026-02-04T19:21:31.430063Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86670/133889 blocks (64.7%), 0 events -2026-02-04T19:21:31.580814Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86680/133889 blocks (64.7%), 0 events -2026-02-04T19:21:31.777917Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86690/133889 blocks (64.7%), 0 events -2026-02-04T19:21:32.010803Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86700/133889 blocks (64.8%), 0 events -2026-02-04T19:21:32.281710Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86710/133889 blocks (64.8%), 0 events -2026-02-04T19:21:32.473256Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86720/133889 blocks (64.8%), 0 events -2026-02-04T19:21:32.566651Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86730/133889 blocks (64.8%), 0 events -2026-02-04T19:21:32.801297Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86740/133889 blocks (64.8%), 0 events -2026-02-04T19:21:33.034503Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86750/133889 blocks (64.8%), 0 events -2026-02-04T19:21:33.324962Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86760/133889 blocks (64.8%), 0 events -2026-02-04T19:21:33.359410Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86770/133889 blocks (64.8%), 0 events -2026-02-04T19:21:33.585611Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86780/133889 blocks (64.8%), 0 events -2026-02-04T19:21:33.847635Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86790/133889 blocks (64.8%), 0 events -2026-02-04T19:21:33.965585Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86800/133889 blocks (64.8%), 0 events -2026-02-04T19:21:34.223698Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86810/133889 blocks (64.8%), 0 events -2026-02-04T19:21:34.445222Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86820/133889 blocks (64.8%), 0 events -2026-02-04T19:21:34.588973Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86830/133889 blocks (64.9%), 0 events -2026-02-04T19:21:34.902060Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86840/133889 blocks (64.9%), 0 events -2026-02-04T19:21:35.060066Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86850/133889 blocks (64.9%), 0 events -2026-02-04T19:21:35.225398Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86860/133889 blocks (64.9%), 0 events -2026-02-04T19:21:35.419832Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86870/133889 blocks (64.9%), 0 events -2026-02-04T19:21:35.791769Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86880/133889 blocks (64.9%), 0 events -2026-02-04T19:21:35.912727Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86890/133889 blocks (64.9%), 0 events -2026-02-04T19:21:35.963817Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86900/133889 blocks (64.9%), 0 events -2026-02-04T19:21:36.193207Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86910/133889 blocks (64.9%), 0 events -2026-02-04T19:21:36.441018Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86920/133889 blocks (64.9%), 0 events -2026-02-04T19:21:36.633551Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86930/133889 blocks (64.9%), 0 events -2026-02-04T19:21:36.799908Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86940/133889 blocks (64.9%), 0 events -2026-02-04T19:21:37.014498Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86950/133889 blocks (64.9%), 0 events -2026-02-04T19:21:37.191870Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86960/133889 blocks (64.9%), 0 events -2026-02-04T19:21:37.368475Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86970/133889 blocks (65.0%), 0 events -2026-02-04T19:21:37.719648Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86980/133889 blocks (65.0%), 0 events -2026-02-04T19:21:37.754619Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 86990/133889 blocks (65.0%), 0 events -2026-02-04T19:21:38.042540Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87000/133889 blocks (65.0%), 0 events -2026-02-04T19:21:38.245542Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87010/133889 blocks (65.0%), 0 events -2026-02-04T19:21:38.411285Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87020/133889 blocks (65.0%), 0 events -2026-02-04T19:21:38.568513Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87030/133889 blocks (65.0%), 0 events -2026-02-04T19:21:38.850662Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87040/133889 blocks (65.0%), 0 events -2026-02-04T19:21:39.107209Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87050/133889 blocks (65.0%), 0 events -2026-02-04T19:21:39.254931Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87060/133889 blocks (65.0%), 0 events -2026-02-04T19:21:39.429821Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87070/133889 blocks (65.0%), 0 events -2026-02-04T19:21:39.653900Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87080/133889 blocks (65.0%), 0 events -2026-02-04T19:21:39.814234Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87090/133889 blocks (65.0%), 0 events -2026-02-04T19:21:40.106858Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87100/133889 blocks (65.1%), 0 events -2026-02-04T19:21:40.177062Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87110/133889 blocks (65.1%), 0 events -2026-02-04T19:21:40.412774Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87120/133889 blocks (65.1%), 0 events -2026-02-04T19:21:40.665532Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87130/133889 blocks (65.1%), 0 events -2026-02-04T19:21:40.867465Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87140/133889 blocks (65.1%), 0 events -2026-02-04T19:21:40.958652Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87150/133889 blocks (65.1%), 0 events -2026-02-04T19:21:41.252283Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87160/133889 blocks (65.1%), 0 events -2026-02-04T19:21:41.453544Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87170/133889 blocks (65.1%), 0 events -2026-02-04T19:21:41.713474Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87180/133889 blocks (65.1%), 0 events -2026-02-04T19:21:41.911814Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87190/133889 blocks (65.1%), 0 events -2026-02-04T19:21:42.040782Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87200/133889 blocks (65.1%), 0 events -2026-02-04T19:21:42.242884Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87210/133889 blocks (65.1%), 0 events -2026-02-04T19:21:42.437003Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87220/133889 blocks (65.1%), 0 events -2026-02-04T19:21:42.729777Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87230/133889 blocks (65.2%), 0 events -2026-02-04T19:21:42.771372Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87240/133889 blocks (65.2%), 0 events -2026-02-04T19:21:43.256024Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87250/133889 blocks (65.2%), 0 events -2026-02-04T19:21:43.294606Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87260/133889 blocks (65.2%), 0 events -2026-02-04T19:21:43.483045Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87270/133889 blocks (65.2%), 0 events -2026-02-04T19:21:43.584274Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87280/133889 blocks (65.2%), 0 events -2026-02-04T19:21:43.812662Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87290/133889 blocks (65.2%), 0 events -2026-02-04T19:21:44.007853Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87300/133889 blocks (65.2%), 0 events -2026-02-04T19:21:44.181271Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87310/133889 blocks (65.2%), 0 events -2026-02-04T19:21:44.363071Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87320/133889 blocks (65.2%), 0 events -2026-02-04T19:21:44.639722Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87330/133889 blocks (65.2%), 0 events -2026-02-04T19:21:44.856800Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87340/133889 blocks (65.2%), 0 events -2026-02-04T19:21:45.062770Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87350/133889 blocks (65.2%), 0 events -2026-02-04T19:21:45.243427Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87360/133889 blocks (65.2%), 0 events -2026-02-04T19:21:45.445360Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87370/133889 blocks (65.3%), 0 events -2026-02-04T19:21:45.635202Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87380/133889 blocks (65.3%), 0 events -2026-02-04T19:21:45.912176Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87390/133889 blocks (65.3%), 0 events -2026-02-04T19:21:45.951755Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87400/133889 blocks (65.3%), 0 events -2026-02-04T19:21:46.241016Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87410/133889 blocks (65.3%), 0 events -2026-02-04T19:21:46.432599Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87420/133889 blocks (65.3%), 0 events -2026-02-04T19:21:46.604391Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87430/133889 blocks (65.3%), 0 events -2026-02-04T19:21:46.794342Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87440/133889 blocks (65.3%), 0 events -2026-02-04T19:21:47.065700Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87450/133889 blocks (65.3%), 0 events -2026-02-04T19:21:47.202364Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87460/133889 blocks (65.3%), 0 events -2026-02-04T19:21:47.485351Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87470/133889 blocks (65.3%), 0 events -2026-02-04T19:21:47.595809Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87480/133889 blocks (65.3%), 0 events -2026-02-04T19:21:47.836610Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87490/133889 blocks (65.3%), 0 events -2026-02-04T19:21:48.007132Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87500/133889 blocks (65.4%), 0 events -2026-02-04T19:21:48.201117Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87510/133889 blocks (65.4%), 0 events -2026-02-04T19:21:48.396830Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87520/133889 blocks (65.4%), 0 events -2026-02-04T19:21:48.641778Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87530/133889 blocks (65.4%), 0 events -2026-02-04T19:21:48.856589Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87540/133889 blocks (65.4%), 0 events -2026-02-04T19:21:49.075984Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87550/133889 blocks (65.4%), 0 events -2026-02-04T19:21:49.180231Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87560/133889 blocks (65.4%), 0 events -2026-02-04T19:21:49.396391Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87570/133889 blocks (65.4%), 0 events -2026-02-04T19:21:49.630965Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87580/133889 blocks (65.4%), 0 events -2026-02-04T19:21:49.777385Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87590/133889 blocks (65.4%), 0 events -2026-02-04T19:21:50.103956Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87600/133889 blocks (65.4%), 0 events -2026-02-04T19:21:50.274059Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87610/133889 blocks (65.4%), 0 events -2026-02-04T19:21:50.382488Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87620/133889 blocks (65.4%), 0 events -2026-02-04T19:21:50.632503Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87630/133889 blocks (65.4%), 0 events -2026-02-04T19:21:50.766178Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87640/133889 blocks (65.5%), 0 events -2026-02-04T19:21:50.993879Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87650/133889 blocks (65.5%), 0 events -2026-02-04T19:21:51.244238Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87660/133889 blocks (65.5%), 0 events -2026-02-04T19:21:51.409003Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87670/133889 blocks (65.5%), 0 events -2026-02-04T19:21:51.677655Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87680/133889 blocks (65.5%), 0 events -2026-02-04T19:21:51.847061Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87690/133889 blocks (65.5%), 0 events -2026-02-04T19:21:52.231011Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87700/133889 blocks (65.5%), 0 events -2026-02-04T19:21:52.312623Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87710/133889 blocks (65.5%), 0 events -2026-02-04T19:21:52.388131Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87720/133889 blocks (65.5%), 0 events -2026-02-04T19:21:52.690221Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87730/133889 blocks (65.5%), 0 events -2026-02-04T19:21:52.818889Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87740/133889 blocks (65.5%), 0 events -2026-02-04T19:21:53.013247Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87750/133889 blocks (65.5%), 0 events -2026-02-04T19:21:53.268087Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87760/133889 blocks (65.5%), 0 events -2026-02-04T19:21:53.401100Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87770/133889 blocks (65.6%), 0 events -2026-02-04T19:21:53.739527Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87780/133889 blocks (65.6%), 0 events -2026-02-04T19:21:53.779356Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87790/133889 blocks (65.6%), 0 events -2026-02-04T19:21:53.968663Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87800/133889 blocks (65.6%), 0 events -2026-02-04T19:21:54.263303Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87810/133889 blocks (65.6%), 0 events -2026-02-04T19:21:54.374415Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87820/133889 blocks (65.6%), 0 events -2026-02-04T19:21:54.630442Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87830/133889 blocks (65.6%), 0 events -2026-02-04T19:21:54.838728Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87840/133889 blocks (65.6%), 0 events -2026-02-04T19:21:55.057027Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87850/133889 blocks (65.6%), 0 events -2026-02-04T19:21:55.158752Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87860/133889 blocks (65.6%), 0 events -2026-02-04T19:21:55.442908Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87870/133889 blocks (65.6%), 0 events -2026-02-04T19:21:55.610930Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87880/133889 blocks (65.6%), 0 events -2026-02-04T19:21:55.836505Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87890/133889 blocks (65.6%), 0 events -2026-02-04T19:21:56.040880Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87900/133889 blocks (65.7%), 0 events -2026-02-04T19:21:56.216746Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87910/133889 blocks (65.7%), 0 events -2026-02-04T19:21:56.428351Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87920/133889 blocks (65.7%), 0 events -2026-02-04T19:21:56.661630Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87930/133889 blocks (65.7%), 0 events -2026-02-04T19:21:56.884600Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87940/133889 blocks (65.7%), 0 events -2026-02-04T19:21:57.021311Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87950/133889 blocks (65.7%), 0 events -2026-02-04T19:21:57.218263Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87960/133889 blocks (65.7%), 0 events -2026-02-04T19:21:57.442292Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87970/133889 blocks (65.7%), 0 events -2026-02-04T19:21:57.554606Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87980/133889 blocks (65.7%), 0 events -2026-02-04T19:21:57.767430Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 87990/133889 blocks (65.7%), 0 events -2026-02-04T19:21:58.012823Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88000/133889 blocks (65.7%), 0 events -2026-02-04T19:21:58.213828Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88010/133889 blocks (65.7%), 0 events -2026-02-04T19:21:58.488232Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88020/133889 blocks (65.7%), 0 events -2026-02-04T19:21:58.615063Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88030/133889 blocks (65.7%), 0 events -2026-02-04T19:21:58.834957Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88040/133889 blocks (65.8%), 0 events -2026-02-04T19:21:59.012168Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88050/133889 blocks (65.8%), 0 events -2026-02-04T19:21:59.227136Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88060/133889 blocks (65.8%), 0 events -2026-02-04T19:21:59.398299Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88070/133889 blocks (65.8%), 0 events -2026-02-04T19:21:59.614517Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88080/133889 blocks (65.8%), 0 events -2026-02-04T19:21:59.845538Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88090/133889 blocks (65.8%), 0 events -2026-02-04T19:22:00.109396Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88100/133889 blocks (65.8%), 0 events -2026-02-04T19:22:00.231689Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88110/133889 blocks (65.8%), 0 events -2026-02-04T19:22:00.402306Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88120/133889 blocks (65.8%), 0 events -2026-02-04T19:22:00.617528Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88130/133889 blocks (65.8%), 0 events -2026-02-04T19:22:00.808270Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88140/133889 blocks (65.8%), 0 events -2026-02-04T19:22:01.078086Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88150/133889 blocks (65.8%), 0 events -2026-02-04T19:22:01.271075Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88160/133889 blocks (65.8%), 0 events -2026-02-04T19:22:01.431099Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88170/133889 blocks (65.9%), 0 events -2026-02-04T19:22:01.637928Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88180/133889 blocks (65.9%), 0 events -2026-02-04T19:22:01.810176Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88190/133889 blocks (65.9%), 0 events -2026-02-04T19:22:01.999015Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88200/133889 blocks (65.9%), 0 events -2026-02-04T19:22:02.204705Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88210/133889 blocks (65.9%), 0 events -2026-02-04T19:22:02.435705Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88220/133889 blocks (65.9%), 0 events -2026-02-04T19:22:02.654230Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88230/133889 blocks (65.9%), 0 events -2026-02-04T19:22:02.833894Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88240/133889 blocks (65.9%), 0 events -2026-02-04T19:22:03.031236Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88250/133889 blocks (65.9%), 0 events -2026-02-04T19:22:03.205963Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88260/133889 blocks (65.9%), 0 events -2026-02-04T19:22:03.383486Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88270/133889 blocks (65.9%), 0 events -2026-02-04T19:22:03.698882Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88280/133889 blocks (65.9%), 0 events -2026-02-04T19:22:03.804852Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88290/133889 blocks (65.9%), 0 events -2026-02-04T19:22:03.967319Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88300/133889 blocks (65.9%), 0 events -2026-02-04T19:22:04.264085Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88310/133889 blocks (66.0%), 0 events -2026-02-04T19:22:04.438903Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88320/133889 blocks (66.0%), 0 events -2026-02-04T19:22:04.640863Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88330/133889 blocks (66.0%), 0 events -2026-02-04T19:22:04.833328Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88340/133889 blocks (66.0%), 0 events -2026-02-04T19:22:05.026899Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88350/133889 blocks (66.0%), 0 events -2026-02-04T19:22:05.271802Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88360/133889 blocks (66.0%), 0 events -2026-02-04T19:22:05.433144Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88370/133889 blocks (66.0%), 0 events -2026-02-04T19:22:05.611942Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88380/133889 blocks (66.0%), 0 events -2026-02-04T19:22:05.839501Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88390/133889 blocks (66.0%), 0 events -2026-02-04T19:22:05.985426Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88400/133889 blocks (66.0%), 0 events -2026-02-04T19:22:06.320979Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88410/133889 blocks (66.0%), 0 events -2026-02-04T19:22:06.366067Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88420/133889 blocks (66.0%), 0 events -2026-02-04T19:22:06.625089Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88430/133889 blocks (66.0%), 0 events -2026-02-04T19:22:06.881350Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88440/133889 blocks (66.1%), 0 events -2026-02-04T19:22:06.988436Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88450/133889 blocks (66.1%), 0 events -2026-02-04T19:22:07.168450Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88460/133889 blocks (66.1%), 0 events -2026-02-04T19:22:07.429921Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88470/133889 blocks (66.1%), 0 events -2026-02-04T19:22:07.561166Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88480/133889 blocks (66.1%), 0 events -2026-02-04T19:22:07.893951Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88490/133889 blocks (66.1%), 0 events -2026-02-04T19:22:07.998676Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88500/133889 blocks (66.1%), 0 events -2026-02-04T19:22:08.243616Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88510/133889 blocks (66.1%), 0 events -2026-02-04T19:22:08.450370Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88520/133889 blocks (66.1%), 0 events -2026-02-04T19:22:08.653519Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88530/133889 blocks (66.1%), 0 events -2026-02-04T19:22:08.769691Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88540/133889 blocks (66.1%), 0 events -2026-02-04T19:22:09.042894Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88550/133889 blocks (66.1%), 0 events -2026-02-04T19:22:09.190314Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88560/133889 blocks (66.1%), 0 events -2026-02-04T19:22:09.497964Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88570/133889 blocks (66.2%), 0 events -2026-02-04T19:22:09.578602Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88580/133889 blocks (66.2%), 0 events -2026-02-04T19:22:09.844906Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88590/133889 blocks (66.2%), 0 events -2026-02-04T19:22:10.028373Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88600/133889 blocks (66.2%), 0 events -2026-02-04T19:22:10.189286Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88610/133889 blocks (66.2%), 0 events -2026-02-04T19:22:10.403811Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88620/133889 blocks (66.2%), 0 events -2026-02-04T19:22:10.609151Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88630/133889 blocks (66.2%), 0 events -2026-02-04T19:22:10.784289Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88640/133889 blocks (66.2%), 0 events -2026-02-04T19:22:11.167717Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88650/133889 blocks (66.2%), 0 events -2026-02-04T19:22:11.205223Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88660/133889 blocks (66.2%), 0 events -2026-02-04T19:22:11.383973Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88670/133889 blocks (66.2%), 0 events -2026-02-04T19:22:11.601958Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88680/133889 blocks (66.2%), 0 events -2026-02-04T19:22:11.847633Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88690/133889 blocks (66.2%), 0 events -2026-02-04T19:22:12.122231Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88700/133889 blocks (66.2%), 0 events -2026-02-04T19:22:12.164356Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88710/133889 blocks (66.3%), 0 events -2026-02-04T19:22:12.403879Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88720/133889 blocks (66.3%), 0 events -2026-02-04T19:22:12.648065Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88730/133889 blocks (66.3%), 0 events -2026-02-04T19:22:12.852996Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88740/133889 blocks (66.3%), 0 events -2026-02-04T19:22:12.976178Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88750/133889 blocks (66.3%), 0 events -2026-02-04T19:22:13.167689Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88760/133889 blocks (66.3%), 0 events -2026-02-04T19:22:13.416691Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88770/133889 blocks (66.3%), 0 events -2026-02-04T19:22:13.659823Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88780/133889 blocks (66.3%), 0 events -2026-02-04T19:22:13.803328Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88790/133889 blocks (66.3%), 0 events -2026-02-04T19:22:14.005564Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88800/133889 blocks (66.3%), 0 events -2026-02-04T19:22:14.222801Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88810/133889 blocks (66.3%), 0 events -2026-02-04T19:22:14.394194Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88820/133889 blocks (66.3%), 0 events -2026-02-04T19:22:14.712024Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88830/133889 blocks (66.3%), 0 events -2026-02-04T19:22:14.835091Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88840/133889 blocks (66.4%), 0 events -2026-02-04T19:22:14.961149Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88850/133889 blocks (66.4%), 0 events -2026-02-04T19:22:15.268717Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88860/133889 blocks (66.4%), 0 events -2026-02-04T19:22:15.393758Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88870/133889 blocks (66.4%), 0 events -2026-02-04T19:22:15.573981Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88880/133889 blocks (66.4%), 0 events -2026-02-04T19:22:15.795584Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88890/133889 blocks (66.4%), 0 events -2026-02-04T19:22:15.958137Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88900/133889 blocks (66.4%), 0 events -2026-02-04T19:22:16.280482Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88910/133889 blocks (66.4%), 0 events -2026-02-04T19:22:16.427576Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88920/133889 blocks (66.4%), 0 events -2026-02-04T19:22:16.618204Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88930/133889 blocks (66.4%), 0 events -2026-02-04T19:22:16.857745Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88940/133889 blocks (66.4%), 0 events -2026-02-04T19:22:17.032792Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88950/133889 blocks (66.4%), 0 events -2026-02-04T19:22:17.210124Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88960/133889 blocks (66.4%), 0 events -2026-02-04T19:22:17.376931Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88970/133889 blocks (66.5%), 0 events -2026-02-04T19:22:17.651785Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88980/133889 blocks (66.5%), 0 events -2026-02-04T19:22:17.889761Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 88990/133889 blocks (66.5%), 0 events -2026-02-04T19:22:18.030149Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 89000/133889 blocks (66.5%), 0 events -2026-02-04T19:22:18.245657Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 89010/133889 blocks (66.5%), 0 events -2026-02-04T19:22:18.418612Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 89020/133889 blocks (66.5%), 0 events -2026-02-04T19:22:18.628828Z  INFO verbeth_indexer::indexer::backfill: Backfill progress: 89030/133889 blocks (66.5%), 0 events From c4e67af3f3df4608095c2a144b6fb413b5cef333 Mon Sep 17 00:00:00 2001 From: Marco Esposito Date: Thu, 5 Feb 2026 10:26:33 +0100 Subject: [PATCH 33/51] add env example --- apps/verbeth-indexer/.env.example | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 apps/verbeth-indexer/.env.example diff --git a/apps/verbeth-indexer/.env.example b/apps/verbeth-indexer/.env.example new file mode 100644 index 0000000..898f337 --- /dev/null +++ b/apps/verbeth-indexer/.env.example @@ -0,0 +1,10 @@ +RPC_WS_URL=wss://base-sepolia.g.alchemy.com/v2/YOUR_KEY + +RPC_HTTP_URL=https://base-sepolia.g.alchemy.com/v2/YOUR_KEY +CONTRACT_ADDRESS=0x82C9c5475D63e4C9e959280e9066aBb24973a663 +CREATION_BLOCK=37097547 +DATABASE_PATH=./data/indexer.db +SERVER_PORT=3002 +BACKFILL_DAYS=7 +RETENTION_DAYS=7 +RUST_LOG=info From 498190bb3354cd4446163423bca32130e9e3ea1e Mon Sep 17 00:00:00 2001 From: Marco Esposito Date: Thu, 5 Feb 2026 10:27:03 +0100 Subject: [PATCH 34/51] add env example --- apps/verbeth-indexer/.gitignore | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 apps/verbeth-indexer/.gitignore diff --git a/apps/verbeth-indexer/.gitignore b/apps/verbeth-indexer/.gitignore new file mode 100644 index 0000000..e46d592 --- /dev/null +++ b/apps/verbeth-indexer/.gitignore @@ -0,0 +1,4 @@ +/target/ +/data/ +.env +indexer.log From ecfbc0ab2b7cb6799bec42a94e5b39bd8265e0fd Mon Sep 17 00:00:00 2001 From: Marco Esposito Date: Thu, 5 Feb 2026 17:01:30 +0100 Subject: [PATCH 35/51] rename indexer --- .cluadeignore | 31 ------------ .gitignore | 2 +- apps/indexer/.DS_Store | Bin 0 -> 6148 bytes .../{verbeth-indexer => indexer}/.env.example | 0 apps/{verbeth-indexer => indexer}/.gitignore | 0 apps/{verbeth-indexer => indexer}/Cargo.lock | 2 +- apps/{verbeth-indexer => indexer}/Cargo.toml | 4 +- apps/{verbeth-indexer => indexer}/Dockerfile | 4 +- apps/{verbeth-indexer => indexer}/README.md | 8 ++-- apps/{verbeth-indexer => indexer}/fly.toml | 2 +- .../src/api/health.rs | 0 .../src/api/mod.rs | 0 .../src/api/state.rs | 0 .../src/config.rs | 0 .../src/db/mod.rs | 0 .../src/db/models.rs | 0 .../src/db/queries.rs | 0 .../src/db/schema.rs | 0 .../{verbeth-indexer => indexer}/src/error.rs | 0 .../src/indexer/backfill.rs | 0 .../src/indexer/events.rs | 0 .../src/indexer/mod.rs | 0 .../src/indexer/processor.rs | 0 .../src/indexer/subscriber.rs | 0 apps/{verbeth-indexer => indexer}/src/main.rs | 0 old-plan-docs.md | 44 ++++++++++++++++++ 26 files changed, 55 insertions(+), 42 deletions(-) delete mode 100644 .cluadeignore create mode 100644 apps/indexer/.DS_Store rename apps/{verbeth-indexer => indexer}/.env.example (100%) rename apps/{verbeth-indexer => indexer}/.gitignore (100%) rename apps/{verbeth-indexer => indexer}/Cargo.lock (99%) rename apps/{verbeth-indexer => indexer}/Cargo.toml (93%) rename apps/{verbeth-indexer => indexer}/Dockerfile (73%) rename apps/{verbeth-indexer => indexer}/README.md (84%) rename apps/{verbeth-indexer => indexer}/fly.toml (95%) rename apps/{verbeth-indexer => indexer}/src/api/health.rs (100%) rename apps/{verbeth-indexer => indexer}/src/api/mod.rs (100%) rename apps/{verbeth-indexer => indexer}/src/api/state.rs (100%) rename apps/{verbeth-indexer => indexer}/src/config.rs (100%) rename apps/{verbeth-indexer => indexer}/src/db/mod.rs (100%) rename apps/{verbeth-indexer => indexer}/src/db/models.rs (100%) rename apps/{verbeth-indexer => indexer}/src/db/queries.rs (100%) rename apps/{verbeth-indexer => indexer}/src/db/schema.rs (100%) rename apps/{verbeth-indexer => indexer}/src/error.rs (100%) rename apps/{verbeth-indexer => indexer}/src/indexer/backfill.rs (100%) rename apps/{verbeth-indexer => indexer}/src/indexer/events.rs (100%) rename apps/{verbeth-indexer => indexer}/src/indexer/mod.rs (100%) rename apps/{verbeth-indexer => indexer}/src/indexer/processor.rs (100%) rename apps/{verbeth-indexer => indexer}/src/indexer/subscriber.rs (100%) rename apps/{verbeth-indexer => indexer}/src/main.rs (100%) create mode 100644 old-plan-docs.md diff --git a/.cluadeignore b/.cluadeignore deleted file mode 100644 index 4100e31..0000000 --- a/.cluadeignore +++ /dev/null @@ -1,31 +0,0 @@ -node_modules -.env -dist - -dist - -# Hardhat files -/cache -/artifacts - -# TypeChain files -/typechain -/typechain-types - -# solidity-coverage files -/coverage -/coverage.json - -ignition/deployments/chain-31337 -ignition/deployments/chain-84532 -.aider* -.venv/ -.envrc -.python-version - -*apps/notes/ - -pnpm-lock.yaml -/tests - -README.md \ No newline at end of file diff --git a/.gitignore b/.gitignore index 6cd36d4..74098b0 100644 --- a/.gitignore +++ b/.gitignore @@ -27,4 +27,4 @@ ignition/deployments/chain-84532 .claudeignore *.claude/ CLAUDE.md -old-plan-docs.md \ No newline at end of file +*myplans \ No newline at end of file diff --git a/apps/indexer/.DS_Store b/apps/indexer/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..1a71cb0776ca1e4c312bf3287e5b925ef4942c2c GIT binary patch literal 6148 zcmeH~F$w}f3`G;&La^D=avBfd4F=H@>;+s9Y(zoSdXDZ-CJ2t!BJu;tpJXO1`-+{7 zi0JyZUy1Z0GJ~7S(n4d3ypz3*a+UEuTu#UH>42KmCvn!+@Lrnz*rt#G36KB@kN^q% z5COZlVY7KvMiL+a5_l4@??Zx{=Fn2rKOG1@0zf;I-LUpq0-CG<&7q|#Dlm=dL8DcD z46(YmLsOi~p`~hV7meXV4M3`}dgXhH(h?7~0-B+w9;*1Wg-e+&OK|2Hj6Nq_|Y zjDU8VVY9|d#ohY$dRE^>)z$?L_2URHKLJSWDqg_du%B!J&7q|#Dlq;CI0gn1_$q-1 DiFXpM literal 0 HcmV?d00001 diff --git a/apps/verbeth-indexer/.env.example b/apps/indexer/.env.example similarity index 100% rename from apps/verbeth-indexer/.env.example rename to apps/indexer/.env.example diff --git a/apps/verbeth-indexer/.gitignore b/apps/indexer/.gitignore similarity index 100% rename from apps/verbeth-indexer/.gitignore rename to apps/indexer/.gitignore diff --git a/apps/verbeth-indexer/Cargo.lock b/apps/indexer/Cargo.lock similarity index 99% rename from apps/verbeth-indexer/Cargo.lock rename to apps/indexer/Cargo.lock index e25aa47..1672b59 100644 --- a/apps/verbeth-indexer/Cargo.lock +++ b/apps/indexer/Cargo.lock @@ -3808,7 +3808,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" [[package]] -name = "verbeth-indexer" +name = "indexer" version = "0.1.0" dependencies = [ "alloy", diff --git a/apps/verbeth-indexer/Cargo.toml b/apps/indexer/Cargo.toml similarity index 93% rename from apps/verbeth-indexer/Cargo.toml rename to apps/indexer/Cargo.toml index 4aa5566..501f008 100644 --- a/apps/verbeth-indexer/Cargo.toml +++ b/apps/indexer/Cargo.toml @@ -1,9 +1,9 @@ [package] -name = "verbeth-indexer" +name = "indexer" version = "0.1.0" edition = "2021" rust-version = "1.84" -default-run = "verbeth-indexer" +default-run = "indexer" [dependencies] tokio = { version = "1.43", features = ["full", "signal"] } diff --git a/apps/verbeth-indexer/Dockerfile b/apps/indexer/Dockerfile similarity index 73% rename from apps/verbeth-indexer/Dockerfile rename to apps/indexer/Dockerfile index 39e3798..7b991f8 100644 --- a/apps/verbeth-indexer/Dockerfile +++ b/apps/indexer/Dockerfile @@ -5,8 +5,8 @@ RUN cargo build --release FROM debian:bookworm-slim RUN apt-get update && apt-get install -y ca-certificates && rm -rf /var/lib/apt/lists/* -COPY --from=builder /app/target/release/verbeth-indexer /usr/local/bin/ +COPY --from=builder /app/target/release/indexer /usr/local/bin/ ENV DATABASE_PATH=/data/indexer.db VOLUME ["/data"] EXPOSE 3000 -CMD ["verbeth-indexer"] +CMD ["indexer"] diff --git a/apps/verbeth-indexer/README.md b/apps/indexer/README.md similarity index 84% rename from apps/verbeth-indexer/README.md rename to apps/indexer/README.md index 8d8061b..2dc316c 100644 --- a/apps/verbeth-indexer/README.md +++ b/apps/indexer/README.md @@ -1,6 +1,6 @@ -# Verbeth Indexer +# Indexer -Rust-based event indexer for Verbeth protocol. Listens to on-chain events via WebSocket and persists them in SQLite with stable sequence counters for APSI integration. +Rust-based event indexer. Listens to on-chain events via WebSocket and persists them in SQLite with stable sequence counters for APSI integration. ## Features @@ -58,8 +58,8 @@ Returns indexer status: ### Docker ```bash -docker build -t verbeth-indexer . -docker run -v indexer-data:/data -e RPC_WS_URL=wss://... verbeth-indexer +docker build -t indexer . +docker run -v indexer-data:/data -e RPC_WS_URL=wss://... indexer ``` ### Fly.io diff --git a/apps/verbeth-indexer/fly.toml b/apps/indexer/fly.toml similarity index 95% rename from apps/verbeth-indexer/fly.toml rename to apps/indexer/fly.toml index a2d284e..3c0bcb0 100644 --- a/apps/verbeth-indexer/fly.toml +++ b/apps/indexer/fly.toml @@ -1,4 +1,4 @@ -app = "verbeth-indexer" +app = "indexer" primary_region = "iad" [env] diff --git a/apps/verbeth-indexer/src/api/health.rs b/apps/indexer/src/api/health.rs similarity index 100% rename from apps/verbeth-indexer/src/api/health.rs rename to apps/indexer/src/api/health.rs diff --git a/apps/verbeth-indexer/src/api/mod.rs b/apps/indexer/src/api/mod.rs similarity index 100% rename from apps/verbeth-indexer/src/api/mod.rs rename to apps/indexer/src/api/mod.rs diff --git a/apps/verbeth-indexer/src/api/state.rs b/apps/indexer/src/api/state.rs similarity index 100% rename from apps/verbeth-indexer/src/api/state.rs rename to apps/indexer/src/api/state.rs diff --git a/apps/verbeth-indexer/src/config.rs b/apps/indexer/src/config.rs similarity index 100% rename from apps/verbeth-indexer/src/config.rs rename to apps/indexer/src/config.rs diff --git a/apps/verbeth-indexer/src/db/mod.rs b/apps/indexer/src/db/mod.rs similarity index 100% rename from apps/verbeth-indexer/src/db/mod.rs rename to apps/indexer/src/db/mod.rs diff --git a/apps/verbeth-indexer/src/db/models.rs b/apps/indexer/src/db/models.rs similarity index 100% rename from apps/verbeth-indexer/src/db/models.rs rename to apps/indexer/src/db/models.rs diff --git a/apps/verbeth-indexer/src/db/queries.rs b/apps/indexer/src/db/queries.rs similarity index 100% rename from apps/verbeth-indexer/src/db/queries.rs rename to apps/indexer/src/db/queries.rs diff --git a/apps/verbeth-indexer/src/db/schema.rs b/apps/indexer/src/db/schema.rs similarity index 100% rename from apps/verbeth-indexer/src/db/schema.rs rename to apps/indexer/src/db/schema.rs diff --git a/apps/verbeth-indexer/src/error.rs b/apps/indexer/src/error.rs similarity index 100% rename from apps/verbeth-indexer/src/error.rs rename to apps/indexer/src/error.rs diff --git a/apps/verbeth-indexer/src/indexer/backfill.rs b/apps/indexer/src/indexer/backfill.rs similarity index 100% rename from apps/verbeth-indexer/src/indexer/backfill.rs rename to apps/indexer/src/indexer/backfill.rs diff --git a/apps/verbeth-indexer/src/indexer/events.rs b/apps/indexer/src/indexer/events.rs similarity index 100% rename from apps/verbeth-indexer/src/indexer/events.rs rename to apps/indexer/src/indexer/events.rs diff --git a/apps/verbeth-indexer/src/indexer/mod.rs b/apps/indexer/src/indexer/mod.rs similarity index 100% rename from apps/verbeth-indexer/src/indexer/mod.rs rename to apps/indexer/src/indexer/mod.rs diff --git a/apps/verbeth-indexer/src/indexer/processor.rs b/apps/indexer/src/indexer/processor.rs similarity index 100% rename from apps/verbeth-indexer/src/indexer/processor.rs rename to apps/indexer/src/indexer/processor.rs diff --git a/apps/verbeth-indexer/src/indexer/subscriber.rs b/apps/indexer/src/indexer/subscriber.rs similarity index 100% rename from apps/verbeth-indexer/src/indexer/subscriber.rs rename to apps/indexer/src/indexer/subscriber.rs diff --git a/apps/verbeth-indexer/src/main.rs b/apps/indexer/src/main.rs similarity index 100% rename from apps/verbeth-indexer/src/main.rs rename to apps/indexer/src/main.rs diff --git a/old-plan-docs.md b/old-plan-docs.md new file mode 100644 index 0000000..b2e0ce5 --- /dev/null +++ b/old-plan-docs.md @@ -0,0 +1,44 @@ +# Verbeth SDK Documentation Plan + +### Obiettivo +Creare una documentazione minimale ma funzionale con un quick start efficace che permetta a qualsiasi sviluppatore web3 di integrare Verbeth SDK in pochi minuti. + +--- + +## Struttura Documentazione (Progressive Disclosure) + +``` +docs/ +โ”œโ”€โ”€ quick-start.md โ† Milestone 1 +โ”œโ”€โ”€ concepts/ โ† Milestone 2 +โ”‚ โ”œโ”€โ”€ how-it-works.md +โ”‚ โ”œโ”€โ”€ identity.md +โ”‚ โ”œโ”€โ”€ handshake.md +โ”‚ โ”œโ”€โ”€ ratchet.md +โ”‚ โ””โ”€โ”€ security.md +โ”œโ”€โ”€ guides/ โ† Milestone 3 +โ”‚ โ”œโ”€โ”€ react-integration.md +โ”‚ โ”œโ”€โ”€ storage-adapters.md +โ”‚ โ”œโ”€โ”€ smart-accounts.md +โ”‚ โ””โ”€โ”€ event-listening.md +โ””โ”€โ”€ reference/ โ† Milestone 4 + โ”œโ”€โ”€ api/ + โ”œโ”€โ”€ types/ + โ””โ”€โ”€ constants.md +``` + +--- + +## Note per Milestones Future + +**Milestone 3 (Guides)**: +- React hooks pattern +- Custom storage adapters +- Safe modules integration +- Smart account integration (base smart account executor was predefined but erc4337 infrastrucutre it is a too expensive option for now, for simple messaging) +- Event listening strategies + +**Milestone 4 (Reference)**: +- Auto-generated API docs +- Type definitions +- Contract ABIs From b5a35128d87632b0b58da6054d2b440498ca04c3 Mon Sep 17 00:00:00 2001 From: Marco Esposito Date: Thu, 5 Feb 2026 17:02:16 +0100 Subject: [PATCH 36/51] rename indexer --- old-plan-docs.md | 44 -------------------------------------------- 1 file changed, 44 deletions(-) delete mode 100644 old-plan-docs.md diff --git a/old-plan-docs.md b/old-plan-docs.md deleted file mode 100644 index b2e0ce5..0000000 --- a/old-plan-docs.md +++ /dev/null @@ -1,44 +0,0 @@ -# Verbeth SDK Documentation Plan - -### Obiettivo -Creare una documentazione minimale ma funzionale con un quick start efficace che permetta a qualsiasi sviluppatore web3 di integrare Verbeth SDK in pochi minuti. - ---- - -## Struttura Documentazione (Progressive Disclosure) - -``` -docs/ -โ”œโ”€โ”€ quick-start.md โ† Milestone 1 -โ”œโ”€โ”€ concepts/ โ† Milestone 2 -โ”‚ โ”œโ”€โ”€ how-it-works.md -โ”‚ โ”œโ”€โ”€ identity.md -โ”‚ โ”œโ”€โ”€ handshake.md -โ”‚ โ”œโ”€โ”€ ratchet.md -โ”‚ โ””โ”€โ”€ security.md -โ”œโ”€โ”€ guides/ โ† Milestone 3 -โ”‚ โ”œโ”€โ”€ react-integration.md -โ”‚ โ”œโ”€โ”€ storage-adapters.md -โ”‚ โ”œโ”€โ”€ smart-accounts.md -โ”‚ โ””โ”€โ”€ event-listening.md -โ””โ”€โ”€ reference/ โ† Milestone 4 - โ”œโ”€โ”€ api/ - โ”œโ”€โ”€ types/ - โ””โ”€โ”€ constants.md -``` - ---- - -## Note per Milestones Future - -**Milestone 3 (Guides)**: -- React hooks pattern -- Custom storage adapters -- Safe modules integration -- Smart account integration (base smart account executor was predefined but erc4337 infrastrucutre it is a too expensive option for now, for simple messaging) -- Event listening strategies - -**Milestone 4 (Reference)**: -- Auto-generated API docs -- Type definitions -- Contract ABIs From 0456093bd6bbcea0969eaafaccac6cf54e4677ae Mon Sep 17 00:00:00 2001 From: Marco Esposito Date: Fri, 6 Feb 2026 09:57:37 +0100 Subject: [PATCH 37/51] fix security bugs --- apps/indexer/Cargo.lock | 46 +++---- apps/indexer/fly.toml | 4 +- apps/indexer/src/config.rs | 26 +++- apps/indexer/src/db/mod.rs | 14 +- apps/indexer/src/db/queries.rs | 44 +++++-- apps/indexer/src/error.rs | 3 + apps/indexer/src/indexer/mod.rs | 1 + apps/indexer/src/indexer/processor.rs | 61 ++++++++- apps/indexer/src/indexer/retry_queue.rs | 83 ++++++++++++ apps/indexer/src/indexer/subscriber.rs | 163 ++++++++++++++++++++++-- apps/indexer/src/main.rs | 7 +- 11 files changed, 391 insertions(+), 61 deletions(-) create mode 100644 apps/indexer/src/indexer/retry_queue.rs diff --git a/apps/indexer/Cargo.lock b/apps/indexer/Cargo.lock index 1672b59..2bbb1c6 100644 --- a/apps/indexer/Cargo.lock +++ b/apps/indexer/Cargo.lock @@ -1986,6 +1986,29 @@ dependencies = [ "syn 2.0.114", ] +[[package]] +name = "indexer" +version = "0.1.0" +dependencies = [ + "alloy", + "axum", + "dotenvy", + "futures-lite", + "governor", + "hex", + "nonzero_ext", + "r2d2", + "r2d2_sqlite", + "rusqlite", + "serde", + "serde_json", + "thiserror 2.0.18", + "tokio", + "tower-http", + "tracing", + "tracing-subscriber", +] + [[package]] name = "indexmap" version = "2.13.0" @@ -3807,29 +3830,6 @@ version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" -[[package]] -name = "indexer" -version = "0.1.0" -dependencies = [ - "alloy", - "axum", - "dotenvy", - "futures-lite", - "governor", - "hex", - "nonzero_ext", - "r2d2", - "r2d2_sqlite", - "rusqlite", - "serde", - "serde_json", - "thiserror 2.0.18", - "tokio", - "tower-http", - "tracing", - "tracing-subscriber", -] - [[package]] name = "version_check" version = "0.9.5" diff --git a/apps/indexer/fly.toml b/apps/indexer/fly.toml index 3c0bcb0..faec29f 100644 --- a/apps/indexer/fly.toml +++ b/apps/indexer/fly.toml @@ -3,12 +3,12 @@ primary_region = "iad" [env] RUST_LOG = "info" - SERVER_PORT = "3000" + SERVER_PORT = "3002" CONTRACT_ADDRESS = "0x82C9c5475D63e4C9e959280e9066aBb24973a663" CREATION_BLOCK = "37097547" [http_service] - internal_port = 3000 + internal_port = 3002 force_https = true min_machines_running = 1 diff --git a/apps/indexer/src/config.rs b/apps/indexer/src/config.rs index d3d0923..21ead80 100644 --- a/apps/indexer/src/config.rs +++ b/apps/indexer/src/config.rs @@ -3,6 +3,19 @@ use std::str::FromStr; use crate::error::{IndexerError, Result}; +/// Sanitize RPC URL by masking API keys. +/// Common patterns: .../v2/abc123 (Alchemy), .../v3/abc123 (Infura) +pub fn sanitize_rpc_url(url: &str) -> String { + if let Some(idx) = url.rfind('/') { + let (base, key) = url.split_at(idx + 1); + // API keys are typically long alphanumeric strings without dots or slashes + if key.len() > 8 && !key.contains('.') && !key.contains('/') { + return format!("{}***", base); + } + } + url.to_string() +} + #[allow(dead_code)] pub struct Config { pub rpc_ws_url: String, @@ -14,6 +27,8 @@ pub struct Config { pub backfill_days: u32, pub retention_days: u32, pub rpc_chunk_size: u64, + /// SQLite synchronous mode: "OFF", "NORMAL", or "FULL" (default: NORMAL) + pub sqlite_sync_mode: String, } impl Config { @@ -39,7 +54,7 @@ impl Config { .unwrap_or_else(|_| "./data/indexer.db".into()); let server_port = std::env::var("SERVER_PORT") - .unwrap_or_else(|_| "3000".into()) + .unwrap_or_else(|_| "3002".into()) .parse::() .map_err(|e| IndexerError::Config(format!("Invalid SERVER_PORT: {e}")))?; @@ -59,6 +74,14 @@ impl Config { .parse::() .map_err(|e| IndexerError::Config(format!("Invalid RPC_CHUNK_SIZE: {e}")))?; + // SQLite sync mode: NORMAL (default), FULL for extra local durability + let sqlite_sync_mode = std::env::var("SQLITE_SYNC_MODE").unwrap_or_else(|_| "NORMAL".into()); + if !["OFF", "NORMAL", "FULL"].contains(&sqlite_sync_mode.as_str()) { + return Err(IndexerError::Config(format!( + "Invalid SQLITE_SYNC_MODE: {sqlite_sync_mode} (expected OFF, NORMAL, or FULL)" + ))); + } + Ok(Self { rpc_ws_url, rpc_http_url, @@ -69,6 +92,7 @@ impl Config { backfill_days, retention_days, rpc_chunk_size, + sqlite_sync_mode, }) } } diff --git a/apps/indexer/src/db/mod.rs b/apps/indexer/src/db/mod.rs index 589f477..b9ca717 100644 --- a/apps/indexer/src/db/mod.rs +++ b/apps/indexer/src/db/mod.rs @@ -10,7 +10,7 @@ pub mod schema; pub type DbPool = Pool; -pub fn create_pool(database_path: &str) -> Result { +pub fn create_pool(database_path: &str, sync_mode: &str) -> Result { if let Some(parent) = Path::new(database_path).parent() { std::fs::create_dir_all(parent).ok(); } @@ -19,11 +19,13 @@ pub fn create_pool(database_path: &str) -> Result { let pool = Pool::builder().max_size(4).build(manager)?; let conn = pool.get()?; - conn.execute_batch( - "PRAGMA journal_mode=WAL; - PRAGMA synchronous=NORMAL; - PRAGMA foreign_keys=ON;", - )?; + let pragmas = format!( + "PRAGMA journal_mode=WAL; PRAGMA synchronous={}; PRAGMA foreign_keys=ON;", + sync_mode + ); + conn.execute_batch(&pragmas)?; + + tracing::info!("SQLite initialized with synchronous={}", sync_mode); schema::run_migrations(&conn)?; diff --git a/apps/indexer/src/db/queries.rs b/apps/indexer/src/db/queries.rs index 830e541..e347c15 100644 --- a/apps/indexer/src/db/queries.rs +++ b/apps/indexer/src/db/queries.rs @@ -9,22 +9,38 @@ pub fn get_and_increment_seq( key_type: &str, key_hash: Option<&[u8; 32]>, ) -> Result { - let seq: i64 = conn - .query_row( - "SELECT next_seq FROM seq_counters WHERE key_type = ?1 AND key_hash IS ?2", - params![key_type, key_hash.map(|h| h.as_slice())], - |row| row.get(0), - ) - .optional()? - .unwrap_or(0); + // BEGIN IMMEDIATE acquires write lock immediately, preventing race conditions + conn.execute("BEGIN IMMEDIATE", [])?; - conn.execute( - "INSERT INTO seq_counters (key_type, key_hash, next_seq) VALUES (?1, ?2, ?3) - ON CONFLICT(key_type, key_hash) DO UPDATE SET next_seq = ?3", - params![key_type, key_hash.map(|h| h.as_slice()), seq + 1], - )?; + let result = (|| -> Result { + let seq: i64 = conn + .query_row( + "SELECT next_seq FROM seq_counters WHERE key_type = ?1 AND key_hash IS ?2", + params![key_type, key_hash.map(|h| h.as_slice())], + |row| row.get(0), + ) + .optional()? + .unwrap_or(0); + + conn.execute( + "INSERT INTO seq_counters (key_type, key_hash, next_seq) VALUES (?1, ?2, ?3) + ON CONFLICT(key_type, key_hash) DO UPDATE SET next_seq = ?3", + params![key_type, key_hash.map(|h| h.as_slice()), seq + 1], + )?; + + Ok(seq) + })(); + + match &result { + Ok(_) => { + conn.execute("COMMIT", [])?; + } + Err(_) => { + let _ = conn.execute("ROLLBACK", []); + } + } - Ok(seq) + result } pub fn insert_message(conn: &Connection, row: &MessageRow) -> Result { diff --git a/apps/indexer/src/error.rs b/apps/indexer/src/error.rs index bf8ad81..dcefc7e 100644 --- a/apps/indexer/src/error.rs +++ b/apps/indexer/src/error.rs @@ -23,6 +23,9 @@ pub enum IndexerError { #[error("task join error: {0}")] Join(#[from] tokio::task::JoinError), + + #[error("payload too large: {field} is {size} bytes (max: {max})")] + PayloadTooLarge { field: &'static str, size: usize, max: usize }, } pub type Result = std::result::Result; diff --git a/apps/indexer/src/indexer/mod.rs b/apps/indexer/src/indexer/mod.rs index 2772f2d..18a2438 100644 --- a/apps/indexer/src/indexer/mod.rs +++ b/apps/indexer/src/indexer/mod.rs @@ -1,4 +1,5 @@ pub mod backfill; pub mod events; pub mod processor; +pub mod retry_queue; pub mod subscriber; diff --git a/apps/indexer/src/indexer/processor.rs b/apps/indexer/src/indexer/processor.rs index b1cf257..47c9189 100644 --- a/apps/indexer/src/indexer/processor.rs +++ b/apps/indexer/src/indexer/processor.rs @@ -6,10 +6,18 @@ use crate::db::queries::{ get_and_increment_seq, insert_handshake, insert_hsr, insert_message, }; use crate::db::DbPool; -use crate::error::Result; +use crate::error::{IndexerError, Result}; use super::events::{Handshake, HandshakeResponse, MessageSent}; +// Payload size limits (reasonable for Verbeth protocol) +const MAX_CIPHERTEXT_SIZE: usize = 64 * 1024; // 64 KB per message +const MAX_PUB_KEYS_SIZE: usize = 65; // version + X25519 + Ed25519 +const MAX_EPHEMERAL_KEY_SIZE: usize = 1216; // X25519 32 + ML-KEM 1184 +const MAX_PLAINTEXT_PAYLOAD_SIZE: usize = 1024; // 1 KB metadata +const MAX_HSR_CIPHERTEXT_SIZE: usize = 4 * 1024; // 4 KB handshake response + +#[derive(Clone)] pub enum VerbethEvent { MessageSent { sender: Address, @@ -33,6 +41,7 @@ pub enum VerbethEvent { }, } +#[derive(Clone)] pub struct LogWithMeta { pub event: VerbethEvent, pub block_number: u64, @@ -40,6 +49,53 @@ pub struct LogWithMeta { pub block_timestamp: u64, } +fn validate_payload_sizes(event: &VerbethEvent) -> Result<()> { + match event { + VerbethEvent::MessageSent { ciphertext, .. } => { + if ciphertext.len() > MAX_CIPHERTEXT_SIZE { + return Err(IndexerError::PayloadTooLarge { + field: "ciphertext", + size: ciphertext.len(), + max: MAX_CIPHERTEXT_SIZE, + }); + } + } + VerbethEvent::Handshake { pub_keys, ephemeral_pub_key, plaintext_payload, .. } => { + if pub_keys.len() > MAX_PUB_KEYS_SIZE { + return Err(IndexerError::PayloadTooLarge { + field: "pubKeys", + size: pub_keys.len(), + max: MAX_PUB_KEYS_SIZE, + }); + } + if ephemeral_pub_key.len() > MAX_EPHEMERAL_KEY_SIZE { + return Err(IndexerError::PayloadTooLarge { + field: "ephemeralPubKey", + size: ephemeral_pub_key.len(), + max: MAX_EPHEMERAL_KEY_SIZE, + }); + } + if plaintext_payload.len() > MAX_PLAINTEXT_PAYLOAD_SIZE { + return Err(IndexerError::PayloadTooLarge { + field: "plaintextPayload", + size: plaintext_payload.len(), + max: MAX_PLAINTEXT_PAYLOAD_SIZE, + }); + } + } + VerbethEvent::HandshakeResponse { ciphertext, .. } => { + if ciphertext.len() > MAX_HSR_CIPHERTEXT_SIZE { + return Err(IndexerError::PayloadTooLarge { + field: "hsrCiphertext", + size: ciphertext.len(), + max: MAX_HSR_CIPHERTEXT_SIZE, + }); + } + } + } + Ok(()) +} + pub struct EventProcessor { pool: DbPool, } @@ -50,6 +106,9 @@ impl EventProcessor { } pub fn process(&self, log: LogWithMeta) -> Result { + // Validate payload sizes before processing + validate_payload_sizes(&log.event)?; + let conn = self.pool.get()?; match log.event { diff --git a/apps/indexer/src/indexer/retry_queue.rs b/apps/indexer/src/indexer/retry_queue.rs new file mode 100644 index 0000000..d7ca6f2 --- /dev/null +++ b/apps/indexer/src/indexer/retry_queue.rs @@ -0,0 +1,83 @@ +use std::collections::VecDeque; +use tokio::sync::Mutex; + +use super::processor::LogWithMeta; + +const MAX_RETRIES: u32 = 3; +const MAX_QUEUE_SIZE: usize = 1000; + +pub struct FailedEvent { + pub log: LogWithMeta, + pub retry_count: u32, + pub last_error: String, +} + +pub struct RetryQueue { + queue: Mutex>, +} + +impl RetryQueue { + pub fn new() -> Self { + Self { + queue: Mutex::new(VecDeque::new()), + } + } + + pub async fn push(&self, log: LogWithMeta, error: String) { + let mut q = self.queue.lock().await; + + // Check if we're at capacity - dead-letter oldest event + if q.len() >= MAX_QUEUE_SIZE { + if let Some(old) = q.pop_front() { + tracing::error!( + block = old.log.block_number, + log_index = old.log.log_index, + retries = old.retry_count, + error = %old.last_error, + "Event permanently failed (dead-letter, queue full)" + ); + } + } + + q.push_back(FailedEvent { + log, + retry_count: 0, + last_error: error, + }); + } + + pub async fn push_retry(&self, mut event: FailedEvent, error: String) { + event.retry_count += 1; + event.last_error = error; + + if event.retry_count >= MAX_RETRIES { + // Dead-letter: log and discard + tracing::error!( + block = event.log.block_number, + log_index = event.log.log_index, + retries = event.retry_count, + error = %event.last_error, + "Event permanently failed (dead-letter, max retries)" + ); + return; + } + + let mut q = self.queue.lock().await; + q.push_back(event); + } + + pub async fn pop(&self) -> Option { + self.queue.lock().await.pop_front() + } + + #[allow(dead_code)] + pub async fn len(&self) -> usize { + self.queue.lock().await.len() + } +} + +impl Default for RetryQueue { + fn default() -> Self { + Self::new() + } +} diff --git a/apps/indexer/src/indexer/subscriber.rs b/apps/indexer/src/indexer/subscriber.rs index 148ad49..5780f28 100644 --- a/apps/indexer/src/indexer/subscriber.rs +++ b/apps/indexer/src/indexer/subscriber.rs @@ -1,3 +1,4 @@ +use std::sync::Arc; use std::time::Duration; use alloy::eips::BlockNumberOrTag; @@ -8,21 +9,36 @@ use alloy::rpc::types::{BlockTransactionsKind, Filter}; use alloy::sol_types::SolEvent; use tokio::sync::watch; -use crate::db::queries::set_last_processed_block; +use crate::config::{sanitize_rpc_url, Config}; +use crate::db::queries::{get_last_processed_block, set_last_processed_block}; use crate::db::DbPool; use crate::error::Result; +use super::backfill::run_backfill; use super::events::{Handshake, HandshakeResponse, MessageSent}; use super::processor::{decode_log, EventProcessor, LogWithMeta}; +use super::retry_queue::RetryQueue; + +const RETRY_INTERVAL_SECS: u64 = 10; pub async fn subscribe_with_reconnect( - ws_url: String, - contract_address: Address, + config: Arc, pool: DbPool, mut shutdown: watch::Receiver, ) { - let processor = EventProcessor::new(pool.clone()); + let processor = Arc::new(EventProcessor::new(pool.clone())); + let retry_queue = Arc::new(RetryQueue::new()); let mut backoff = Duration::from_secs(1); + let mut is_first_connect = true; + + // Spawn background retry task + let retry_processor = processor.clone(); + let retry_q = retry_queue.clone(); + let retry_pool = pool.clone(); + let retry_shutdown = shutdown.clone(); + tokio::spawn(async move { + run_retry_loop(retry_q, retry_processor, retry_pool, retry_shutdown).await; + }); loop { if *shutdown.borrow() { @@ -30,8 +46,24 @@ pub async fn subscribe_with_reconnect( break; } - match connect_and_subscribe(&ws_url, contract_address, &processor, &pool, &mut shutdown) - .await + // Recover missed events via HTTP before (re)connecting WS + // Skip on first connect since main.rs already does initial backfill + if !is_first_connect { + if let Err(e) = recover_missed_events(&config, &pool).await { + tracing::warn!("Failed to recover missed events: {e}"); + } + } + is_first_connect = false; + + match connect_and_subscribe( + &config.rpc_ws_url, + config.contract_address, + &processor, + &retry_queue, + &pool, + &mut shutdown, + ) + .await { Ok(()) => { tracing::info!("Subscriber shut down gracefully"); @@ -53,14 +85,104 @@ pub async fn subscribe_with_reconnect( } } +async fn recover_missed_events(config: &Config, pool: &DbPool) -> Result<()> { + let conn = pool.get()?; + let last_block = get_last_processed_block(&conn)?.unwrap_or(0) as u64; + drop(conn); + + // Derive HTTP URL from WS URL if not explicitly set + let http_url = config.rpc_http_url.clone().unwrap_or_else(|| { + config + .rpc_ws_url + .replace("wss://", "https://") + .replace("ws://", "http://") + }); + + let provider = ProviderBuilder::new().on_http(http_url.parse().map_err(|e| { + crate::error::IndexerError::Config(format!("Invalid HTTP RPC URL: {e}")) + })?); + + let chain_head = provider.get_block_number().await?; + + if chain_head <= last_block { + tracing::debug!("No missed blocks to recover"); + return Ok(()); + } + + let gap = chain_head - last_block; + tracing::info!( + "Recovering {} missed blocks ({} -> {})", + gap, + last_block + 1, + chain_head + ); + + run_backfill( + &http_url, + config.contract_address, + last_block + 1, + chain_head, + config.rpc_chunk_size, + pool.clone(), + ) + .await?; + + tracing::info!("Recovery complete"); + Ok(()) +} + +async fn run_retry_loop( + queue: Arc, + processor: Arc, + pool: DbPool, + mut shutdown: watch::Receiver, +) { + loop { + tokio::select! { + _ = shutdown.changed() => { + if *shutdown.borrow() { + tracing::debug!("Retry loop shutting down"); + return; + } + } + _ = tokio::time::sleep(Duration::from_secs(RETRY_INTERVAL_SECS)) => { + while let Some(failed) = queue.pop().await { + let block_number = failed.log.block_number; + let log_clone = failed.log.clone(); + match processor.process(log_clone) { + Ok(true) => { + tracing::info!( + block = block_number, + attempt = failed.retry_count + 1, + "Retry succeeded" + ); + if let Ok(conn) = pool.get() { + let _ = set_last_processed_block(&conn, block_number as i64); + } + } + Ok(false) => { + tracing::debug!(block = block_number, "Retry: duplicate event"); + } + Err(e) => { + // Re-queue for another retry attempt + queue.push_retry(failed, e.to_string()).await; + } + } + } + } + } + } +} + async fn connect_and_subscribe( ws_url: &str, contract_address: Address, - processor: &EventProcessor, + processor: &Arc, + retry_queue: &Arc, pool: &DbPool, shutdown: &mut watch::Receiver, ) -> Result<()> { - tracing::info!("Connecting to WebSocket: {}", ws_url); + tracing::info!("Connecting to WebSocket: {}", sanitize_rpc_url(ws_url)); let ws = WsConnect::new(ws_url); let provider = ProviderBuilder::new().on_ws(ws).await?; @@ -102,7 +224,13 @@ async fn connect_and_subscribe( continue; }; - let block_timestamp = fetch_block_timestamp(&provider, block_number).await?; + let block_timestamp = match fetch_block_timestamp(&provider, block_number).await { + Ok(ts) => ts, + Err(e) => { + tracing::warn!("Failed to fetch block timestamp: {e}"); + continue; + } + }; let log_with_meta = LogWithMeta { event, @@ -121,7 +249,22 @@ async fn connect_and_subscribe( tracing::debug!("Duplicate event at block {}", block_number); } Err(e) => { - tracing::error!("Failed to process event: {e}"); + tracing::warn!( + block = block_number, + log_index = log_index, + error = %e, + "Failed to process event, queuing for retry" + ); + // Re-create log_with_meta for retry (need to re-decode) + if let Some(event) = decode_log(&log) { + let retry_log = LogWithMeta { + event, + block_number, + log_index, + block_timestamp, + }; + retry_queue.push(retry_log, e.to_string()).await; + } } } } diff --git a/apps/indexer/src/main.rs b/apps/indexer/src/main.rs index e69a049..9f98063 100644 --- a/apps/indexer/src/main.rs +++ b/apps/indexer/src/main.rs @@ -33,7 +33,7 @@ async fn main() -> Result<()> { tracing::info!("Database: {}", config.database_path); tracing::info!("RPC chunk size: {} blocks", config.rpc_chunk_size); - let pool = create_pool(&config.database_path)?; + let pool = create_pool(&config.database_path, &config.sqlite_sync_mode)?; let (shutdown_tx, shutdown_rx) = watch::channel(false); @@ -80,13 +80,12 @@ async fn main() -> Result<()> { let state = AppState::new(pool.clone(), config); let subscriber_handle = { - let ws_url = state.config.rpc_ws_url.clone(); - let contract_address = state.config.contract_address; + let config = state.config.clone(); let pool = pool.clone(); let shutdown_rx = shutdown_rx.clone(); tokio::spawn(async move { - subscriber::subscribe_with_reconnect(ws_url, contract_address, pool, shutdown_rx).await; + subscriber::subscribe_with_reconnect(config, pool, shutdown_rx).await; }) }; From a0d1db189649da348ee1a2f02ce971208ffc6b23 Mon Sep 17 00:00:00 2001 From: Marco Esposito Date: Fri, 6 Feb 2026 16:33:38 +0100 Subject: [PATCH 38/51] rename to verbeth --- README.md | 10 +++++----- apps/docs/docusaurus.config.ts | 6 +++--- apps/docs/src/pages/index.tsx | 2 +- package.json | 2 +- packages/sdk/README.md | 6 +++--- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index ea19ca0..af32588 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@

- E2EE messaging over Ethereum logs, using the blockchain as the only transport layer. + E2EE messaging over the blockchain, using EVM logs as the only transport layer.

@@ -16,11 +16,11 @@ - - + + -

diff --git a/apps/docs/docusaurus.config.ts b/apps/docs/docusaurus.config.ts index 3d597fb..79366a4 100644 --- a/apps/docs/docusaurus.config.ts +++ b/apps/docs/docusaurus.config.ts @@ -15,7 +15,7 @@ const config: Config = { baseUrl: '/', organizationName: 'okrame', - projectName: 'verbeth-sdk', + projectName: 'verbeth', onBrokenLinks: 'throw', @@ -36,7 +36,7 @@ const config: Config = { { docs: { sidebarPath: './sidebars.ts', - editUrl: 'https://github.com/okrame/verbeth-sdk/tree/main/apps/docs/', + editUrl: 'https://github.com/okrame/verbeth/tree/main/apps/docs/', }, blog: false, theme: { @@ -61,7 +61,7 @@ const config: Config = { label: 'Docs', }, { - href: 'https://github.com/okrame/verbeth-sdk', + href: 'https://github.com/okrame/verbeth', label: 'GitHub', position: 'right', }, diff --git a/apps/docs/src/pages/index.tsx b/apps/docs/src/pages/index.tsx index d319e8b..851b94d 100644 --- a/apps/docs/src/pages/index.tsx +++ b/apps/docs/src/pages/index.tsx @@ -12,7 +12,7 @@ export default function Home(): ReactNode {

End-to-end encrypted messaging over Ethereum

Get Started - GitHub + GitHub
- {/* Activity Log + Debug Info */} - {ready && ( -
-
-
setIsActivityLogOpen(!isActivityLogOpen)} - > -
-
-

Activity Log

- - {isActivityLogOpen ? 'โ–ผ' : 'โ–ถ'} - -
- {canLoadMore && ready && isActivityLogOpen && ( - - )} -
- {(isInitialLoading || isLoadingMore) && isActivityLogOpen && ( -
-
- {isInitialLoading ? 'Initial sync...' : 'Loading more...'} - {syncProgress && ( - ({syncProgress.current}/{syncProgress.total}) - )} -
- )} -
- -
-
-