diff --git a/packages/cli/package.json b/packages/cli/package.json index db5b219f45..255edb9e7c 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -69,6 +69,7 @@ "p-retry": "^5.1.2", "path": "^0.12.7", "rxjs": "7.5.5", + "solady": "^0.1.26", "throttle-debounce": "^5.0.0", "toposort": "^2.0.2", "viem": "2.35.1", diff --git a/packages/cli/src/commands/index.ts b/packages/cli/src/commands/index.ts index cce1230fa6..6421123bee 100644 --- a/packages/cli/src/commands/index.ts +++ b/packages/cli/src/commands/index.ts @@ -15,6 +15,7 @@ import trace from "./trace"; import devContracts from "./dev-contracts"; import verify from "./verify"; import pull from "./pull"; +import mirror from "./mirror"; // eslint-disable-next-line @typescript-eslint/no-explicit-any -- Each command has different options export const commands: CommandModule[] = [ @@ -32,4 +33,5 @@ export const commands: CommandModule[] = [ abiTs, verify, pull, + mirror, ]; diff --git a/packages/cli/src/commands/mirror.ts b/packages/cli/src/commands/mirror.ts new file mode 100644 index 0000000000..2bdade4364 --- /dev/null +++ b/packages/cli/src/commands/mirror.ts @@ -0,0 +1,153 @@ +import type { CommandModule, InferredOptionTypes } from "yargs"; +import { createClient, getAddress, http, isHex } from "viem"; +import chalk from "chalk"; +import { getChainId } from "viem/actions"; +import { defaultChains } from "../defaultChains"; +import { mirror } from "../mirror/mirror"; +import { MUDError } from "@latticexyz/common/errors"; +import { kmsKeyToAccount } from "@latticexyz/common/kms"; +import { privateKeyToAccount } from "viem/accounts"; + +const options = { + rpcBatch: { + type: "boolean", + desc: "Enable batch processing of RPC requests via Viem client (defaults to batch size of 100 and wait of 1s).", + }, + kms: { + type: "boolean", + desc: "Deploy the world with an AWS KMS key instead of local private key.", + }, + fromWorld: { + type: "string", + desc: "Source world address to mirror data from.", + required: true, + }, + fromBlock: { + type: "number", + desc: "Block number of source world deploy.", + }, + fromRpc: { + type: "string", + desc: "RPC URL of source chain to mirror from.", + required: true, + }, + fromIndexer: { + type: "string", + desc: "MUD indexer URL of source chain to mirror from. Used to fetch table data.", + }, + fromBlockscout: { + type: "string", + desc: "Blockscout URL of source chain to mirror from. Used to fetch contract init code.", + }, + toWorld: { + type: "string", + desc: "Target world address to mirror data to.", + required: true, + }, + toBlock: { + type: "number", + desc: "Block number of target world deploy.", + }, + toRpc: { + type: "string", + desc: "RPC URL of target chain to mirror to.", + required: true, + }, +} as const; + +type Options = InferredOptionTypes; + +const commandModule: CommandModule = { + command: "mirror", + + describe: "Mirror an existing world and its data to another chain.", + + builder(yargs) { + return yargs.options(options); + }, + + async handler(opts) { + const fromWorld = getAddress(opts.fromWorld); + const fromClient = createClient({ + transport: http(opts.fromRpc, { + batch: opts.rpcBatch ? { batchSize: 100, wait: 1000 } : undefined, + }), + pollingInterval: 500, + }); + const fromChainId = await getChainId(fromClient); + const fromChain = defaultChains.find((chain) => chain.id === fromChainId); + const fromIndexer = opts.fromIndexer ?? fromChain?.indexerUrl; + if (!fromIndexer) { + throw new MUDError(`No \`--fromIndexer\` provided or indexer URL configured for chain ${fromChainId}.`); + } + + const fromBlockscout = opts.fromBlockscout + ? ({ name: "Blockscout", url: opts.fromBlockscout } as const) + : fromChain?.blockExplorers.default; + if (!fromBlockscout || fromBlockscout.name !== "Blockscout") { + throw new MUDError( + `No \`--fromBlockscout\` provided or Blockscout block explorer URL configured for chain ${fromChainId}.`, + ); + } + + const account = await (async () => { + if (opts.kms) { + const keyId = process.env.AWS_KMS_KEY_ID; + if (!keyId) { + throw new MUDError( + "Missing `AWS_KMS_KEY_ID` environment variable. This is required when using with `--kms` option.", + ); + } + + return await kmsKeyToAccount({ keyId }); + } else { + const privateKey = process.env.PRIVATE_KEY; + if (!isHex(privateKey)) { + throw new MUDError( + // eslint-disable-next-line max-len + `Missing or invalid \`PRIVATE_KEY\` environment variable. To use the default Anvil private key, run\n\n echo "PRIVATE_KEY=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80" > .env\n`, + ); + } + return privateKeyToAccount(privateKey); + } + })(); + + const toWorld = getAddress(opts.toWorld); + const toClient = createClient({ + account, + transport: http(opts.toRpc, { + batch: opts.rpcBatch ? { batchSize: 100, wait: 1000 } : undefined, + }), + pollingInterval: 500, + }); + const toChainId = await getChainId(toClient); + + console.log( + chalk.bgBlue( + chalk.whiteBright(` + Mirroring MUD data + from world ${fromWorld} on chain ${fromChainId} + to world ${toWorld} on chain ${toChainId} +`), + ), + ); + + await mirror({ + rootDir: process.cwd(), + from: { + client: fromClient, + indexer: fromIndexer, + world: fromWorld, + block: opts.fromBlock != null ? BigInt(opts.fromBlock) : undefined, + blockscout: fromBlockscout.url, + }, + to: { + client: toClient, + world: toWorld, + block: opts.toBlock != null ? BigInt(opts.toBlock) : undefined, + }, + }); + }, +}; + +export default commandModule; diff --git a/packages/cli/src/deploy/configToModules.ts b/packages/cli/src/deploy/configToModules.ts index d2bd2407e0..a512d1d4d4 100644 --- a/packages/cli/src/deploy/configToModules.ts +++ b/packages/cli/src/deploy/configToModules.ts @@ -17,7 +17,7 @@ const callWithSignatureModuleArtifact = getContractArtifact(callWithSignatureMod const batchStoreModuleArtifact = getContractArtifact(batchStoreModule); // metadata module is installed inside `ensureResourceTags` -const defaultModules: Module[] = [ +export const defaultModules: Module[] = [ { // optional for now // TODO: figure out approach to install on existing worlds where deployer may not own root namespace diff --git a/packages/cli/src/mirror/common.ts b/packages/cli/src/mirror/common.ts new file mode 100644 index 0000000000..f1611723bd --- /dev/null +++ b/packages/cli/src/mirror/common.ts @@ -0,0 +1,19 @@ +import { mudDataDirectory } from "@latticexyz/world/node"; +import { Address, Hex } from "viem"; +import { DeployedSystem } from "../deploy/common"; +import { StoreLog } from "@latticexyz/store"; + +export const mirrorPlansDirectory = `${mudDataDirectory}/mirror-plans`; + +export type PlanStep = + | { step: "deploySystem"; system: DeployedSystem; bytecode: DeployedBytecode } + | { step: "setRecord"; record: Extract["args"] }; + +export type DeployedBytecode = { + address: Address; + initCode: Hex; + libraries: { + offset: number; + reference: DeployedBytecode; + }[]; +}; diff --git a/packages/cli/src/mirror/createMirrorPlan.ts b/packages/cli/src/mirror/createMirrorPlan.ts new file mode 100644 index 0000000000..b7f7f179ee --- /dev/null +++ b/packages/cli/src/mirror/createMirrorPlan.ts @@ -0,0 +1,110 @@ +import { Address, Client } from "viem"; +import { getWorldDeploy } from "../deploy/getWorldDeploy"; +import { getChainId } from "viem/actions"; +import { getTables } from "../deploy/getTables"; +import { resourceToLabel } from "@latticexyz/common"; +import { getRecordsAsLogs } from "@latticexyz/store-sync"; +import pRetry from "p-retry"; +import { Table } from "@latticexyz/config"; +import path from "path"; +import { createPlanWriter } from "./createPlanWriter"; +import { mkdir, rm } from "fs/promises"; +import { mirrorPlansDirectory } from "./common"; +import { getSystems } from "../deploy/getSystems"; +import { getDeployedBytecode } from "./getDeployedBytecode"; +import { debug } from "./debug"; + +// TODO: attempt to create world the same way as it was originally created, thus preserving world address +// TODO: set up table to track migrated records with original metadata (block number/timestamp) and for lazy migrations + +export async function createMirrorPlan({ + rootDir, + from, +}: { + rootDir: string; + from: { + block?: bigint; + world: Address; + client: Client; + indexer: string; + blockscout: string; + }; +}) { + const fromChainId = await getChainId(from.client); + + const planFilename = path.join(rootDir, mirrorPlansDirectory, `${fromChainId}_${from.world.toLowerCase()}.ndjson.gz`); + await mkdir(path.dirname(planFilename), { recursive: true }); + + const plan = createPlanWriter(planFilename); + + const makePlan = (async () => { + const worldDeploy = await getWorldDeploy(from.client, from.world, from.block); + + debug("getting systems"); + const systems = await getSystems({ + client: from.client, + worldDeploy, + indexerUrl: from.indexer, + chainId: fromChainId, + }); + + debug("getting bytecode for", systems.length, "systems"); + const systemsWithBytecode = await Promise.all( + systems.map(async (system) => { + const bytecode = await getDeployedBytecode({ + client: from.client, + address: system.address, + debugLabel: `${resourceToLabel(system)} system`, + allowedStorage: ["empty", { worldConsumer: worldDeploy.address }], + blockscoutUrl: from.blockscout, + }); + return { system, bytecode }; + }), + ); + for (const { system, bytecode } of systemsWithBytecode) { + if (!bytecode) continue; + plan.write({ step: "deploySystem", system, bytecode }); + } + + const tables = await getTables({ + client: from.client, + worldDeploy, + indexerUrl: from.indexer, + chainId: fromChainId, + }); + + // TODO: sort tables so that the insert order is correct (e.g. namespaces first) + + let count = 0; + for (const table of tables) { + const logs = await pRetry(() => + getRecordsAsLogs({ + worldAddress: from.world, + table: table as never, + client: from.client, + indexerUrl: from.indexer, + chainId: fromChainId, + }), + ); + debug("got", logs.length, "logs for", resourceToLabel(table)); + for (const log of logs) { + plan.write({ step: "setRecord", record: log.args }); + } + count += logs.length; + } + debug("got", count, "total record logs"); + })(); + + try { + try { + await makePlan; + } finally { + console.log("writing plan to", path.relative(rootDir, planFilename)); + await plan.end(); + } + return planFilename; + } catch (error) { + await rm(planFilename, { force: true }); + throw error; + } +} diff --git a/packages/cli/src/mirror/createPlanWriter.ts b/packages/cli/src/mirror/createPlanWriter.ts new file mode 100644 index 0000000000..c9695e9ab9 --- /dev/null +++ b/packages/cli/src/mirror/createPlanWriter.ts @@ -0,0 +1,20 @@ +import { createWriteStream } from "node:fs"; +import { createGzip } from "node:zlib"; +import { pipeline } from "node:stream/promises"; +import { PlanStep } from "./common"; + +export function createPlanWriter(filename: string) { + const gzip = createGzip(); + const fileStream = createWriteStream(filename); + const output = pipeline(gzip, fileStream); + return { + write(data: PlanStep) { + gzip.write(JSON.stringify(data) + "\n"); + return this; + }, + async end() { + gzip.end(); + await output; + }, + }; +} diff --git a/packages/cli/src/mirror/createRecordHandler.ts b/packages/cli/src/mirror/createRecordHandler.ts new file mode 100644 index 0000000000..5be7e5fd6f --- /dev/null +++ b/packages/cli/src/mirror/createRecordHandler.ts @@ -0,0 +1,442 @@ +import { + Account, + Address, + Chain, + Client, + Hex, + Transport, + decodeFunctionResult, + encodeAbiParameters, + formatEther, + zeroHash, +} from "viem"; +import { writeContract } from "@latticexyz/common"; +import { encodeSystemCall, worldCallAbi } from "@latticexyz/world/internal"; +import batchStoreConfig from "@latticexyz/world-module-batchstore/mud.config"; +import { readContract, waitForTransactionReceipt } from "viem/actions"; +import chalk from "chalk"; +import { StoreRecord } from "./executeMirrorPlan"; +import { debug } from "./debug"; +import { LibZip } from "solady"; + +export function createRecordHandler({ + client, + worldAddress, + totalRecords, +}: { + client: Client; + worldAddress: Address; + totalRecords: number; +}) { + const batchSize = 250; + const records: StoreRecord[] = []; + const status = { + submitted: 0, + confirmed: 0, + gasUsed: 0, + calldataSent: 0, + timePerRecord: Infinity, + }; + + async function flush() { + const hash = await onBatch(records.splice(0, records.length)); + return hash ? [hash] : []; + } + + // assumes records are added in order by table ID + async function set(record: StoreRecord) { + const hashes: Hex[] = []; + if (records[0] && records[0].tableId !== record.tableId) { + hashes.push(...(await flush())); + } + records.push({ + ...record, + // indexer returns 0x00 for zero-length encodedLengths + // TODO: fix indexer response + encodedLengths: record.encodedLengths === "0x00" ? zeroHash : record.encodedLengths, + }); + if (records.length >= batchSize) { + hashes.push(...(await flush())); + } + return hashes; + } + + async function finalize() { + return await flush(); + } + + async function onBatch(batch: StoreRecord[]) { + const start = Date.now(); + const hash = await setRecords(batch); + const elapsedPerRecord = (Date.now() - start) / batch.length; + + status.timePerRecord = + status.timePerRecord === Infinity ? elapsedPerRecord : status.timePerRecord * 0.95 + elapsedPerRecord * 0.05; + status.submitted += batch.length; + + const estimatedTime = (status.timePerRecord * (totalRecords - status.submitted)) / 1000 / 60 / 60; + const progress = status.submitted / totalRecords; + const progressBarSize = 60; + const progressBarFilled = Math.floor(progress * progressBarSize); + + console.log( + `Records submitted: ${status.submitted.toLocaleString()} / ${totalRecords.toLocaleString()} + +${chalk.green("▮".repeat(progressBarFilled))}${chalk.gray("▯".repeat(progressBarSize - progressBarFilled))} ${(progress * 100).toFixed(1)}% +${" ".repeat(progressBarFilled)}~${estimatedTime.toFixed(1)} hours +`, + ); + + if (hash) { + waitForTransactionReceipt(client, { hash }).then((receipt) => { + if (receipt.status === "reverted") { + console.error("Could not submit records", batch, receipt); + return; + } + + status.confirmed += batch.length; + status.gasUsed += Number(receipt.gasUsed); + + const estimatedGas = Math.ceil((status.gasUsed / status.confirmed) * totalRecords); + console.log( + `Records confirmed: ${status.confirmed.toLocaleString()} / ${totalRecords.toLocaleString()} +Gas used: ${status.gasUsed.toLocaleString()} / ~${estimatedGas.toLocaleString()} (${receipt.gasUsed.toLocaleString()} used last batch) +Estimated L2 cost at 100k wei: ${parseFloat(formatEther(BigInt(estimatedGas) * 100000n)).toFixed(3)} ETH +`, + ); + }); + } + + return hash; + } + + async function setRecords(records: StoreRecord[]) { + const existingRecords = decodeFunctionResult({ + abi: batchStoreSystemAbi, + functionName: "getTableRecords", + data: await readContract(client, { + address: worldAddress, + abi: worldCallAbi, + functionName: "call", + args: encodeSystemCall({ + systemId: batchStoreConfig.systems.BatchStoreSystem.systemId, + abi: batchStoreSystemAbi, + functionName: "getTableRecords", + args: [records[0].tableId, records.map((record) => record.keyTuple)], + }), + }), + }); + + const changedRecords = records.filter((record, i) => { + const recordEncoded = encodeAbiParameters([tableRecordAbiItem], [record]); + const existingRecordEncoded = encodeAbiParameters([tableRecordAbiItem], [existingRecords[i]]); + if (recordEncoded === existingRecordEncoded) return false; + // console.log("record changed in", record.tableId); + // console.log(" ", recordEncoded); + // console.log(" ", existingRecordEncoded); + return true; + }); + if (!changedRecords.length) { + return; + } + + const calldata = encodeAbiParameters( + [{ type: "bytes32" }, tableRecordsAbiItem], + [changedRecords[0].tableId, changedRecords], + ); + const args = encodeSystemCall({ + systemId: batchStoreConfig.systems.BatchStoreSystem.systemId, + abi: batchStoreSystemAbi, + functionName: "_setTableRecords_flz", + args: [LibZip.flzCompress(calldata) as Hex], + }); + // console.log( + // "flz compression", + // size(calldata), + // "=>", + // size(LibZip.flzCompress(calldata) as Hex), + // " = ", + // size(LibZip.flzCompress(calldata) as Hex) / size(calldata), + // ); + const hash = await writeContract(client, { + chain: client.chain ?? null, + address: worldAddress, + abi: worldCallAbi, + functionName: "call", + args, + }); + debug("set", changedRecords.length, "records", `(tx: ${hash})`); + return hash; + } + + return { set, finalize }; +} + +const tableRecordAbiItem = { + type: "tuple", + internalType: "struct TableRecord", + components: [ + { + name: "keyTuple", + type: "bytes32[]", + internalType: "bytes32[]", + }, + { + name: "staticData", + type: "bytes", + internalType: "bytes", + }, + { + name: "encodedLengths", + type: "bytes32", + internalType: "EncodedLengths", + }, + { + name: "dynamicData", + type: "bytes", + internalType: "bytes", + }, + ], +} as const; + +const tableRecordsAbiItem = { + type: "tuple[]", + internalType: "struct TableRecord[]", + components: [ + { + name: "keyTuple", + type: "bytes32[]", + internalType: "bytes32[]", + }, + { + name: "staticData", + type: "bytes", + internalType: "bytes", + }, + { + name: "encodedLengths", + type: "bytes32", + internalType: "EncodedLengths", + }, + { + name: "dynamicData", + type: "bytes", + internalType: "bytes", + }, + ], +}; + +const batchStoreSystemAbi = [ + { + type: "function", + name: "_deleteTableRecords", + inputs: [ + { + name: "tableId", + type: "bytes32", + internalType: "ResourceId", + }, + { + name: "keyTuples", + type: "bytes32[][]", + internalType: "bytes32[][]", + }, + ], + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "_setTableRecords", + inputs: [ + { + name: "tableId", + type: "bytes32", + internalType: "ResourceId", + }, + { + name: "records", + type: "tuple[]", + internalType: "struct TableRecord[]", + components: [ + { + name: "keyTuple", + type: "bytes32[]", + internalType: "bytes32[]", + }, + { + name: "staticData", + type: "bytes", + internalType: "bytes", + }, + { + name: "encodedLengths", + type: "bytes32", + internalType: "EncodedLengths", + }, + { + name: "dynamicData", + type: "bytes", + internalType: "bytes", + }, + ], + }, + ], + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "_setTableRecords_flz", + inputs: [ + { + name: "data", + type: "bytes", + internalType: "bytes", + }, + ], + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "deleteTableRecords", + inputs: [ + { + name: "tableId", + type: "bytes32", + internalType: "ResourceId", + }, + { + name: "keyTuples", + type: "bytes32[][]", + internalType: "bytes32[][]", + }, + ], + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "getTableRecords", + inputs: [ + { + name: "tableId", + type: "bytes32", + internalType: "ResourceId", + }, + { + name: "keyTuples", + type: "bytes32[][]", + internalType: "bytes32[][]", + }, + ], + outputs: [ + { + name: "records", + type: "tuple[]", + internalType: "struct TableRecord[]", + components: [ + { + name: "keyTuple", + type: "bytes32[]", + internalType: "bytes32[]", + }, + { + name: "staticData", + type: "bytes", + internalType: "bytes", + }, + { + name: "encodedLengths", + type: "bytes32", + internalType: "EncodedLengths", + }, + { + name: "dynamicData", + type: "bytes", + internalType: "bytes", + }, + ], + }, + ], + stateMutability: "view", + }, + { + type: "function", + name: "setTableRecords", + inputs: [ + { + name: "tableId", + type: "bytes32", + internalType: "ResourceId", + }, + { + name: "records", + type: "tuple[]", + internalType: "struct TableRecord[]", + components: [ + { + name: "keyTuple", + type: "bytes32[]", + internalType: "bytes32[]", + }, + { + name: "staticData", + type: "bytes", + internalType: "bytes", + }, + { + name: "encodedLengths", + type: "bytes32", + internalType: "EncodedLengths", + }, + { + name: "dynamicData", + type: "bytes", + internalType: "bytes", + }, + ], + }, + ], + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "error", + name: "Slice_OutOfBounds", + inputs: [ + { + name: "data", + type: "bytes", + internalType: "bytes", + }, + { + name: "start", + type: "uint256", + internalType: "uint256", + }, + { + name: "end", + type: "uint256", + internalType: "uint256", + }, + ], + }, + { + type: "error", + name: "World_AccessDenied", + inputs: [ + { + name: "resource", + type: "string", + internalType: "string", + }, + { + name: "caller", + type: "address", + internalType: "address", + }, + ], + }, +] as const; diff --git a/packages/cli/src/mirror/debug.ts b/packages/cli/src/mirror/debug.ts new file mode 100644 index 0000000000..99de12cf11 --- /dev/null +++ b/packages/cli/src/mirror/debug.ts @@ -0,0 +1,10 @@ +import { debug as parentDebug } from "../debug"; + +export const debug = parentDebug.extend("mirror"); +export const error = parentDebug.extend("mirror"); + +// Pipe debug output to stdout instead of stderr +debug.log = console.debug.bind(console); + +// Pipe error output to stderr +error.log = console.error.bind(console); diff --git a/packages/cli/src/mirror/executeMirrorPlan.ts b/packages/cli/src/mirror/executeMirrorPlan.ts new file mode 100644 index 0000000000..643027cfa7 --- /dev/null +++ b/packages/cli/src/mirror/executeMirrorPlan.ts @@ -0,0 +1,150 @@ +import { Account, Address, Chain, Client, Hex, Transport, concatHex, withCache } from "viem"; +import { readPlan } from "./readPlan"; +import { hexToResource, resourceToHex, resourceToLabel, spliceHex } from "@latticexyz/common"; +import { StoreLog } from "@latticexyz/store"; +import { getWorldDeploy } from "../deploy/getWorldDeploy"; +import { mudTables } from "@latticexyz/store-sync"; +import { createRecordHandler } from "./createRecordHandler"; +import { wait } from "@latticexyz/common/utils"; +import { debug } from "./debug"; +import { DeployedBytecode, PlanStep } from "./common"; +import { ensureContract, ensureDeployer, getContractAddress, waitForTransactions } from "@latticexyz/common/internal"; + +export type StoreRecord = Extract["args"]; + +export async function executeMirrorPlan({ + planFilename, + to: { client, world: worldAddress, block: deployBlock }, +}: { + planFilename: string; + to: { client: Client; world: Address; block?: bigint }; +}) { + let totalSystems = 0; + let totalRecords = 0; + + for await (const step of readPlan(planFilename)) { + if (step.step === "deploySystem") { + totalSystems += 1; + } + if (step.step === "setRecord") { + totalRecords += 1; + } + } + + console.log(`- deploying ${totalSystems.toLocaleString()} systems`); + console.log(`- setting ${totalRecords.toLocaleString()} records`); + console.log(); + + // TODO: prompt to continue + await wait(5_000); + + const worldDeploy = await getWorldDeploy(client, worldAddress, deployBlock); + debug("found world deploy at", worldDeploy.address); + + // TODO: lift into CLI to allow overriding? + const deployerAddress = await ensureDeployer(client); + debug("deploying systems via", deployerAddress); + + const deploySystemSteps: Extract[] = []; + for await (const step of readPlan(planFilename)) { + if (step.step === "deploySystem") { + deploySystemSteps.push(step); + } + } + + async function deploy(bytecode: DeployedBytecode) { + let initCode = bytecode.initCode; + for (const lib of bytecode.libraries) { + debug("deploying referenced library"); + initCode = spliceHex(initCode, lib.offset, 20, await deploy(lib.reference)); + } + const address = getContractAddress({ + deployerAddress, + bytecode: initCode, + }); + + await withCache( + async () => { + const hashes = await ensureContract({ client, deployerAddress, bytecode: initCode }); + return waitForTransactions({ client, hashes, debugLabel: "contract deploy" }); + }, + { cacheKey: `deploy:${address}` }, + ); + + return address; + } + + const systems = await Promise.all( + deploySystemSteps.map(async (step) => { + debug(`deploying ${resourceToLabel(step.system)} system`); + const address = await deploy(step.bytecode); + return { + system: step.system, + address, + previousAddress: step.bytecode.address, + }; + }), + ); + + const systemReplacements = new Map( + systems.map((system) => [ + system.previousAddress.toLowerCase().replace(/^0x/, ""), + { + value: system.address.toLowerCase().replace(/^0x/, ""), + debugLabel: `${resourceToLabel(system.system)} system address`, + }, + ]), + ); + const systemReplacementsPattern = new RegExp(Array.from(systemReplacements.keys()).join("|"), "ig"); + + function replaceSystems(data: Hex, debugLabel: string): Hex { + return data.replaceAll(systemReplacementsPattern, (match) => { + const replacement = systemReplacements.get(match); + // this should never happen, this is here just in case I messed up the logic + if (!replacement) throw new Error(`No replacement for match: ${match}`); + + debug("replacing", replacement.debugLabel, "in", debugLabel, `(0x${match} => 0x${replacement.value})`); + return replacement.value; + }) as never; + } + + const recordHandler = createRecordHandler({ + client, + worldAddress: worldDeploy.address, + totalRecords, + }); + const deferredRecords: StoreRecord[] = []; + + for await (const step of readPlan(planFilename)) { + await (async () => { + if (step.step !== "setRecord") return; + + // Update system addresses if found in record + const tableLabel = resourceToLabel(hexToResource(step.record.tableId)); + step.record.keyTuple = step.record.keyTuple.map((key) => replaceSystems(key, `key of ${tableLabel}`)); + step.record.staticData = replaceSystems(step.record.staticData, `static data of ${tableLabel}`); + step.record.dynamicData = replaceSystems(step.record.dynamicData, `dynamic data of ${tableLabel}`); + + // Defer updating root namespace owner so we can set all records + // before reverting it to the original owner. + // This allows mirroring any world, not just ones you own. + if ( + step.record.tableId === mudTables.NamespaceOwner.tableId && + concatHex(step.record.keyTuple) === resourceToHex({ type: "namespace", namespace: "", name: "" }) + ) { + deferredRecords.push(step.record); + return; + } + + await recordHandler.set(step.record); + return; + })(); + } + + for (const record of deferredRecords) { + await recordHandler.set(record); + } + await recordHandler.finalize(); + + console.log("all done!"); +} diff --git a/packages/cli/src/mirror/getDeployedBytecode.ts b/packages/cli/src/mirror/getDeployedBytecode.ts new file mode 100644 index 0000000000..d01e1af0f0 --- /dev/null +++ b/packages/cli/src/mirror/getDeployedBytecode.ts @@ -0,0 +1,102 @@ +import { Address, Client, isAddress, isHex, keccak256, withCache } from "viem"; +import { getProof } from "viem/actions"; +import { execa } from "execa"; +import { DeployedBytecode } from "./common"; +import { getWorldConsumerStorageHash } from "./getWorldConsumerStorageHash"; +import chalk from "chalk"; + +const emptyStorageHash = "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"; + +export async function getDeployedBytecode({ + client, + address, + debugLabel, + allowedStorage, + blockscoutUrl, +}: { + client: Client; + address: Address; + debugLabel: string; + allowedStorage: ("empty" | { worldConsumer: Address })[]; + blockscoutUrl: string; +}) { + const initCode = await withCache( + () => + fetch(`${blockscoutUrl}/api/v2/smart-contracts/${address.toLowerCase()}`) + .then((res) => res.json()) + .then((data) => data.creation_bytecode), + { + cacheKey: `${blockscoutUrl}/api/v2/smart-contracts/${address.toLowerCase()}`, + }, + ); + if (!isHex(initCode)) return; + + async function getStorageHash() { + const { storageHash } = await withCache(() => getProof(client, { address, storageKeys: [] }), { + cacheKey: `getProof:${client.uid}:${address.toLowerCase()}`, + }); + return storageHash; + } + + const isAllowed = await (async (): Promise => { + for (const mode of allowedStorage) { + if (mode === "empty") { + const storageHash = await getStorageHash(); + if (storageHash === emptyStorageHash) { + return true; + } + } else if ("worldConsumer" in mode) { + const storageHash = await getStorageHash(); + if (storageHash === getWorldConsumerStorageHash(mode.worldConsumer)) { + return true; + } + } + } + return false; + })(); + + if (!isAllowed) { + console.warn( + // eslint-disable-next-line max-len + `${chalk.bgYellowBright(chalk.black(" Warning! "))} ${debugLabel} (${address}) is expected to be stateless, but has unexpected storage. It'll be deployed using its original constructor arguments, but may be missing some of its internal state.`, + ); + } + + const { stdout } = await withCache(() => execa({ input: initCode })`cast disassemble`, { + cacheKey: `cast disassemble:${keccak256(initCode)}`, + }); + + const matches = stdout.matchAll(/([0-9a-f]+): PUSH20 (0x[0-9a-f]{40})/g); + const libraries: DeployedBytecode["libraries"] = []; + + for (const match of matches) { + // address bytecode offset after opcode + const offset = parseInt(match[1], 16) + 1; + const value = match[2]; + if (!isAddress(value, { strict: false })) { + throw new Error(`Found PUSH20 with invalid address: ${value}`); + } + // check if PUSH20 is followed by a DELEGATECALL within a reasonable number of opcodes + // otherwise it's probably not a public library + if (!new RegExp(`PUSH20 ${value}\n([^\n]+\n){0,24}[0-9a-f]+: DELEGATECALL`).test(stdout)) { + continue; + } + + const reference = await getDeployedBytecode({ + client, + address: value, + debugLabel: `address at bytecode offset ${offset}`, + allowedStorage: ["empty"], + blockscoutUrl, + }); + if (!reference) continue; + + libraries.push({ offset, reference }); + } + + return { + address, + initCode, + libraries, + } satisfies DeployedBytecode; +} diff --git a/packages/cli/src/mirror/getWorldConsumerStorageHash.test.ts b/packages/cli/src/mirror/getWorldConsumerStorageHash.test.ts new file mode 100644 index 0000000000..68364780f1 --- /dev/null +++ b/packages/cli/src/mirror/getWorldConsumerStorageHash.test.ts @@ -0,0 +1,10 @@ +import { describe, expect, it } from "vitest"; +import { getWorldConsumerStorageHash } from "./getWorldConsumerStorageHash"; + +describe("getWorldConsumerStorageHash", () => { + it("returns the storage hash", () => { + expect(getWorldConsumerStorageHash("0x253eb85B3C953bFE3827CC14a151262482E7189C")).toBe( + "0xcdb3e62b7ac1760b56fcd0ba2817b5f17160f89333ebef26a79db4b4ecab7e7f", + ); + }); +}); diff --git a/packages/cli/src/mirror/getWorldConsumerStorageHash.ts b/packages/cli/src/mirror/getWorldConsumerStorageHash.ts new file mode 100644 index 0000000000..8a5817a287 --- /dev/null +++ b/packages/cli/src/mirror/getWorldConsumerStorageHash.ts @@ -0,0 +1,10 @@ +import { Hex, concatHex, keccak256, stringToHex, toRlp } from "viem"; + +// keep aligned with StoreSwitch.sol +export const storeSwitchSlot = keccak256(stringToHex("mud.store.storage.StoreSwitch")); + +export function getWorldConsumerStorageHash(worldAddress: Hex) { + const path = concatHex(["0x20", keccak256(storeSwitchSlot)]); + const leaf = toRlp([path, toRlp(worldAddress)]); + return keccak256(leaf); +} diff --git a/packages/cli/src/mirror/mirror.ts b/packages/cli/src/mirror/mirror.ts new file mode 100644 index 0000000000..60946589f2 --- /dev/null +++ b/packages/cli/src/mirror/mirror.ts @@ -0,0 +1,48 @@ +import path from "node:path"; +import { Account, Address, Chain, Client, Transport } from "viem"; +import { createMirrorPlan } from "./createMirrorPlan"; +import { executeMirrorPlan } from "./executeMirrorPlan"; + +// TODO: attempt to create world the same way as it was originally created, thus preserving world address +// TODO: set up table to track migrated records with original metadata (block number/timestamp) and for lazy migrations + +export async function mirror({ + rootDir, + from, + to, +}: { + rootDir: string; + from: { + client: Client; + indexer: string; + world: Address; + block?: bigint; + blockscout: string; + }; + to: { + client: Client; + world: Address; + block?: bigint; + }; +}) { + // TODO: check for world balance, warn + // TODO: deploy world + // + + // TODO: fetch data from indexer + // TODO: check each system for state/balance, warn + // + // TODO: set records for each table + // + // TODO: deploy each system via original bytecode + // TODO: update system addresses as necessary (should this be done as part of setting records?) + // + + console.log("creating plan"); + const planFilename = await createMirrorPlan({ rootDir, from }); + + // TODO: show plan summary, prompt to continue + + console.log("executing plan at", path.relative(rootDir, planFilename)); + await executeMirrorPlan({ planFilename, to }); +} diff --git a/packages/cli/src/mirror/readPlan.ts b/packages/cli/src/mirror/readPlan.ts new file mode 100644 index 0000000000..59e80b4bd4 --- /dev/null +++ b/packages/cli/src/mirror/readPlan.ts @@ -0,0 +1,15 @@ +import { createGunzip } from "node:zlib"; +import readline from "node:readline"; +import { createReadStream } from "node:fs"; +import { PlanStep } from "./common"; + +export async function* readPlan(filename: string): AsyncGenerator { + const lines = readline.createInterface({ + input: createReadStream(filename).pipe(createGunzip()), + crlfDelay: Infinity, + }); + for await (const line of lines) { + if (line.trim().length === 0) continue; + yield JSON.parse(line); + } +} diff --git a/packages/store-sync/src/exports/internal.ts b/packages/store-sync/src/exports/internal.ts index ec9a119473..9a9e8ac6cc 100644 --- a/packages/store-sync/src/exports/internal.ts +++ b/packages/store-sync/src/exports/internal.ts @@ -1,5 +1,10 @@ +export * from "../getRecords"; + // SQL -export * from "../sql"; +export * from "../sql/common"; +export * from "../sql/fetchRecords"; +export * from "../sql/selectFrom"; +export * from "../sql/getSnapshot"; // Stash export * from "../stash/common"; diff --git a/packages/store-sync/src/getRecords.ts b/packages/store-sync/src/getRecords.ts index c831417d4c..a538443f46 100644 --- a/packages/store-sync/src/getRecords.ts +++ b/packages/store-sync/src/getRecords.ts @@ -43,46 +43,48 @@ type GetRecordsResult
= { export async function getRecords
( options: GetRecordsOptions
, ): Promise> { - async function getLogs(): Promise { - if (options.indexerUrl && options.chainId) { - debug("fetching records for", options.table.label, "via indexer from", options.indexerUrl); - const logs = await getSnapshot({ - chainId: options.chainId, - address: options.worldAddress, - indexerUrl: options.indexerUrl, - filters: [{ tableId: options.table.tableId }], - }); - // By default, the indexer includes the `store.Tables` table as part of the snapshot. - // Once we change this default, we can remove the filter here. - // See https://github.com/latticexyz/mud/issues/3386. - return logs?.logs.filter((log) => log.args.tableId === options.table.tableId) ?? []; - } else { - const client = - options.client ?? - createClient({ - transport: http(options.rpcUrl), - }); - debug("fetching records for", options.table.label, "via RPC from", client.transport.url); - const blockLogs = await fetchBlockLogs({ - fromBlock: options.fromBlock ?? 0n, - toBlock: options.toBlock ?? (await getAction(client, getBlockNumber, "getBlockNumber")({})), - maxBlockRange: 100_000n, - async getLogs({ fromBlock, toBlock }) { - return getStoreLogs(client, { - address: options.worldAddress, - fromBlock, - toBlock, - tableId: options.table.tableId, - }); - }, - }); - return flattenStoreLogs(blockLogs.flatMap((block) => block.logs)); - } - } - - const logs = await getLogs(); - const records = logs.map((log) => logToRecord({ log: log as LogToRecordArgs
["log"], table: options.table })); + const logs = await getRecordsAsLogs(options); + const records = logs.map((log) => logToRecord({ log: log as never, table: options.table })); const blockNumber = logs.length > 0 ? logs[logs.length - 1].blockNumber ?? 0n : 0n; debug("found", records.length, "records for table", options.table.label, "at block", blockNumber); return { records, blockNumber }; } + +export async function getRecordsAsLogs
( + options: GetRecordsOptions
, +): Promise[]> { + if (options.indexerUrl && options.chainId) { + debug("fetching records for", options.table.label, "via indexer from", options.indexerUrl); + const snapshot = await getSnapshot({ + chainId: options.chainId, + address: options.worldAddress, + indexerUrl: options.indexerUrl, + filters: [{ tableId: options.table.tableId }], + }); + // By default, the indexer includes the `store.Tables` table as part of the snapshot. + // Once we change this default, we can remove the filter here. + // See https://github.com/latticexyz/mud/issues/3386. + return (snapshot?.logs.filter((log) => log.args.tableId === options.table.tableId) ?? []) as never; + } + + const client = + options.client ?? + createClient({ + transport: http(options.rpcUrl), + }); + debug("fetching records for", options.table.label, "via RPC from", client.transport.url); + const blockLogs = await fetchBlockLogs({ + fromBlock: options.fromBlock ?? 0n, + toBlock: options.toBlock ?? (await getAction(client, getBlockNumber, "getBlockNumber")({})), + maxBlockRange: 100_000n, + async getLogs({ fromBlock, toBlock }) { + return getStoreLogs(client, { + address: options.worldAddress, + fromBlock, + toBlock, + tableId: options.table.tableId, + }); + }, + }); + return flattenStoreLogs(blockLogs.flatMap((block) => block.logs)); +} diff --git a/packages/store-sync/src/sql/getSnapshot.ts b/packages/store-sync/src/sql/getSnapshot.ts index 1dd68ff9c1..858c63a7dd 100644 --- a/packages/store-sync/src/sql/getSnapshot.ts +++ b/packages/store-sync/src/sql/getSnapshot.ts @@ -49,7 +49,7 @@ export async function getSnapshot({ }); if (logsFilters && logsFilters.length === 0) { - return undefined; + return; } return getSnapshotLogs({ diff --git a/packages/store-sync/src/sql/index.ts b/packages/store-sync/src/sql/index.ts deleted file mode 100644 index aeeec5224e..0000000000 --- a/packages/store-sync/src/sql/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -export * from "./common"; -export * from "./fetchRecords"; -export * from "./selectFrom"; -export * from "./getSnapshot"; diff --git a/packages/store/ts/exports/index.ts b/packages/store/ts/exports/index.ts index a4385f20af..7b288bd81b 100644 --- a/packages/store/ts/exports/index.ts +++ b/packages/store/ts/exports/index.ts @@ -15,6 +15,7 @@ export { export { storeEventsAbi } from "../storeEventsAbi"; export type { StoreEventsAbi, StoreEventsAbiItem } from "../storeEventsAbi"; +export type { StoreLog } from "../storeLog"; export { defineStore } from "../config/v2/store"; export type { StoreInput } from "../config/v2/input"; diff --git a/packages/store/ts/storeEventsAbi.ts b/packages/store/ts/storeEventsAbi.ts index dbe26f3bac..e059d0b4f3 100644 --- a/packages/store/ts/storeEventsAbi.ts +++ b/packages/store/ts/storeEventsAbi.ts @@ -7,4 +7,4 @@ export type storeEventsAbi = typeof storeEventsAbi; export type StoreEventsAbi = typeof storeEventsAbi; export type StoreEventsAbiItem = (typeof storeEventsAbi)[number]; -export type StoreSetRecordEventAbiItem = StoreEventsAbiItem & { readonly name: "Store_SetRecord" }; +export type StoreSetRecordEventAbiItem = Extract; diff --git a/packages/world-module-batchstore/package.json b/packages/world-module-batchstore/package.json index 3f6f4c8012..6266ce5d4f 100644 --- a/packages/world-module-batchstore/package.json +++ b/packages/world-module-batchstore/package.json @@ -44,7 +44,8 @@ "dependencies": { "@latticexyz/schema-type": "workspace:*", "@latticexyz/store": "workspace:*", - "@latticexyz/world": "workspace:*" + "@latticexyz/world": "workspace:*", + "solady": "^0.1.26" }, "devDependencies": { "@latticexyz/abi-ts": "workspace:*", diff --git a/packages/world-module-batchstore/remappings.txt b/packages/world-module-batchstore/remappings.txt index e2614d0aa8..3d8d9f5774 100644 --- a/packages/world-module-batchstore/remappings.txt +++ b/packages/world-module-batchstore/remappings.txt @@ -1,2 +1,3 @@ forge-std/=node_modules/forge-std/src/ @latticexyz/=node_modules/@latticexyz/ +solady/=node_modules/solady/src/ diff --git a/packages/world-module-batchstore/src/BatchStoreSystem.sol b/packages/world-module-batchstore/src/BatchStoreSystem.sol index c984c7b9c6..8e26a038ca 100644 --- a/packages/world-module-batchstore/src/BatchStoreSystem.sol +++ b/packages/world-module-batchstore/src/BatchStoreSystem.sol @@ -4,20 +4,23 @@ pragma solidity >=0.8.24; import { ResourceId } from "@latticexyz/store/src/ResourceId.sol"; import { System } from "@latticexyz/world/src/System.sol"; import { AccessControl } from "@latticexyz/world/src/AccessControl.sol"; +import { ROOT_NAMESPACE_ID } from "@latticexyz/world/src/constants.sol"; import { StoreCore } from "@latticexyz/store/src/StoreCore.sol"; import { EncodedLengths } from "@latticexyz/store/src/EncodedLengths.sol"; import { FieldLayout } from "@latticexyz/store/src/FieldLayout.sol"; import { TableRecord } from "./common.sol"; +import { LibZip } from "solady/utils/LibZip.sol"; +import { revertWithBytes } from "@latticexyz/world/src/revertWithBytes.sol"; +import { IBaseWorld } from "@latticexyz/world/src/codegen/interfaces/IBaseWorld.sol"; contract BatchStoreSystem is System { function getTableRecords( ResourceId tableId, bytes32[][] memory keyTuples ) external view returns (TableRecord[] memory records) { - AccessControl._requireAccess(tableId, _msgSender()); + records = new TableRecord[](keyTuples.length); FieldLayout fieldLayout = StoreCore.getFieldLayout(tableId); - records = new TableRecord[](keyTuples.length); for (uint256 i = 0; i < keyTuples.length; i++) { (bytes memory staticData, EncodedLengths encodedLengths, bytes memory dynamicData) = StoreCore.getRecord( @@ -35,7 +38,9 @@ contract BatchStoreSystem is System { } function setTableRecords(ResourceId tableId, TableRecord[] memory records) external { - AccessControl._requireAccess(tableId, _msgSender()); + AccessControl.requireAccess(tableId, _msgSender()); + + FieldLayout fieldLayout = StoreCore.getFieldLayout(tableId); for (uint256 i = 0; i < records.length; i++) { StoreCore.setRecord( @@ -43,13 +48,14 @@ contract BatchStoreSystem is System { records[i].keyTuple, records[i].staticData, records[i].encodedLengths, - records[i].dynamicData + records[i].dynamicData, + fieldLayout ); } } function deleteTableRecords(ResourceId tableId, bytes32[][] memory keyTuples) external { - AccessControl._requireAccess(tableId, _msgSender()); + AccessControl.requireAccess(tableId, _msgSender()); FieldLayout fieldLayout = StoreCore.getFieldLayout(tableId); @@ -57,4 +63,39 @@ contract BatchStoreSystem is System { StoreCore.deleteRecord(tableId, keyTuples[i], fieldLayout); } } + + function _setTableRecords(ResourceId tableId, TableRecord[] memory records) public { + AccessControl.requireOwner(ROOT_NAMESPACE_ID, _msgSender()); + + FieldLayout fieldLayout = StoreCore.getFieldLayout(tableId); + + for (uint256 i = 0; i < records.length; i++) { + StoreCore.setRecord( + tableId, + records[i].keyTuple, + records[i].staticData, + records[i].encodedLengths, + records[i].dynamicData, + fieldLayout + ); + } + } + + function _deleteTableRecords(ResourceId tableId, bytes32[][] memory keyTuples) external { + AccessControl.requireOwner(ROOT_NAMESPACE_ID, _msgSender()); + + FieldLayout fieldLayout = StoreCore.getFieldLayout(tableId); + + for (uint256 i = 0; i < keyTuples.length; i++) { + StoreCore.deleteRecord(tableId, keyTuples[i], fieldLayout); + } + } + + function _setTableRecords_flz(bytes calldata data) external { + (ResourceId tableId, TableRecord[] memory records) = abi.decode( + LibZip.flzDecompress(data), + (ResourceId, TableRecord[]) + ); + _setTableRecords(tableId, records); + } } diff --git a/packages/world-module-batchstore/src/codegen/experimental/systems/BatchStoreSystemLib.sol b/packages/world-module-batchstore/src/codegen/experimental/systems/BatchStoreSystemLib.sol index 0f3fce2f18..ad11162c10 100644 --- a/packages/world-module-batchstore/src/codegen/experimental/systems/BatchStoreSystemLib.sol +++ b/packages/world-module-batchstore/src/codegen/experimental/systems/BatchStoreSystemLib.sol @@ -54,6 +54,18 @@ library BatchStoreSystemLib { return CallWrapper(self.toResourceId(), address(0)).deleteTableRecords(tableId, keyTuples); } + function _setTableRecords(BatchStoreSystemType self, ResourceId tableId, TableRecord[] memory records) internal { + return CallWrapper(self.toResourceId(), address(0))._setTableRecords(tableId, records); + } + + function _deleteTableRecords(BatchStoreSystemType self, ResourceId tableId, bytes32[][] memory keyTuples) internal { + return CallWrapper(self.toResourceId(), address(0))._deleteTableRecords(tableId, keyTuples); + } + + function _setTableRecords_flz(BatchStoreSystemType self, bytes memory data) internal { + return CallWrapper(self.toResourceId(), address(0))._setTableRecords_flz(data); + } + function getTableRecords( CallWrapper memory self, ResourceId tableId, @@ -105,6 +117,42 @@ library BatchStoreSystemLib { : _world().callFrom(self.from, self.systemId, systemCall); } + function _setTableRecords(CallWrapper memory self, ResourceId tableId, TableRecord[] memory records) internal { + // if the contract calling this function is a root system, it should use `callAsRoot` + if (address(_world()) == address(this)) revert BatchStoreSystemLib_CallingFromRootSystem(); + + bytes memory systemCall = abi.encodeCall( + __setTableRecords_ResourceId_TableRecordArray._setTableRecords, + (tableId, records) + ); + self.from == address(0) + ? _world().call(self.systemId, systemCall) + : _world().callFrom(self.from, self.systemId, systemCall); + } + + function _deleteTableRecords(CallWrapper memory self, ResourceId tableId, bytes32[][] memory keyTuples) internal { + // if the contract calling this function is a root system, it should use `callAsRoot` + if (address(_world()) == address(this)) revert BatchStoreSystemLib_CallingFromRootSystem(); + + bytes memory systemCall = abi.encodeCall( + __deleteTableRecords_ResourceId_bytes32ArrayArray._deleteTableRecords, + (tableId, keyTuples) + ); + self.from == address(0) + ? _world().call(self.systemId, systemCall) + : _world().callFrom(self.from, self.systemId, systemCall); + } + + function _setTableRecords_flz(CallWrapper memory self, bytes memory data) internal { + // if the contract calling this function is a root system, it should use `callAsRoot` + if (address(_world()) == address(this)) revert BatchStoreSystemLib_CallingFromRootSystem(); + + bytes memory systemCall = abi.encodeCall(__setTableRecords_flz_bytes._setTableRecords_flz, (data)); + self.from == address(0) + ? _world().call(self.systemId, systemCall) + : _world().callFrom(self.from, self.systemId, systemCall); + } + function setTableRecords(RootCallWrapper memory self, ResourceId tableId, TableRecord[] memory records) internal { bytes memory systemCall = abi.encodeCall( _setTableRecords_ResourceId_TableRecordArray.setTableRecords, @@ -121,6 +169,27 @@ library BatchStoreSystemLib { SystemCall.callWithHooksOrRevert(self.from, self.systemId, systemCall, msg.value); } + function _setTableRecords(RootCallWrapper memory self, ResourceId tableId, TableRecord[] memory records) internal { + bytes memory systemCall = abi.encodeCall( + __setTableRecords_ResourceId_TableRecordArray._setTableRecords, + (tableId, records) + ); + SystemCall.callWithHooksOrRevert(self.from, self.systemId, systemCall, msg.value); + } + + function _deleteTableRecords(RootCallWrapper memory self, ResourceId tableId, bytes32[][] memory keyTuples) internal { + bytes memory systemCall = abi.encodeCall( + __deleteTableRecords_ResourceId_bytes32ArrayArray._deleteTableRecords, + (tableId, keyTuples) + ); + SystemCall.callWithHooksOrRevert(self.from, self.systemId, systemCall, msg.value); + } + + function _setTableRecords_flz(RootCallWrapper memory self, bytes memory data) internal { + bytes memory systemCall = abi.encodeCall(__setTableRecords_flz_bytes._setTableRecords_flz, (data)); + SystemCall.callWithHooksOrRevert(self.from, self.systemId, systemCall, msg.value); + } + function callFrom(BatchStoreSystemType self, address from) internal pure returns (CallWrapper memory) { return CallWrapper(self.toResourceId(), from); } @@ -171,6 +240,18 @@ interface _deleteTableRecords_ResourceId_bytes32ArrayArray { function deleteTableRecords(ResourceId tableId, bytes32[][] memory keyTuples) external; } +interface __setTableRecords_ResourceId_TableRecordArray { + function _setTableRecords(ResourceId tableId, TableRecord[] memory records) external; +} + +interface __deleteTableRecords_ResourceId_bytes32ArrayArray { + function _deleteTableRecords(ResourceId tableId, bytes32[][] memory keyTuples) external; +} + +interface __setTableRecords_flz_bytes { + function _setTableRecords_flz(bytes memory data) external; +} + using BatchStoreSystemLib for BatchStoreSystemType global; using BatchStoreSystemLib for CallWrapper global; using BatchStoreSystemLib for RootCallWrapper global; diff --git a/packages/world-module-batchstore/test/BatchStoreModule.t.sol b/packages/world-module-batchstore/test/BatchStoreModule.t.sol index dadf0debc0..b51bec57e8 100644 --- a/packages/world-module-batchstore/test/BatchStoreModule.t.sol +++ b/packages/world-module-batchstore/test/BatchStoreModule.t.sol @@ -96,4 +96,46 @@ contract BatchStoreModuleTest is Test, GasReporter { assertEq(NamespaceOwner.get(namespace), address(0)); } + + function testRootSetTableRecords() public { + world.installRootModule(batchStoreModule, new bytes(0)); + + ResourceId namespace = WorldResourceIdLib.encodeNamespace("example"); + assertEq(NamespaceOwner.get(namespace), address(0)); + + TableRecord[] memory records = new TableRecord[](1); + (bytes memory staticData, EncodedLengths encodedLengths, bytes memory dynamicData) = NamespaceOwner.encode( + address(this) + ); + records[0] = TableRecord({ + keyTuple: NamespaceOwner.encodeKeyTuple(WorldResourceIdLib.encodeNamespace("example")), + staticData: staticData, + encodedLengths: encodedLengths, + dynamicData: dynamicData + }); + + startGasReport("set table records"); + batchStoreSystem._setTableRecords(NamespaceOwner._tableId, records); + endGasReport(); + + assertEq(NamespaceOwner.get(namespace), address(this)); + } + + function testRootDeleteTableRecords() public { + world.installRootModule(batchStoreModule, new bytes(0)); + + ResourceId namespace = WorldResourceIdLib.encodeNamespace("example"); + NamespaceOwner.set(namespace, address(this)); + + assertEq(NamespaceOwner.get(namespace), address(this)); + + bytes32[][] memory keys = new bytes32[][](1); + keys[0] = NamespaceOwner.encodeKeyTuple(namespace); + + startGasReport("delete table records"); + batchStoreSystem._deleteTableRecords(NamespaceOwner._tableId, keys); + endGasReport(); + + assertEq(NamespaceOwner.get(namespace), address(0)); + } } diff --git a/packages/world/ts/exports/internal.ts b/packages/world/ts/exports/internal.ts index bcde49a6b0..d3e190a13e 100644 --- a/packages/world/ts/exports/internal.ts +++ b/packages/world/ts/exports/internal.ts @@ -2,6 +2,7 @@ export * from "../encodeSystemCall"; export * from "../encodeSystemCallFrom"; export * from "../encodeSystemCalls"; export * from "../encodeSystemCallsFrom"; +export * from "../worldCallAbi"; export * from "../actions/callFrom"; export * from "../actions/sendUserOperationFrom"; diff --git a/packages/world/ts/node/common.ts b/packages/world/ts/node/common.ts index 2c4c615cbb..ccf03bc833 100644 --- a/packages/world/ts/node/common.ts +++ b/packages/world/ts/node/common.ts @@ -4,7 +4,8 @@ import { Abi, Hex } from "viem"; export const contractSizeLimit = parseInt("6000", 16); // relative to project root dir (`rootDir`) -export const systemsManifestFilename = ".mud/local/systems.json"; +export const mudDataDirectory = ".mud"; +export const systemsManifestFilename = `${mudDataDirectory}/local/systems.json`; export type ReferenceIdentifier = { /** diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 13d9c02637..db076420ee 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -106,7 +106,7 @@ importers: version: 0.8.4(typescript@5.4.2)(zod@3.23.8) porto: specifier: 0.0.76 - version: 0.0.76(@tanstack/react-query@5.83.0(react@19.1.0))(@types/react@18.2.22)(@wagmi/core@2.20.0(@tanstack/query-core@5.83.0)(@types/react@18.2.22)(react@19.1.0)(typescript@5.4.2)(use-sync-external-store@1.4.0(react@19.1.0))(viem@2.35.1(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8)))(react@19.1.0)(typescript@5.4.2)(use-sync-external-store@1.4.0(react@19.1.0))(viem@2.35.1(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8))(wagmi@2.16.5(@tanstack/query-core@5.83.0)(@tanstack/react-query@5.83.0(react@19.1.0))(@types/react@18.2.22)(bufferutil@4.0.8)(encoding@0.1.13)(react@19.1.0)(typescript@5.4.2)(utf-8-validate@5.0.10)(viem@2.35.1(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8))(zod@3.23.8))(zod@3.23.8) + version: 0.0.76(@tanstack/react-query@5.83.0(react@19.1.0))(@types/react@18.2.22)(@wagmi/core@2.20.0(@tanstack/query-core@5.83.0)(@types/react@18.2.22)(react@19.1.0)(typescript@5.4.2)(use-sync-external-store@1.4.0(react@19.1.0))(viem@2.35.1(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8)))(react@19.1.0)(typescript@5.4.2)(use-sync-external-store@1.4.0(react@19.1.0))(viem@2.35.1(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8))(wagmi@2.16.5(@tanstack/query-core@5.83.0)(@tanstack/react-query@5.83.0(react@19.1.0))(@types/react@18.2.22)(@upstash/redis@1.34.9)(bufferutil@4.0.8)(encoding@0.1.13)(react@19.1.0)(typescript@5.4.2)(utf-8-validate@5.0.10)(viem@2.35.1(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8))(zod@3.23.8))(zod@3.23.8) react: specifier: ^19.1.0 version: 19.1.0 @@ -124,7 +124,7 @@ importers: version: 2.35.1(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8) wagmi: specifier: 2.16.5 - version: 2.16.5(@tanstack/query-core@5.83.0)(@tanstack/react-query@5.83.0(react@19.1.0))(@types/react@18.2.22)(bufferutil@4.0.8)(encoding@0.1.13)(react@19.1.0)(typescript@5.4.2)(utf-8-validate@5.0.10)(viem@2.35.1(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8))(zod@3.23.8) + version: 2.16.5(@tanstack/query-core@5.83.0)(@tanstack/react-query@5.83.0(react@19.1.0))(@types/react@18.2.22)(@upstash/redis@1.34.9)(bufferutil@4.0.8)(encoding@0.1.13)(react@19.1.0)(typescript@5.4.2)(utf-8-validate@5.0.10)(viem@2.35.1(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8))(zod@3.23.8) zustand: specifier: ^5.0.6 version: 5.0.6(@types/react@18.2.22)(react@19.1.0)(use-sync-external-store@1.4.0(react@19.1.0)) @@ -284,6 +284,9 @@ importers: rxjs: specifier: 7.5.5 version: 7.5.5 + solady: + specifier: ^0.1.26 + version: 0.1.26 throttle-debounce: specifier: ^5.0.0 version: 5.0.0 @@ -519,7 +522,7 @@ importers: version: 2.20.2(@types/react@18.2.22)(@upstash/redis@1.34.9)(bufferutil@4.0.8)(encoding@0.1.13)(react@18.2.0)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8) connectkit: specifier: ^1.9.0 - version: 1.9.0(@babel/core@7.25.2)(@tanstack/react-query@5.56.2(react@18.2.0))(react-dom@18.2.0(react@18.2.0))(react-is@18.2.0)(react@18.2.0)(viem@2.35.1(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8))(wagmi@2.16.5(@tanstack/query-core@5.83.0)(@tanstack/react-query@5.56.2(react@18.2.0))(@types/react@18.2.22)(@upstash/redis@1.34.9)(bufferutil@4.0.8)(encoding@0.1.13)(react@18.2.0)(typescript@5.4.2)(utf-8-validate@5.0.10)(viem@2.35.1(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8))(zod@3.23.8)) + version: 1.9.0(@babel/core@7.28.0)(@tanstack/react-query@5.56.2(react@18.2.0))(react-dom@18.2.0(react@18.2.0))(react-is@18.2.0)(react@18.2.0)(viem@2.35.1(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8))(wagmi@2.16.5(@tanstack/query-core@5.83.0)(@tanstack/react-query@5.56.2(react@18.2.0))(@types/react@18.2.22)(@upstash/redis@1.34.9)(bufferutil@4.0.8)(encoding@0.1.13)(react@18.2.0)(typescript@5.4.2)(utf-8-validate@5.0.10)(viem@2.35.1(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8))(zod@3.23.8)) debug: specifier: ^4.3.4 version: 4.3.7 @@ -676,7 +679,7 @@ importers: version: 3.1.3(@types/react-dom@18.2.7)(@types/react@18.2.22)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) '@rainbow-me/rainbowkit': specifier: ^2.2.6 - version: 2.2.6(@tanstack/react-query@5.52.0(react@18.2.0))(@types/react@18.2.22)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(viem@2.35.1(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8))(wagmi@2.16.5(@tanstack/query-core@5.83.0)(@tanstack/react-query@5.52.0(react@18.2.0))(@types/react@18.2.22)(bufferutil@4.0.8)(encoding@0.1.13)(react@18.2.0)(typescript@5.4.2)(utf-8-validate@5.0.10)(viem@2.35.1(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8))(zod@3.23.8)) + version: 2.2.6(@tanstack/react-query@5.52.0(react@18.2.0))(@types/react@18.2.22)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(viem@2.35.1(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8))(wagmi@2.16.5(@tanstack/query-core@5.83.0)(@tanstack/react-query@5.52.0(react@18.2.0))(@types/react@18.2.22)(@upstash/redis@1.34.9)(bufferutil@4.0.8)(encoding@0.1.13)(react@18.2.0)(typescript@5.4.2)(utf-8-validate@5.0.10)(viem@2.35.1(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8))(zod@3.23.8)) '@tanstack/react-query': specifier: ^5.51.3 version: 5.52.0(react@18.2.0) @@ -742,7 +745,7 @@ importers: version: 1.12.0 wagmi: specifier: 2.16.5 - version: 2.16.5(@tanstack/query-core@5.83.0)(@tanstack/react-query@5.52.0(react@18.2.0))(@types/react@18.2.22)(bufferutil@4.0.8)(encoding@0.1.13)(react@18.2.0)(typescript@5.4.2)(utf-8-validate@5.0.10)(viem@2.35.1(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8))(zod@3.23.8) + version: 2.16.5(@tanstack/query-core@5.83.0)(@tanstack/react-query@5.52.0(react@18.2.0))(@types/react@18.2.22)(@upstash/redis@1.34.9)(bufferutil@4.0.8)(encoding@0.1.13)(react@18.2.0)(typescript@5.4.2)(utf-8-validate@5.0.10)(viem@2.35.1(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8))(zod@3.23.8) yargs: specifier: ^17.7.1 version: 17.7.2 @@ -874,7 +877,7 @@ importers: version: 4.4.1(supports-color@5.5.0) porto: specifier: 0.0.76 - version: 0.0.76(@tanstack/react-query@5.83.0(react@19.1.0))(@types/react@18.2.22)(@wagmi/core@2.20.0(@tanstack/query-core@5.83.0)(@types/react@18.2.22)(react@19.1.0)(typescript@5.4.2)(use-sync-external-store@1.4.0(react@19.1.0))(viem@2.35.1(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8)))(react@19.1.0)(typescript@5.4.2)(use-sync-external-store@1.4.0(react@19.1.0))(viem@2.35.1(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8))(wagmi@2.16.5(@tanstack/query-core@5.83.0)(@tanstack/react-query@5.83.0(react@19.1.0))(@types/react@18.2.22)(bufferutil@4.0.8)(encoding@0.1.13)(react@19.1.0)(typescript@5.4.2)(utf-8-validate@5.0.10)(viem@2.35.1(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8))(zod@3.23.8))(zod@3.23.8) + version: 0.0.76(@tanstack/react-query@5.83.0(react@19.1.0))(@types/react@18.2.22)(@wagmi/core@2.20.0(@tanstack/query-core@5.83.0)(@types/react@18.2.22)(react@19.1.0)(typescript@5.4.2)(use-sync-external-store@1.4.0(react@19.1.0))(viem@2.35.1(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8)))(react@19.1.0)(typescript@5.4.2)(use-sync-external-store@1.4.0(react@19.1.0))(viem@2.35.1(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8))(wagmi@2.16.5(@tanstack/query-core@5.83.0)(@tanstack/react-query@5.83.0(react@19.1.0))(@types/react@18.2.22)(@upstash/redis@1.34.9)(bufferutil@4.0.8)(encoding@0.1.13)(react@19.1.0)(typescript@5.4.2)(utf-8-validate@5.0.10)(viem@2.35.1(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8))(zod@3.23.8))(zod@3.23.8) devDependencies: '@types/debug': specifier: ^4.1.7 @@ -884,7 +887,7 @@ importers: version: 2.35.1(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8) wagmi: specifier: 2.16.5 - version: 2.16.5(@tanstack/query-core@5.83.0)(@tanstack/react-query@5.83.0(react@19.1.0))(@types/react@18.2.22)(bufferutil@4.0.8)(encoding@0.1.13)(react@19.1.0)(typescript@5.4.2)(utf-8-validate@5.0.10)(viem@2.35.1(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8))(zod@3.23.8) + version: 2.16.5(@tanstack/query-core@5.83.0)(@tanstack/react-query@5.83.0(react@19.1.0))(@types/react@18.2.22)(@upstash/redis@1.34.9)(bufferutil@4.0.8)(encoding@0.1.13)(react@19.1.0)(typescript@5.4.2)(utf-8-validate@5.0.10)(viem@2.35.1(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8))(zod@3.23.8) packages/paymaster: devDependencies: @@ -992,10 +995,10 @@ importers: version: 8.3.4 jest: specifier: ^29.3.1 - version: 29.5.0(@types/node@20.17.16) + version: 29.5.0(@types/node@24.3.0) ts-jest: specifier: ^29.0.5 - version: 29.0.5(@babel/core@7.28.0)(@jest/types@29.6.3)(babel-jest@29.5.0(@babel/core@7.28.0))(esbuild@0.23.1)(jest@29.5.0(@types/node@20.17.16))(typescript@5.4.2) + version: 29.0.5(@babel/core@7.28.0)(@jest/types@29.6.3)(babel-jest@29.5.0(@babel/core@7.28.0))(esbuild@0.23.1)(jest@29.5.0(@types/node@24.3.0))(typescript@5.4.2) type-fest: specifier: ^2.14.0 version: 2.14.0 @@ -1356,7 +1359,7 @@ importers: version: 2.35.1(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8) wagmi: specifier: 2.16.5 - version: 2.16.5(@tanstack/query-core@5.83.0)(@tanstack/react-query@5.56.2(react@18.2.0))(@types/react@18.2.22)(bufferutil@4.0.8)(encoding@0.1.13)(react@18.2.0)(typescript@5.4.2)(utf-8-validate@5.0.10)(viem@2.35.1(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8))(zod@3.23.8) + version: 2.16.5(@tanstack/query-core@5.83.0)(@tanstack/react-query@5.56.2(react@18.2.0))(@types/react@18.2.22)(@upstash/redis@1.34.9)(bufferutil@4.0.8)(encoding@0.1.13)(react@18.2.0)(typescript@5.4.2)(utf-8-validate@5.0.10)(viem@2.35.1(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8))(zod@3.23.8) packages/utils: dependencies: @@ -1375,10 +1378,10 @@ importers: version: 27.4.1 jest: specifier: ^29.3.1 - version: 29.5.0(@types/node@24.3.0) + version: 29.5.0(@types/node@20.17.16) ts-jest: specifier: ^29.0.5 - version: 29.0.5(@babel/core@7.28.0)(@jest/types@29.6.3)(babel-jest@29.5.0(@babel/core@7.28.0))(esbuild@0.23.1)(jest@29.5.0(@types/node@24.3.0))(typescript@5.4.2) + version: 29.0.5(@babel/core@7.28.0)(@jest/types@29.6.3)(babel-jest@29.5.0(@babel/core@7.28.0))(esbuild@0.23.1)(jest@29.5.0(@types/node@20.17.16))(typescript@5.4.2) packages/vite-plugin-mud: devDependencies: @@ -1483,6 +1486,9 @@ importers: '@latticexyz/world': specifier: workspace:* version: link:../world + solady: + specifier: ^0.1.26 + version: 0.1.26 devDependencies: '@latticexyz/abi-ts': specifier: workspace:* @@ -10699,6 +10705,9 @@ packages: resolution: {integrity: sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ==} engines: {node: '>= 10.13.0', npm: '>= 3.0.0'} + solady@0.1.26: + resolution: {integrity: sha512-dhGr/ptJFdea/1KE6xgqgwEdbMhUiSfRc6A+jLeltPe16zyt9qtED3PElIBVRnzEmUO5aZTjKVAr6SlqXBBcIw==} + solhint@3.3.7: resolution: {integrity: sha512-NjjjVmXI3ehKkb3aNtRJWw55SUVJ8HMKKodwe0HnejA+k0d2kmhw7jvpa+MCTbcEgt8IWSwx0Hu6aCo/iYOZzQ==} hasBin: true @@ -12832,9 +12841,9 @@ snapshots: '@babel/core': 7.28.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-jsx@7.27.1(@babel/core@7.25.2)': + '@babel/plugin-syntax-jsx@7.27.1(@babel/core@7.28.0)': dependencies: - '@babel/core': 7.25.2 + '@babel/core': 7.28.0 '@babel/helper-plugin-utils': 7.27.1 '@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.28.0)': @@ -15710,7 +15719,7 @@ snapshots: '@types/react': 18.2.22 '@types/react-dom': 18.2.7 - '@rainbow-me/rainbowkit@2.2.6(@tanstack/react-query@5.52.0(react@18.2.0))(@types/react@18.2.22)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(viem@2.35.1(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8))(wagmi@2.16.5(@tanstack/query-core@5.83.0)(@tanstack/react-query@5.52.0(react@18.2.0))(@types/react@18.2.22)(bufferutil@4.0.8)(encoding@0.1.13)(react@18.2.0)(typescript@5.4.2)(utf-8-validate@5.0.10)(viem@2.35.1(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8))(zod@3.23.8))': + '@rainbow-me/rainbowkit@2.2.6(@tanstack/react-query@5.52.0(react@18.2.0))(@types/react@18.2.22)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(viem@2.35.1(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8))(wagmi@2.16.5(@tanstack/query-core@5.83.0)(@tanstack/react-query@5.52.0(react@18.2.0))(@types/react@18.2.22)(@upstash/redis@1.34.9)(bufferutil@4.0.8)(encoding@0.1.13)(react@18.2.0)(typescript@5.4.2)(utf-8-validate@5.0.10)(viem@2.35.1(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8))(zod@3.23.8))': dependencies: '@tanstack/react-query': 5.52.0(react@18.2.0) '@vanilla-extract/css': 1.15.5 @@ -15723,7 +15732,7 @@ snapshots: react-remove-scroll: 2.6.2(@types/react@18.2.22)(react@18.2.0) ua-parser-js: 1.0.38 viem: 2.35.1(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8) - wagmi: 2.16.5(@tanstack/query-core@5.83.0)(@tanstack/react-query@5.52.0(react@18.2.0))(@types/react@18.2.22)(bufferutil@4.0.8)(encoding@0.1.13)(react@18.2.0)(typescript@5.4.2)(utf-8-validate@5.0.10)(viem@2.35.1(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8))(zod@3.23.8) + wagmi: 2.16.5(@tanstack/query-core@5.83.0)(@tanstack/react-query@5.52.0(react@18.2.0))(@types/react@18.2.22)(@upstash/redis@1.34.9)(bufferutil@4.0.8)(encoding@0.1.13)(react@18.2.0)(typescript@5.4.2)(utf-8-validate@5.0.10)(viem@2.35.1(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8))(zod@3.23.8) transitivePeerDependencies: - '@types/react' - babel-plugin-macros @@ -15834,37 +15843,7 @@ snapshots: - utf-8-validate - zod - '@reown/appkit-controllers@1.7.8(@types/react@18.2.22)(bufferutil@4.0.8)(encoding@0.1.13)(react@18.2.0)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8)': - dependencies: - '@reown/appkit-common': 1.7.8(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8) - '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10) - '@walletconnect/universal-provider': 2.21.0(@upstash/redis@1.34.9)(bufferutil@4.0.8)(encoding@0.1.13)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8) - valtio: 1.13.2(@types/react@18.2.22)(react@18.2.0) - viem: 2.35.1(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8) - transitivePeerDependencies: - - '@azure/app-configuration' - - '@azure/cosmos' - - '@azure/data-tables' - - '@azure/identity' - - '@azure/keyvault-secrets' - - '@azure/storage-blob' - - '@capacitor/preferences' - - '@netlify/blobs' - - '@planetscale/database' - - '@react-native-async-storage/async-storage' - - '@types/react' - - '@upstash/redis' - - '@vercel/kv' - - bufferutil - - encoding - - ioredis - - react - - typescript - - uWebSockets.js - - utf-8-validate - - zod - - '@reown/appkit-controllers@1.7.8(@types/react@18.2.22)(bufferutil@4.0.8)(encoding@0.1.13)(react@19.1.0)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8)': + '@reown/appkit-controllers@1.7.8(@types/react@18.2.22)(@upstash/redis@1.34.9)(bufferutil@4.0.8)(encoding@0.1.13)(react@19.1.0)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8)': dependencies: '@reown/appkit-common': 1.7.8(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8) '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10) @@ -15925,43 +15904,12 @@ snapshots: - utf-8-validate - zod - '@reown/appkit-pay@1.7.8(@types/react@18.2.22)(bufferutil@4.0.8)(encoding@0.1.13)(react@18.2.0)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8)': - dependencies: - '@reown/appkit-common': 1.7.8(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8) - '@reown/appkit-controllers': 1.7.8(@types/react@18.2.22)(bufferutil@4.0.8)(encoding@0.1.13)(react@18.2.0)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8) - '@reown/appkit-ui': 1.7.8(@types/react@18.2.22)(bufferutil@4.0.8)(encoding@0.1.13)(react@18.2.0)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8) - '@reown/appkit-utils': 1.7.8(@types/react@18.2.22)(bufferutil@4.0.8)(encoding@0.1.13)(react@18.2.0)(typescript@5.4.2)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@18.2.22)(react@18.2.0))(zod@3.23.8) - lit: 3.3.0 - valtio: 1.13.2(@types/react@18.2.22)(react@18.2.0) - transitivePeerDependencies: - - '@azure/app-configuration' - - '@azure/cosmos' - - '@azure/data-tables' - - '@azure/identity' - - '@azure/keyvault-secrets' - - '@azure/storage-blob' - - '@capacitor/preferences' - - '@netlify/blobs' - - '@planetscale/database' - - '@react-native-async-storage/async-storage' - - '@types/react' - - '@upstash/redis' - - '@vercel/kv' - - bufferutil - - encoding - - ioredis - - react - - typescript - - uWebSockets.js - - utf-8-validate - - zod - - '@reown/appkit-pay@1.7.8(@types/react@18.2.22)(bufferutil@4.0.8)(encoding@0.1.13)(react@19.1.0)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8)': + '@reown/appkit-pay@1.7.8(@types/react@18.2.22)(@upstash/redis@1.34.9)(bufferutil@4.0.8)(encoding@0.1.13)(react@19.1.0)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8)': dependencies: '@reown/appkit-common': 1.7.8(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8) - '@reown/appkit-controllers': 1.7.8(@types/react@18.2.22)(bufferutil@4.0.8)(encoding@0.1.13)(react@19.1.0)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8) - '@reown/appkit-ui': 1.7.8(@types/react@18.2.22)(bufferutil@4.0.8)(encoding@0.1.13)(react@19.1.0)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8) - '@reown/appkit-utils': 1.7.8(@types/react@18.2.22)(bufferutil@4.0.8)(encoding@0.1.13)(react@19.1.0)(typescript@5.4.2)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@18.2.22)(react@19.1.0))(zod@3.23.8) + '@reown/appkit-controllers': 1.7.8(@types/react@18.2.22)(@upstash/redis@1.34.9)(bufferutil@4.0.8)(encoding@0.1.13)(react@19.1.0)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8) + '@reown/appkit-ui': 1.7.8(@types/react@18.2.22)(@upstash/redis@1.34.9)(bufferutil@4.0.8)(encoding@0.1.13)(react@19.1.0)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8) + '@reown/appkit-utils': 1.7.8(@types/react@18.2.22)(@upstash/redis@1.34.9)(bufferutil@4.0.8)(encoding@0.1.13)(react@19.1.0)(typescript@5.4.2)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@18.2.22)(react@19.1.0))(zod@3.23.8) lit: 3.3.0 valtio: 1.13.2(@types/react@18.2.22)(react@19.1.0) transitivePeerDependencies: @@ -16059,44 +16007,12 @@ snapshots: - valtio - zod - '@reown/appkit-scaffold-ui@1.7.8(@types/react@18.2.22)(bufferutil@4.0.8)(encoding@0.1.13)(react@18.2.0)(typescript@5.4.2)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@18.2.22)(react@18.2.0))(zod@3.23.8)': - dependencies: - '@reown/appkit-common': 1.7.8(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8) - '@reown/appkit-controllers': 1.7.8(@types/react@18.2.22)(bufferutil@4.0.8)(encoding@0.1.13)(react@18.2.0)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8) - '@reown/appkit-ui': 1.7.8(@types/react@18.2.22)(bufferutil@4.0.8)(encoding@0.1.13)(react@18.2.0)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8) - '@reown/appkit-utils': 1.7.8(@types/react@18.2.22)(bufferutil@4.0.8)(encoding@0.1.13)(react@18.2.0)(typescript@5.4.2)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@18.2.22)(react@18.2.0))(zod@3.23.8) - '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10) - lit: 3.3.0 - transitivePeerDependencies: - - '@azure/app-configuration' - - '@azure/cosmos' - - '@azure/data-tables' - - '@azure/identity' - - '@azure/keyvault-secrets' - - '@azure/storage-blob' - - '@capacitor/preferences' - - '@netlify/blobs' - - '@planetscale/database' - - '@react-native-async-storage/async-storage' - - '@types/react' - - '@upstash/redis' - - '@vercel/kv' - - bufferutil - - encoding - - ioredis - - react - - typescript - - uWebSockets.js - - utf-8-validate - - valtio - - zod - - '@reown/appkit-scaffold-ui@1.7.8(@types/react@18.2.22)(bufferutil@4.0.8)(encoding@0.1.13)(react@19.1.0)(typescript@5.4.2)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@18.2.22)(react@19.1.0))(zod@3.23.8)': + '@reown/appkit-scaffold-ui@1.7.8(@types/react@18.2.22)(@upstash/redis@1.34.9)(bufferutil@4.0.8)(encoding@0.1.13)(react@19.1.0)(typescript@5.4.2)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@18.2.22)(react@19.1.0))(zod@3.23.8)': dependencies: '@reown/appkit-common': 1.7.8(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8) - '@reown/appkit-controllers': 1.7.8(@types/react@18.2.22)(bufferutil@4.0.8)(encoding@0.1.13)(react@19.1.0)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8) - '@reown/appkit-ui': 1.7.8(@types/react@18.2.22)(bufferutil@4.0.8)(encoding@0.1.13)(react@19.1.0)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8) - '@reown/appkit-utils': 1.7.8(@types/react@18.2.22)(bufferutil@4.0.8)(encoding@0.1.13)(react@19.1.0)(typescript@5.4.2)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@18.2.22)(react@19.1.0))(zod@3.23.8) + '@reown/appkit-controllers': 1.7.8(@types/react@18.2.22)(@upstash/redis@1.34.9)(bufferutil@4.0.8)(encoding@0.1.13)(react@19.1.0)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8) + '@reown/appkit-ui': 1.7.8(@types/react@18.2.22)(@upstash/redis@1.34.9)(bufferutil@4.0.8)(encoding@0.1.13)(react@19.1.0)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8) + '@reown/appkit-utils': 1.7.8(@types/react@18.2.22)(@upstash/redis@1.34.9)(bufferutil@4.0.8)(encoding@0.1.13)(react@19.1.0)(typescript@5.4.2)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@18.2.22)(react@19.1.0))(zod@3.23.8) '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10) lit: 3.3.0 transitivePeerDependencies: @@ -16183,40 +16099,10 @@ snapshots: - utf-8-validate - zod - '@reown/appkit-ui@1.7.8(@types/react@18.2.22)(bufferutil@4.0.8)(encoding@0.1.13)(react@18.2.0)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8)': + '@reown/appkit-ui@1.7.8(@types/react@18.2.22)(@upstash/redis@1.34.9)(bufferutil@4.0.8)(encoding@0.1.13)(react@19.1.0)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8)': dependencies: '@reown/appkit-common': 1.7.8(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8) - '@reown/appkit-controllers': 1.7.8(@types/react@18.2.22)(bufferutil@4.0.8)(encoding@0.1.13)(react@18.2.0)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8) - '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10) - lit: 3.3.0 - qrcode: 1.5.3 - transitivePeerDependencies: - - '@azure/app-configuration' - - '@azure/cosmos' - - '@azure/data-tables' - - '@azure/identity' - - '@azure/keyvault-secrets' - - '@azure/storage-blob' - - '@capacitor/preferences' - - '@netlify/blobs' - - '@planetscale/database' - - '@react-native-async-storage/async-storage' - - '@types/react' - - '@upstash/redis' - - '@vercel/kv' - - bufferutil - - encoding - - ioredis - - react - - typescript - - uWebSockets.js - - utf-8-validate - - zod - - '@reown/appkit-ui@1.7.8(@types/react@18.2.22)(bufferutil@4.0.8)(encoding@0.1.13)(react@19.1.0)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8)': - dependencies: - '@reown/appkit-common': 1.7.8(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8) - '@reown/appkit-controllers': 1.7.8(@types/react@18.2.22)(bufferutil@4.0.8)(encoding@0.1.13)(react@19.1.0)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8) + '@reown/appkit-controllers': 1.7.8(@types/react@18.2.22)(@upstash/redis@1.34.9)(bufferutil@4.0.8)(encoding@0.1.13)(react@19.1.0)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8) '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10) lit: 3.3.0 qrcode: 1.5.3 @@ -16309,43 +16195,10 @@ snapshots: - utf-8-validate - zod - '@reown/appkit-utils@1.7.8(@types/react@18.2.22)(bufferutil@4.0.8)(encoding@0.1.13)(react@18.2.0)(typescript@5.4.2)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@18.2.22)(react@18.2.0))(zod@3.23.8)': - dependencies: - '@reown/appkit-common': 1.7.8(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8) - '@reown/appkit-controllers': 1.7.8(@types/react@18.2.22)(bufferutil@4.0.8)(encoding@0.1.13)(react@18.2.0)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8) - '@reown/appkit-polyfills': 1.7.8 - '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10) - '@walletconnect/logger': 2.1.2 - '@walletconnect/universal-provider': 2.21.0(@upstash/redis@1.34.9)(bufferutil@4.0.8)(encoding@0.1.13)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8) - valtio: 1.13.2(@types/react@18.2.22)(react@18.2.0) - viem: 2.35.1(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8) - transitivePeerDependencies: - - '@azure/app-configuration' - - '@azure/cosmos' - - '@azure/data-tables' - - '@azure/identity' - - '@azure/keyvault-secrets' - - '@azure/storage-blob' - - '@capacitor/preferences' - - '@netlify/blobs' - - '@planetscale/database' - - '@react-native-async-storage/async-storage' - - '@types/react' - - '@upstash/redis' - - '@vercel/kv' - - bufferutil - - encoding - - ioredis - - react - - typescript - - uWebSockets.js - - utf-8-validate - - zod - - '@reown/appkit-utils@1.7.8(@types/react@18.2.22)(bufferutil@4.0.8)(encoding@0.1.13)(react@19.1.0)(typescript@5.4.2)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@18.2.22)(react@19.1.0))(zod@3.23.8)': + '@reown/appkit-utils@1.7.8(@types/react@18.2.22)(@upstash/redis@1.34.9)(bufferutil@4.0.8)(encoding@0.1.13)(react@19.1.0)(typescript@5.4.2)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@18.2.22)(react@19.1.0))(zod@3.23.8)': dependencies: '@reown/appkit-common': 1.7.8(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8) - '@reown/appkit-controllers': 1.7.8(@types/react@18.2.22)(bufferutil@4.0.8)(encoding@0.1.13)(react@19.1.0)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8) + '@reown/appkit-controllers': 1.7.8(@types/react@18.2.22)(@upstash/redis@1.34.9)(bufferutil@4.0.8)(encoding@0.1.13)(react@19.1.0)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8) '@reown/appkit-polyfills': 1.7.8 '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10) '@walletconnect/logger': 2.1.2 @@ -16472,53 +16325,15 @@ snapshots: - utf-8-validate - zod - '@reown/appkit@1.7.8(@types/react@18.2.22)(bufferutil@4.0.8)(encoding@0.1.13)(react@18.2.0)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8)': + '@reown/appkit@1.7.8(@types/react@18.2.22)(@upstash/redis@1.34.9)(bufferutil@4.0.8)(encoding@0.1.13)(react@19.1.0)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8)': dependencies: '@reown/appkit-common': 1.7.8(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8) - '@reown/appkit-controllers': 1.7.8(@types/react@18.2.22)(bufferutil@4.0.8)(encoding@0.1.13)(react@18.2.0)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8) - '@reown/appkit-pay': 1.7.8(@types/react@18.2.22)(bufferutil@4.0.8)(encoding@0.1.13)(react@18.2.0)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8) + '@reown/appkit-controllers': 1.7.8(@types/react@18.2.22)(@upstash/redis@1.34.9)(bufferutil@4.0.8)(encoding@0.1.13)(react@19.1.0)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8) + '@reown/appkit-pay': 1.7.8(@types/react@18.2.22)(@upstash/redis@1.34.9)(bufferutil@4.0.8)(encoding@0.1.13)(react@19.1.0)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8) '@reown/appkit-polyfills': 1.7.8 - '@reown/appkit-scaffold-ui': 1.7.8(@types/react@18.2.22)(bufferutil@4.0.8)(encoding@0.1.13)(react@18.2.0)(typescript@5.4.2)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@18.2.22)(react@18.2.0))(zod@3.23.8) - '@reown/appkit-ui': 1.7.8(@types/react@18.2.22)(bufferutil@4.0.8)(encoding@0.1.13)(react@18.2.0)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8) - '@reown/appkit-utils': 1.7.8(@types/react@18.2.22)(bufferutil@4.0.8)(encoding@0.1.13)(react@18.2.0)(typescript@5.4.2)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@18.2.22)(react@18.2.0))(zod@3.23.8) - '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10) - '@walletconnect/types': 2.21.0(@upstash/redis@1.34.9) - '@walletconnect/universal-provider': 2.21.0(@upstash/redis@1.34.9)(bufferutil@4.0.8)(encoding@0.1.13)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8) - bs58: 6.0.0 - valtio: 1.13.2(@types/react@18.2.22)(react@18.2.0) - viem: 2.35.1(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8) - transitivePeerDependencies: - - '@azure/app-configuration' - - '@azure/cosmos' - - '@azure/data-tables' - - '@azure/identity' - - '@azure/keyvault-secrets' - - '@azure/storage-blob' - - '@capacitor/preferences' - - '@netlify/blobs' - - '@planetscale/database' - - '@react-native-async-storage/async-storage' - - '@types/react' - - '@upstash/redis' - - '@vercel/kv' - - bufferutil - - encoding - - ioredis - - react - - typescript - - uWebSockets.js - - utf-8-validate - - zod - - '@reown/appkit@1.7.8(@types/react@18.2.22)(bufferutil@4.0.8)(encoding@0.1.13)(react@19.1.0)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8)': - dependencies: - '@reown/appkit-common': 1.7.8(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8) - '@reown/appkit-controllers': 1.7.8(@types/react@18.2.22)(bufferutil@4.0.8)(encoding@0.1.13)(react@19.1.0)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8) - '@reown/appkit-pay': 1.7.8(@types/react@18.2.22)(bufferutil@4.0.8)(encoding@0.1.13)(react@19.1.0)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8) - '@reown/appkit-polyfills': 1.7.8 - '@reown/appkit-scaffold-ui': 1.7.8(@types/react@18.2.22)(bufferutil@4.0.8)(encoding@0.1.13)(react@19.1.0)(typescript@5.4.2)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@18.2.22)(react@19.1.0))(zod@3.23.8) - '@reown/appkit-ui': 1.7.8(@types/react@18.2.22)(bufferutil@4.0.8)(encoding@0.1.13)(react@19.1.0)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8) - '@reown/appkit-utils': 1.7.8(@types/react@18.2.22)(bufferutil@4.0.8)(encoding@0.1.13)(react@19.1.0)(typescript@5.4.2)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@18.2.22)(react@19.1.0))(zod@3.23.8) + '@reown/appkit-scaffold-ui': 1.7.8(@types/react@18.2.22)(@upstash/redis@1.34.9)(bufferutil@4.0.8)(encoding@0.1.13)(react@19.1.0)(typescript@5.4.2)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@18.2.22)(react@19.1.0))(zod@3.23.8) + '@reown/appkit-ui': 1.7.8(@types/react@18.2.22)(@upstash/redis@1.34.9)(bufferutil@4.0.8)(encoding@0.1.13)(react@19.1.0)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8) + '@reown/appkit-utils': 1.7.8(@types/react@18.2.22)(@upstash/redis@1.34.9)(bufferutil@4.0.8)(encoding@0.1.13)(react@19.1.0)(typescript@5.4.2)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@18.2.22)(react@19.1.0))(zod@3.23.8) '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10) '@walletconnect/types': 2.21.0(@upstash/redis@1.34.9) '@walletconnect/universal-provider': 2.21.0(@upstash/redis@1.34.9)(bufferutil@4.0.8)(encoding@0.1.13)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8) @@ -17817,46 +17632,7 @@ snapshots: - utf-8-validate - zod - '@wagmi/connectors@5.9.5(@types/react@18.2.22)(@wagmi/core@2.20.0(@tanstack/query-core@5.83.0)(@types/react@18.2.22)(react@18.2.0)(typescript@5.4.2)(use-sync-external-store@1.4.0(react@18.2.0))(viem@2.35.1(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8)))(bufferutil@4.0.8)(encoding@0.1.13)(react@18.2.0)(typescript@5.4.2)(use-sync-external-store@1.4.0(react@18.2.0))(utf-8-validate@5.0.10)(viem@2.35.1(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8))(zod@3.23.8)': - dependencies: - '@base-org/account': 1.1.1(@types/react@18.2.22)(bufferutil@4.0.8)(react@18.2.0)(typescript@5.4.2)(use-sync-external-store@1.4.0(react@18.2.0))(utf-8-validate@5.0.10)(zod@3.23.8) - '@coinbase/wallet-sdk': 4.3.6(@types/react@18.2.22)(bufferutil@4.0.8)(react@18.2.0)(typescript@5.4.2)(use-sync-external-store@1.4.0(react@18.2.0))(utf-8-validate@5.0.10)(zod@3.23.8) - '@gemini-wallet/core': 0.2.0(viem@2.35.1(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8)) - '@metamask/sdk': 0.32.0(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10) - '@safe-global/safe-apps-provider': 0.18.6(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8) - '@safe-global/safe-apps-sdk': 9.1.0(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8) - '@wagmi/core': 2.20.0(@tanstack/query-core@5.83.0)(@types/react@18.2.22)(react@18.2.0)(typescript@5.4.2)(use-sync-external-store@1.4.0(react@18.2.0))(viem@2.35.1(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8)) - '@walletconnect/ethereum-provider': 2.21.1(@types/react@18.2.22)(bufferutil@4.0.8)(encoding@0.1.13)(react@18.2.0)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8) - cbw-sdk: '@coinbase/wallet-sdk@3.9.3' - viem: 2.35.1(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8) - optionalDependencies: - typescript: 5.4.2 - transitivePeerDependencies: - - '@azure/app-configuration' - - '@azure/cosmos' - - '@azure/data-tables' - - '@azure/identity' - - '@azure/keyvault-secrets' - - '@azure/storage-blob' - - '@capacitor/preferences' - - '@netlify/blobs' - - '@planetscale/database' - - '@react-native-async-storage/async-storage' - - '@types/react' - - '@upstash/redis' - - '@vercel/kv' - - bufferutil - - encoding - - immer - - ioredis - - react - - supports-color - - uWebSockets.js - - use-sync-external-store - - utf-8-validate - - zod - - '@wagmi/connectors@5.9.5(@types/react@18.2.22)(@wagmi/core@2.20.0(@tanstack/query-core@5.83.0)(@types/react@18.2.22)(react@19.1.0)(typescript@5.4.2)(use-sync-external-store@1.4.0(react@19.1.0))(viem@2.35.1(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8)))(bufferutil@4.0.8)(encoding@0.1.13)(react@19.1.0)(typescript@5.4.2)(use-sync-external-store@1.4.0(react@19.1.0))(utf-8-validate@5.0.10)(viem@2.35.1(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8))(zod@3.23.8)': + '@wagmi/connectors@5.9.5(@types/react@18.2.22)(@upstash/redis@1.34.9)(@wagmi/core@2.20.0(@tanstack/query-core@5.83.0)(@types/react@18.2.22)(react@19.1.0)(typescript@5.4.2)(use-sync-external-store@1.4.0(react@19.1.0))(viem@2.35.1(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8)))(bufferutil@4.0.8)(encoding@0.1.13)(react@19.1.0)(typescript@5.4.2)(use-sync-external-store@1.4.0(react@19.1.0))(utf-8-validate@5.0.10)(viem@2.35.1(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8))(zod@3.23.8)': dependencies: '@base-org/account': 1.1.1(@types/react@18.2.22)(bufferutil@4.0.8)(react@19.1.0)(typescript@5.4.2)(use-sync-external-store@1.4.0(react@19.1.0))(utf-8-validate@5.0.10)(zod@3.23.8) '@coinbase/wallet-sdk': 4.3.6(@types/react@18.2.22)(bufferutil@4.0.8)(react@19.1.0)(typescript@5.4.2)(use-sync-external-store@1.4.0(react@19.1.0))(utf-8-validate@5.0.10)(zod@3.23.8) @@ -17865,7 +17641,7 @@ snapshots: '@safe-global/safe-apps-provider': 0.18.6(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8) '@safe-global/safe-apps-sdk': 9.1.0(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8) '@wagmi/core': 2.20.0(@tanstack/query-core@5.83.0)(@types/react@18.2.22)(react@19.1.0)(typescript@5.4.2)(use-sync-external-store@1.4.0(react@19.1.0))(viem@2.35.1(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8)) - '@walletconnect/ethereum-provider': 2.21.1(@types/react@18.2.22)(bufferutil@4.0.8)(encoding@0.1.13)(react@19.1.0)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8) + '@walletconnect/ethereum-provider': 2.21.1(@types/react@18.2.22)(@upstash/redis@1.34.9)(bufferutil@4.0.8)(encoding@0.1.13)(react@19.1.0)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8) cbw-sdk: '@coinbase/wallet-sdk@3.9.3' viem: 2.35.1(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8) optionalDependencies: @@ -18157,45 +17933,9 @@ snapshots: - utf-8-validate - zod - '@walletconnect/ethereum-provider@2.21.1(@types/react@18.2.22)(bufferutil@4.0.8)(encoding@0.1.13)(react@18.2.0)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8)': + '@walletconnect/ethereum-provider@2.21.1(@types/react@18.2.22)(@upstash/redis@1.34.9)(bufferutil@4.0.8)(encoding@0.1.13)(react@19.1.0)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8)': dependencies: - '@reown/appkit': 1.7.8(@types/react@18.2.22)(bufferutil@4.0.8)(encoding@0.1.13)(react@18.2.0)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8) - '@walletconnect/jsonrpc-http-connection': 1.0.8(encoding@0.1.13) - '@walletconnect/jsonrpc-provider': 1.0.14 - '@walletconnect/jsonrpc-types': 1.0.4 - '@walletconnect/jsonrpc-utils': 1.0.8 - '@walletconnect/keyvaluestorage': 1.1.1(@upstash/redis@1.34.9) - '@walletconnect/sign-client': 2.21.1(@upstash/redis@1.34.9)(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8) - '@walletconnect/types': 2.21.1(@upstash/redis@1.34.9) - '@walletconnect/universal-provider': 2.21.1(@upstash/redis@1.34.9)(bufferutil@4.0.8)(encoding@0.1.13)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8) - '@walletconnect/utils': 2.21.1(@upstash/redis@1.34.9)(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8) - events: 3.3.0 - transitivePeerDependencies: - - '@azure/app-configuration' - - '@azure/cosmos' - - '@azure/data-tables' - - '@azure/identity' - - '@azure/keyvault-secrets' - - '@azure/storage-blob' - - '@capacitor/preferences' - - '@netlify/blobs' - - '@planetscale/database' - - '@react-native-async-storage/async-storage' - - '@types/react' - - '@upstash/redis' - - '@vercel/kv' - - bufferutil - - encoding - - ioredis - - react - - typescript - - uWebSockets.js - - utf-8-validate - - zod - - '@walletconnect/ethereum-provider@2.21.1(@types/react@18.2.22)(bufferutil@4.0.8)(encoding@0.1.13)(react@19.1.0)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8)': - dependencies: - '@reown/appkit': 1.7.8(@types/react@18.2.22)(bufferutil@4.0.8)(encoding@0.1.13)(react@19.1.0)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8) + '@reown/appkit': 1.7.8(@types/react@18.2.22)(@upstash/redis@1.34.9)(bufferutil@4.0.8)(encoding@0.1.13)(react@19.1.0)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8) '@walletconnect/jsonrpc-http-connection': 1.0.8(encoding@0.1.13) '@walletconnect/jsonrpc-provider': 1.0.14 '@walletconnect/jsonrpc-types': 1.0.4 @@ -19199,14 +18939,14 @@ snapshots: '@types/babel__core': 7.20.5 '@types/babel__traverse': 7.18.3 - babel-plugin-styled-components@2.1.4(@babel/core@7.25.2)(styled-components@5.3.11(@babel/core@7.25.2)(react-dom@18.2.0(react@18.2.0))(react-is@18.2.0)(react@18.2.0))(supports-color@5.5.0): + babel-plugin-styled-components@2.1.4(@babel/core@7.28.0)(styled-components@5.3.11(@babel/core@7.28.0)(react-dom@18.2.0(react@18.2.0))(react-is@18.2.0)(react@18.2.0))(supports-color@5.5.0): dependencies: '@babel/helper-annotate-as-pure': 7.27.3 '@babel/helper-module-imports': 7.27.1(supports-color@5.5.0) - '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.25.2) + '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.28.0) lodash: 4.17.21 picomatch: 2.3.1 - styled-components: 5.3.11(@babel/core@7.25.2)(react-dom@18.2.0(react@18.2.0))(react-is@18.2.0)(react@18.2.0) + styled-components: 5.3.11(@babel/core@7.28.0)(react-dom@18.2.0(react@18.2.0))(react-is@18.2.0)(react@18.2.0) transitivePeerDependencies: - '@babel/core' - supports-color @@ -19654,7 +19394,7 @@ snapshots: confbox@0.1.7: {} - connectkit@1.9.0(@babel/core@7.25.2)(@tanstack/react-query@5.56.2(react@18.2.0))(react-dom@18.2.0(react@18.2.0))(react-is@18.2.0)(react@18.2.0)(viem@2.35.1(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8))(wagmi@2.16.5(@tanstack/query-core@5.83.0)(@tanstack/react-query@5.56.2(react@18.2.0))(@types/react@18.2.22)(@upstash/redis@1.34.9)(bufferutil@4.0.8)(encoding@0.1.13)(react@18.2.0)(typescript@5.4.2)(utf-8-validate@5.0.10)(viem@2.35.1(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8))(zod@3.23.8)): + connectkit@1.9.0(@babel/core@7.28.0)(@tanstack/react-query@5.56.2(react@18.2.0))(react-dom@18.2.0(react@18.2.0))(react-is@18.2.0)(react@18.2.0)(viem@2.35.1(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8))(wagmi@2.16.5(@tanstack/query-core@5.83.0)(@tanstack/react-query@5.56.2(react@18.2.0))(@types/react@18.2.22)(@upstash/redis@1.34.9)(bufferutil@4.0.8)(encoding@0.1.13)(react@18.2.0)(typescript@5.4.2)(utf-8-validate@5.0.10)(viem@2.35.1(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8))(zod@3.23.8)): dependencies: '@tanstack/react-query': 5.56.2(react@18.2.0) buffer: 6.0.3 @@ -19667,7 +19407,7 @@ snapshots: react-transition-state: 1.1.5(react-dom@18.2.0(react@18.2.0))(react@18.2.0) react-use-measure: 2.1.7(react-dom@18.2.0(react@18.2.0))(react@18.2.0) resize-observer-polyfill: 1.5.1 - styled-components: 5.3.11(@babel/core@7.25.2)(react-dom@18.2.0(react@18.2.0))(react-is@18.2.0)(react@18.2.0) + styled-components: 5.3.11(@babel/core@7.28.0)(react-dom@18.2.0(react@18.2.0))(react-is@18.2.0)(react@18.2.0) viem: 2.35.1(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8) wagmi: 2.16.5(@tanstack/query-core@5.83.0)(@tanstack/react-query@5.56.2(react@18.2.0))(@types/react@18.2.22)(@upstash/redis@1.34.9)(bufferutil@4.0.8)(encoding@0.1.13)(react@18.2.0)(typescript@5.4.2)(utf-8-validate@5.0.10)(viem@2.35.1(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8))(zod@3.23.8) transitivePeerDependencies: @@ -23271,7 +23011,7 @@ snapshots: style-value-types: 5.0.0 tslib: 2.8.1 - porto@0.0.76(@tanstack/react-query@5.83.0(react@19.1.0))(@types/react@18.2.22)(@wagmi/core@2.20.0(@tanstack/query-core@5.83.0)(@types/react@18.2.22)(react@19.1.0)(typescript@5.4.2)(use-sync-external-store@1.4.0(react@19.1.0))(viem@2.35.1(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8)))(react@19.1.0)(typescript@5.4.2)(use-sync-external-store@1.4.0(react@19.1.0))(viem@2.35.1(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8))(wagmi@2.16.5(@tanstack/query-core@5.83.0)(@tanstack/react-query@5.83.0(react@19.1.0))(@types/react@18.2.22)(bufferutil@4.0.8)(encoding@0.1.13)(react@19.1.0)(typescript@5.4.2)(utf-8-validate@5.0.10)(viem@2.35.1(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8))(zod@3.23.8))(zod@3.23.8): + porto@0.0.76(@tanstack/react-query@5.83.0(react@19.1.0))(@types/react@18.2.22)(@wagmi/core@2.20.0(@tanstack/query-core@5.83.0)(@types/react@18.2.22)(react@19.1.0)(typescript@5.4.2)(use-sync-external-store@1.4.0(react@19.1.0))(viem@2.35.1(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8)))(react@19.1.0)(typescript@5.4.2)(use-sync-external-store@1.4.0(react@19.1.0))(viem@2.35.1(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8))(wagmi@2.16.5(@tanstack/query-core@5.83.0)(@tanstack/react-query@5.83.0(react@19.1.0))(@types/react@18.2.22)(@upstash/redis@1.34.9)(bufferutil@4.0.8)(encoding@0.1.13)(react@19.1.0)(typescript@5.4.2)(utf-8-validate@5.0.10)(viem@2.35.1(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8))(zod@3.23.8))(zod@3.23.8): dependencies: '@wagmi/core': 2.20.0(@tanstack/query-core@5.83.0)(@types/react@18.2.22)(react@19.1.0)(typescript@5.4.2)(use-sync-external-store@1.4.0(react@19.1.0))(viem@2.35.1(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8)) effect: 3.16.16 @@ -23285,7 +23025,7 @@ snapshots: '@tanstack/react-query': 5.83.0(react@19.1.0) react: 19.1.0 typescript: 5.4.2 - wagmi: 2.16.5(@tanstack/query-core@5.83.0)(@tanstack/react-query@5.83.0(react@19.1.0))(@types/react@18.2.22)(bufferutil@4.0.8)(encoding@0.1.13)(react@19.1.0)(typescript@5.4.2)(utf-8-validate@5.0.10)(viem@2.35.1(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8))(zod@3.23.8) + wagmi: 2.16.5(@tanstack/query-core@5.83.0)(@tanstack/react-query@5.83.0(react@19.1.0))(@types/react@18.2.22)(@upstash/redis@1.34.9)(bufferutil@4.0.8)(encoding@0.1.13)(react@19.1.0)(typescript@5.4.2)(utf-8-validate@5.0.10)(viem@2.35.1(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8))(zod@3.23.8) transitivePeerDependencies: - '@types/react' - immer @@ -24220,6 +23960,8 @@ snapshots: ip: 2.0.0 smart-buffer: 4.2.0 + solady@0.1.26: {} + solhint@3.3.7: dependencies: '@solidity-parser/parser': 0.14.5 @@ -24477,14 +24219,14 @@ snapshots: hey-listen: 1.0.8 tslib: 2.8.1 - styled-components@5.3.11(@babel/core@7.25.2)(react-dom@18.2.0(react@18.2.0))(react-is@18.2.0)(react@18.2.0): + styled-components@5.3.11(@babel/core@7.28.0)(react-dom@18.2.0(react@18.2.0))(react-is@18.2.0)(react@18.2.0): dependencies: '@babel/helper-module-imports': 7.27.1(supports-color@5.5.0) '@babel/traverse': 7.27.3(supports-color@5.5.0) '@emotion/is-prop-valid': 1.3.1 '@emotion/stylis': 0.8.5 '@emotion/unitless': 0.7.5 - babel-plugin-styled-components: 2.1.4(@babel/core@7.25.2)(styled-components@5.3.11(@babel/core@7.25.2)(react-dom@18.2.0(react@18.2.0))(react-is@18.2.0)(react@18.2.0))(supports-color@5.5.0) + babel-plugin-styled-components: 2.1.4(@babel/core@7.28.0)(styled-components@5.3.11(@babel/core@7.28.0)(react-dom@18.2.0(react@18.2.0))(react-is@18.2.0)(react@18.2.0))(supports-color@5.5.0) css-to-react-native: 3.2.0 hoist-non-react-statics: 3.3.2 react: 18.2.0 @@ -25389,10 +25131,10 @@ snapshots: dependencies: xml-name-validator: 4.0.0 - wagmi@2.16.5(@tanstack/query-core@5.83.0)(@tanstack/react-query@5.52.0(react@18.2.0))(@types/react@18.2.22)(bufferutil@4.0.8)(encoding@0.1.13)(react@18.2.0)(typescript@5.4.2)(utf-8-validate@5.0.10)(viem@2.35.1(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8))(zod@3.23.8): + wagmi@2.16.5(@tanstack/query-core@5.83.0)(@tanstack/react-query@5.52.0(react@18.2.0))(@types/react@18.2.22)(@upstash/redis@1.34.9)(bufferutil@4.0.8)(encoding@0.1.13)(react@18.2.0)(typescript@5.4.2)(utf-8-validate@5.0.10)(viem@2.35.1(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8))(zod@3.23.8): dependencies: '@tanstack/react-query': 5.52.0(react@18.2.0) - '@wagmi/connectors': 5.9.5(@types/react@18.2.22)(@wagmi/core@2.20.0(@tanstack/query-core@5.83.0)(@types/react@18.2.22)(react@18.2.0)(typescript@5.4.2)(use-sync-external-store@1.4.0(react@18.2.0))(viem@2.35.1(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8)))(bufferutil@4.0.8)(encoding@0.1.13)(react@18.2.0)(typescript@5.4.2)(use-sync-external-store@1.4.0(react@18.2.0))(utf-8-validate@5.0.10)(viem@2.35.1(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8))(zod@3.23.8) + '@wagmi/connectors': 5.9.5(@types/react@18.2.22)(@upstash/redis@1.34.9)(@wagmi/core@2.20.0(@tanstack/query-core@5.83.0)(@types/react@18.2.22)(react@18.2.0)(typescript@5.4.2)(use-sync-external-store@1.4.0(react@18.2.0))(viem@2.35.1(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8)))(bufferutil@4.0.8)(encoding@0.1.13)(react@18.2.0)(typescript@5.4.2)(use-sync-external-store@1.4.0(react@18.2.0))(utf-8-validate@5.0.10)(viem@2.35.1(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8))(zod@3.23.8) '@wagmi/core': 2.20.0(@tanstack/query-core@5.83.0)(@types/react@18.2.22)(react@18.2.0)(typescript@5.4.2)(use-sync-external-store@1.4.0(react@18.2.0))(viem@2.35.1(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8)) react: 18.2.0 use-sync-external-store: 1.4.0(react@18.2.0) @@ -25457,44 +25199,10 @@ snapshots: - utf-8-validate - zod - wagmi@2.16.5(@tanstack/query-core@5.83.0)(@tanstack/react-query@5.56.2(react@18.2.0))(@types/react@18.2.22)(bufferutil@4.0.8)(encoding@0.1.13)(react@18.2.0)(typescript@5.4.2)(utf-8-validate@5.0.10)(viem@2.35.1(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8))(zod@3.23.8): - dependencies: - '@tanstack/react-query': 5.56.2(react@18.2.0) - '@wagmi/connectors': 5.9.5(@types/react@18.2.22)(@wagmi/core@2.20.0(@tanstack/query-core@5.83.0)(@types/react@18.2.22)(react@18.2.0)(typescript@5.4.2)(use-sync-external-store@1.4.0(react@18.2.0))(viem@2.35.1(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8)))(bufferutil@4.0.8)(encoding@0.1.13)(react@18.2.0)(typescript@5.4.2)(use-sync-external-store@1.4.0(react@18.2.0))(utf-8-validate@5.0.10)(viem@2.35.1(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8))(zod@3.23.8) - '@wagmi/core': 2.20.0(@tanstack/query-core@5.83.0)(@types/react@18.2.22)(react@18.2.0)(typescript@5.4.2)(use-sync-external-store@1.4.0(react@18.2.0))(viem@2.35.1(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8)) - react: 18.2.0 - use-sync-external-store: 1.4.0(react@18.2.0) - viem: 2.35.1(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8) - optionalDependencies: - typescript: 5.4.2 - transitivePeerDependencies: - - '@azure/app-configuration' - - '@azure/cosmos' - - '@azure/data-tables' - - '@azure/identity' - - '@azure/keyvault-secrets' - - '@azure/storage-blob' - - '@capacitor/preferences' - - '@netlify/blobs' - - '@planetscale/database' - - '@react-native-async-storage/async-storage' - - '@tanstack/query-core' - - '@types/react' - - '@upstash/redis' - - '@vercel/kv' - - bufferutil - - encoding - - immer - - ioredis - - supports-color - - uWebSockets.js - - utf-8-validate - - zod - - wagmi@2.16.5(@tanstack/query-core@5.83.0)(@tanstack/react-query@5.83.0(react@19.1.0))(@types/react@18.2.22)(bufferutil@4.0.8)(encoding@0.1.13)(react@19.1.0)(typescript@5.4.2)(utf-8-validate@5.0.10)(viem@2.35.1(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8))(zod@3.23.8): + wagmi@2.16.5(@tanstack/query-core@5.83.0)(@tanstack/react-query@5.83.0(react@19.1.0))(@types/react@18.2.22)(@upstash/redis@1.34.9)(bufferutil@4.0.8)(encoding@0.1.13)(react@19.1.0)(typescript@5.4.2)(utf-8-validate@5.0.10)(viem@2.35.1(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8))(zod@3.23.8): dependencies: '@tanstack/react-query': 5.83.0(react@19.1.0) - '@wagmi/connectors': 5.9.5(@types/react@18.2.22)(@wagmi/core@2.20.0(@tanstack/query-core@5.83.0)(@types/react@18.2.22)(react@19.1.0)(typescript@5.4.2)(use-sync-external-store@1.4.0(react@19.1.0))(viem@2.35.1(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8)))(bufferutil@4.0.8)(encoding@0.1.13)(react@19.1.0)(typescript@5.4.2)(use-sync-external-store@1.4.0(react@19.1.0))(utf-8-validate@5.0.10)(viem@2.35.1(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8))(zod@3.23.8) + '@wagmi/connectors': 5.9.5(@types/react@18.2.22)(@upstash/redis@1.34.9)(@wagmi/core@2.20.0(@tanstack/query-core@5.83.0)(@types/react@18.2.22)(react@19.1.0)(typescript@5.4.2)(use-sync-external-store@1.4.0(react@19.1.0))(viem@2.35.1(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8)))(bufferutil@4.0.8)(encoding@0.1.13)(react@19.1.0)(typescript@5.4.2)(use-sync-external-store@1.4.0(react@19.1.0))(utf-8-validate@5.0.10)(viem@2.35.1(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8))(zod@3.23.8) '@wagmi/core': 2.20.0(@tanstack/query-core@5.83.0)(@types/react@18.2.22)(react@19.1.0)(typescript@5.4.2)(use-sync-external-store@1.4.0(react@19.1.0))(viem@2.35.1(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10)(zod@3.23.8)) react: 19.1.0 use-sync-external-store: 1.4.0(react@19.1.0)